1 |
|
2 |
FIles transferred over SHell protocol (V 0.0.2) |
3 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4 |
|
5 |
This protocol was designed for transferring files over a remote shell |
6 |
connection (rsh and compatibles). It can be as well used for transfers over |
7 |
rsh, and there may be other uses. |
8 |
|
9 |
Client sends requests of following form: |
10 |
|
11 |
#FISH_COMMAND |
12 |
equivalent shell commands, |
13 |
which may be multiline |
14 |
|
15 |
Only fish commands are defined here, shell equivalents are for your |
16 |
information only and will probably vary from implementation to |
17 |
implementation. Fish commands always have priority: server is |
18 |
expected to execute fish command if it understands it. If it does not, |
19 |
however, it can try the luck and execute shell command. |
20 |
|
21 |
Server's reply is multiline, but always ends with |
22 |
|
23 |
### 000<optional text> |
24 |
|
25 |
line. ### is prefix to mark this line, 000 is return code. Return |
26 |
codes are superset to those used in ftp. |
27 |
|
28 |
There are few new exit codes defined: |
29 |
|
30 |
000 don't know; if there were no previous lines, this marks COMPLETE |
31 |
success, if they were, it marks failure. |
32 |
|
33 |
001 don't know; if there were no previous lines, this marks |
34 |
PRELIMinary success, if they were, it marks failure |
35 |
|
36 |
Connecting |
37 |
~~~~~~~~~~ |
38 |
Client uses "echo FISH:;/bin/sh" as command executed on remote |
39 |
machine. This should make it possible for server to distinguish FISH |
40 |
connections from normal rsh/ssh. |
41 |
|
42 |
Commands |
43 |
~~~~~~~~ |
44 |
#FISH |
45 |
echo; start_fish_server; echo '### 200' |
46 |
|
47 |
This command is sent at the beginning. It marks that client wishes to |
48 |
talk via FISH protocol. #VER command must follow. If server |
49 |
understands FISH protocol, it has option to put FISH server somewhere |
50 |
on system path and name it start_fish_server. |
51 |
|
52 |
#VER 0.0.2 <feature1> <feature2> <...> |
53 |
echo '### 000' |
54 |
|
55 |
This command is the second one. It sends client version and extensions |
56 |
to the server. Server should reply with protocol version to be used, |
57 |
and list of extensions accepted. |
58 |
|
59 |
VER 0.0.0 <feature2> |
60 |
### 200 |
61 |
|
62 |
#PWD |
63 |
pwd; echo '### 200' |
64 |
|
65 |
Server should reply with current directory (in form /abc/def/ghi) |
66 |
followed by line indicating success. |
67 |
|
68 |
#LIST /directory |
69 |
ls -lLa $1 | grep '^[^cbt]' | ( while read p x u g s m d y n; do echo "P$p $u.$g |
70 |
S$s |
71 |
d$m $d $y |
72 |
:$n |
73 |
"; done ) |
74 |
ls -lLa $1 | grep '^[cb]' | ( while read p x u g a i m d y n; do echo "P$p $u.$g |
75 |
E$a$i |
76 |
dD$m $d $y |
77 |
:$n |
78 |
"; done ) |
79 |
echo '### 200' |
80 |
|
81 |
This allows client to list directory or get status information about |
82 |
single file. Output is in following form (any line except :<filename> |
83 |
may be omitted): |
84 |
|
85 |
P<unix permissions> <owner>.<group> |
86 |
S<size> |
87 |
d<3-letters month name> <day> <year or HH:MM> |
88 |
D<year> <month> <day> <hour> <minute> <second>[.1234] |
89 |
E<major-of-device>,<minor> |
90 |
:<filename> |
91 |
L<filename symlink points to> |
92 |
<blank line to separate items> |
93 |
|
94 |
Unix permissions are of form X--------- where X is type of |
95 |
file. Currently, '-' means regular file, 'd' means directory, 'c', 'b' |
96 |
means character and block device, 'l' means symbolic link, 'p' means |
97 |
FIFO and 's' means socket. |
98 |
|
99 |
'd' has three fields: month (one of strings Jan Feb Mar Apr May Jun |
100 |
Jul Aug Sep Oct Nov Dec), day of month, and third is either single |
101 |
number indicating year, or HH:MM field (assume current year in such |
102 |
case). As you've probably noticed, this is pretty broken; it is for |
103 |
compatibility with ls listing. |
104 |
|
105 |
#RETR /some/name |
106 |
ls -l /some/name | ( read a b c d x e; echo $x ); echo '### 100'; cat /some/name; echo '### 200' |
107 |
|
108 |
Server sends line with filesize on it, followed by line with ### 100 |
109 |
indicating partial success, then it sends binary data (exactly |
110 |
filesize bytes) and follows them with (with no preceding newline) ### |
111 |
200. |
112 |
|
113 |
Note that there's no way to abort running RETR command - except |
114 |
closing the connection. |
115 |
|
116 |
#STOR <size> /file/name |
117 |
> /file/name; echo '### 001'; ( dd bs=4096 count=<size/4096>; dd bs=<size%4096> count=1 ) 2>/dev/null | ( cat > %s; cat > /dev/null ); echo '### 200' |
118 |
|
119 |
This command is for storing /file/name, which is exactly size bytes |
120 |
big. You probably think I went crazy. Well, I did not: that strange |
121 |
cat > /dev/null has purpose to discard any extra data which was not |
122 |
written to disk (due to for example out of space condition). |
123 |
|
124 |
[Why? Imagine uploading file with "rm -rf /" line in it.] |
125 |
|
126 |
#CWD /somewhere |
127 |
cd /somewhere; echo '### 000' |
128 |
|
129 |
It is specified here, but I'm not sure how wise idea is to use this |
130 |
one: it breaks stateless-ness of the protocol. |
131 |
|
132 |
Following commands should be rather self-explanatory: |
133 |
|
134 |
#CHMOD 1234 file |
135 |
chmod 1234 file; echo '### 000' |
136 |
|
137 |
#DELE /some/path |
138 |
rm -f /some/path; echo '### 000' |
139 |
|
140 |
#MKD /some/path |
141 |
mkdir /some/path; echo '### 000' |
142 |
|
143 |
#RMD /some/path |
144 |
rmdir /some/path; echo '### 000' |
145 |
|
146 |
#RENAME /path/a /path/b |
147 |
mv /path/a /path/b; echo '### 000' |
148 |
|
149 |
#LINK /path/a /path/b |
150 |
ln /path/a /path/b; echo '### 000' |
151 |
|
152 |
#SYMLINK /path/a /path/b |
153 |
ln -s /path/a /path/b; echo '### 000' |
154 |
|
155 |
#CHOWN user /file/name |
156 |
chown user /file/name; echo '### 000' |
157 |
|
158 |
#CHGRP group /file/name |
159 |
chgrp group /file/name; echo '### 000' |
160 |
|
161 |
#READ <offset> <size> /path/and/filename |
162 |
cat /path/and/filename | ( dd bs=4096 count=<offset/4096> > /dev/null; |
163 |
dd bs=<offset%4096> count=1 > /dev/null; |
164 |
dd bs=4096 count=<offset/4096>; |
165 |
dd bs=<offset%4096> count=1; ) |
166 |
|
167 |
Returns ### 200 on successful exit, ### 291 on successful exit when |
168 |
reading ended at eof, ### 292 on successfull exit when reading did not |
169 |
end at eof. |
170 |
|
171 |
#WRITE <offset> <size> /path/and/filename |
172 |
|
173 |
Hmm, shall we define these ones if we know our client is not going to |
174 |
use them? |
175 |
|
176 |
|
177 |
That's all, folks! |
178 |
pavel@ucw.cz |