PageRenderTime 71ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

commands/ftp101/ftp.c

http://www.minix3.org/
C | 409 lines | 333 code | 57 blank | 19 comment | 68 complexity | 295e5ea5ba77fa44fa1b54b3b09fabd6 MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. /* ftp.c Copyright 1992-2000 by Michael Temari All Rights Reserved
  2. *
  3. * ftp An ftp client program for use with TNET.
  4. *
  5. * Usage: ftp [host]
  6. *
  7. * Version: 0.10 06/21/92 (pre-release not yet completed)
  8. * 0.20 07/01/92
  9. * 0.30 01/15/96 (Minix 1.7.1 initial release)
  10. * 0.40 08/27/96
  11. * 0.50 03/08/00
  12. * 1.00 12/12/03 (added ver command)
  13. * 1.01 02/07/05
  14. *
  15. * Author: Michael Temari, <Michael@TemWare.Com>
  16. */
  17. #include <sys/types.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <ctype.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include "ftp.h"
  24. #include "local.h"
  25. #include "file.h"
  26. #include "other.h"
  27. #include "net.h"
  28. char *FtpVersion = "1.01 02/07/05";
  29. int linkopen;
  30. int loggedin;
  31. int type;
  32. int format;
  33. int mode;
  34. int structure;
  35. int passive;
  36. int atty;
  37. int cmdargc;
  38. char *cmdargv[NUMARGS];
  39. int printreply = 1;
  40. char reply[1024];
  41. #ifdef __NBSD_LIBC
  42. /* Already declared in stdio.h */
  43. #define getline ftp_getline
  44. #endif
  45. _PROTOTYPE(static void makeargs, (char *buff));
  46. _PROTOTYPE(int DOver, (void));
  47. _PROTOTYPE(int DOhelp, (void));
  48. _PROTOTYPE(static int getline, (char *line, int len));
  49. _PROTOTYPE(int main, (int argc, char *argv[]));
  50. static void makeargs(buff)
  51. char *buff;
  52. {
  53. int i;
  54. char *p;
  55. for(i = 0; i < NUMARGS; i++)
  56. cmdargv[i] = (char *)0;
  57. p = buff + strlen(buff) - 1;
  58. while(p >= buff)
  59. if(*p == '\r' || *p == '\n' || isspace(*p))
  60. *p-- = '\0';
  61. else
  62. break;
  63. p = buff;
  64. cmdargc = 0;
  65. while(cmdargc < NUMARGS) {
  66. while(*p && isspace(*p))
  67. p++;
  68. if(*p == '\0')
  69. break;
  70. cmdargv[cmdargc++] = p;
  71. while(*p && !isspace(*p)) {
  72. if(cmdargc == 1)
  73. *p = tolower(*p);
  74. p++;
  75. }
  76. if(*p == '\0')
  77. break;
  78. *p = '\0';
  79. p++;
  80. }
  81. }
  82. int readline(prompt, buff, len)
  83. char *prompt;
  84. char *buff;
  85. int len;
  86. {
  87. char *p;
  88. printf(prompt); fflush(stdout);
  89. if(fgets(buff, len, stdin) == (char *)NULL) {
  90. printf("\nEnd of file on input!\n");
  91. return(-1);
  92. }
  93. p = buff + strlen(buff) - 1;
  94. while(p >= buff)
  95. if(*p == '\r' || *p == '\n' || isspace(*p))
  96. *p-- = '\0';
  97. else
  98. break;
  99. if(!atty) {
  100. printf("%s\n", buff);
  101. fflush(stdout);
  102. }
  103. return(0);
  104. }
  105. static int getline(line, len)
  106. char *line;
  107. int len;
  108. {
  109. int s;
  110. int gotcr;
  111. /* leave room for at end for null */
  112. len--;
  113. /* got to be able to put in at least 1 character */
  114. if(len < 1)
  115. return(-1);
  116. gotcr = 0;
  117. while(len-- > 0) {
  118. s = read(ftpcomm_fd, line, 1);
  119. if(s != 1)
  120. return(-1);
  121. if(*line == '\n')
  122. break;
  123. gotcr = (*line == '\r');
  124. line++;
  125. }
  126. if(gotcr)
  127. --line;
  128. *line = '\0';
  129. return(0);
  130. }
  131. int DOgetreply()
  132. {
  133. int firsttime;
  134. int s;
  135. char code[4];
  136. do {
  137. firsttime = 1;
  138. do {
  139. if((s = getline(reply, sizeof(reply))) < 0)
  140. return(s);
  141. if(printreply) {
  142. printf("%s\n", reply);
  143. fflush(stdout);
  144. }
  145. if(firsttime) {
  146. firsttime = 0;
  147. strncpy(code, reply, 3);
  148. code[3] = '\0';
  149. }
  150. } while(strncmp(reply, code, 3) || reply[3] == '-');
  151. s = atoi(code);
  152. } while(s < 200 && s != 125 && s != 150);
  153. return(s);
  154. }
  155. int DOcmdcheck()
  156. {
  157. if(!linkopen) {
  158. printf("You must \"OPEN\" a connection first.\n");
  159. return(1);
  160. }
  161. if(!loggedin) {
  162. printf("You must login first.\n");
  163. return(1);
  164. }
  165. return(0);
  166. }
  167. int DOcommand(ftpcommand, ftparg)
  168. char *ftpcommand;
  169. char *ftparg;
  170. {
  171. int s;
  172. #if 1
  173. static char ss[64];
  174. if(*ftparg)
  175. sprintf(ss, "%s %s\r\n", ftpcommand, ftparg);
  176. else
  177. sprintf(ss, "%s\r\n", ftpcommand);
  178. s = write(ftpcomm_fd, ss, strlen(ss));
  179. if(s != strlen(ss))
  180. return(-1);
  181. #else
  182. s = write(ftpcomm_fd, ftpcommand, strlen(ftpcommand));
  183. if(s != strlen(ftpcommand))
  184. return(-1);
  185. if(*ftparg) {
  186. s = write(ftpcomm_fd, " ", 1);
  187. if(s != 1)
  188. return(-1);
  189. s = write(ftpcomm_fd, ftparg, strlen(ftparg));
  190. if(s != strlen(ftparg))
  191. return(-1);
  192. }
  193. s = write(ftpcomm_fd, "\r\n", 2);
  194. if(s != 2)
  195. return(-1);
  196. #endif
  197. return(DOgetreply());
  198. }
  199. int DOver()
  200. {
  201. printf("FTP Version %s\n", FtpVersion);
  202. return(0);
  203. }
  204. int DOhelp()
  205. {
  206. char junk[10];
  207. printf("Command: Description\n");
  208. printf("! Escape to a shell\n");
  209. printf("append Append a file to remote host\n");
  210. printf("ascii Set file transfer type to ascii\n");
  211. printf("binary Set file transfer type to binary\n");
  212. printf("block Set file transfer mode to block\n");
  213. printf("bye Close connection and exit\n");
  214. printf("cd Change directory on remote host\n");
  215. printf("close Close connection\n");
  216. printf("clone Clone a file\n");
  217. printf("del Remove file on remote host\n");
  218. printf("dir Display long form remote host directory listing\n");
  219. printf("exit Close connection and exit\n");
  220. printf("get Retrieve a file from remote host\n");
  221. printf("help Display this text\n");
  222. if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
  223. return(-1);
  224. printf("lcd Change directory on local host\n");
  225. printf("ldir Display long form local host directory listing\n");
  226. printf("lls Display local host directory listing\n");
  227. printf("lmkdir Create directory on local host\n");
  228. printf("lpwd Display current directory on local host\n");
  229. printf("lrmdir Remove directory on local host\n");
  230. printf("ls Display remote host directory listing\n");
  231. printf("mget Retrieve multiple files from remote host\n");
  232. printf("mkdir Create directory on remote host\n");
  233. printf("mod Get file modification time\n");
  234. printf("mput Send multiple files to remote host\n");
  235. printf("noop Send the ftp NOOP command\n");
  236. if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
  237. return(-1);
  238. printf("open Open connection to remote host\n");
  239. printf("pass Enter remote user password\n");
  240. printf("passive Toggle passive mode\n");
  241. printf("put Send a file to remote host\n");
  242. printf("putu Send a file to remote host(unique)\n");
  243. printf("pwd Display current directory on remote host\n");
  244. printf("quit Close connection and exit\n");
  245. printf("quote Send raw ftp command to remote host\n");
  246. printf("reget Restart a partial file retrieve from remote host\n");
  247. printf("remotehelp Display ftp commands implemented on remote host\n");
  248. printf("reput Restart a partial file send to remote host\n");
  249. printf("rm Remove file on remote host\n");
  250. printf("rmdir Remove directory on remote host\n");
  251. if(readline("Press ENTER to continue... ", junk, sizeof(junk)))
  252. return(-1);
  253. printf("site Send a site specific command\n");
  254. printf("size Get file size information\n");
  255. printf("status Get connection/file status information\n");
  256. printf("stream Set file transfer mode to stream\n");
  257. printf("system Get remote system type information\n");
  258. printf("user Enter remote user information\n");
  259. printf("ver Display client version information\n");
  260. return(0);
  261. }
  262. struct commands {
  263. char *name;
  264. _PROTOTYPE(int (*func), (void));
  265. };
  266. static struct commands commands[] = {
  267. "!", DOlshell,
  268. "append", DOappe,
  269. "ascii", DOascii,
  270. "binary", DObinary,
  271. "block", DOblock,
  272. "bye", DOquit,
  273. "cd", DOcd,
  274. "close", DOclose,
  275. "clone", DOclone,
  276. "del", DOdelete,
  277. "dir", DOlist,
  278. "exit", DOquit,
  279. "get", DOretr,
  280. "help", DOhelp,
  281. "lcd", DOlcd,
  282. "ldir", DOllist,
  283. "lls", DOlnlst,
  284. "lmkdir", DOlmkdir,
  285. "lpwd", DOlpwd,
  286. "lrmdir", DOlrmdir,
  287. "ls", DOnlst,
  288. "mget", DOMretr,
  289. "mkdir", DOmkdir,
  290. "mod", DOmdtm,
  291. "mput", DOMstor,
  292. "noop", DOnoop,
  293. "open", DOopen,
  294. "pass", DOpass,
  295. "passive", DOpassive,
  296. "put", DOstor,
  297. "putu", DOstou,
  298. "pwd", DOpwd,
  299. "quit", DOquit,
  300. "quote", DOquote,
  301. "reget", DOrretr,
  302. "remotehelp", DOremotehelp,
  303. "reput", DOrstor,
  304. "rm", DOdelete,
  305. "rmdir", DOrmdir,
  306. "site", DOsite,
  307. "size", DOsize,
  308. "status", DOstat,
  309. "stream", DOstream,
  310. "system", DOsyst,
  311. "user", DOuser,
  312. "ver", DOver,
  313. "", (int (*)())0
  314. };
  315. int main(argc, argv)
  316. int argc;
  317. char *argv[];
  318. {
  319. int s;
  320. struct commands *cmd;
  321. static char buffer[128];
  322. if(NETinit())
  323. return(-1);
  324. FTPinit();
  325. s = 0;
  326. if(argc > 1) {
  327. sprintf(buffer, "open %s ", argv[1]);
  328. makeargs(buffer);
  329. s = DOopen();
  330. if(atty && s > 0) {
  331. sprintf(buffer, "user");
  332. makeargs(buffer);
  333. s = DOuser();
  334. }
  335. }
  336. while(s >= 0) {
  337. s = readline("ftp>", buffer, sizeof(buffer));
  338. if(s < 0) break;
  339. makeargs(buffer);
  340. if(cmdargc == 0) continue;
  341. for(cmd = commands; *cmd->name != '\0'; cmd++)
  342. if(!strcmp(cmdargv[0], cmd->name))
  343. break;
  344. if(*cmd->name != '\0')
  345. s = (*cmd->func)();
  346. else {
  347. s = 0;
  348. printf("Command \"%s\" not recognized.\n", cmdargv[0]);
  349. }
  350. }
  351. return(s);
  352. }