Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmds.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1985, 1989 Regents of the University of California. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms are permitted 00006 * provided that the above copyright notice and this paragraph are 00007 * duplicated in all such forms and that any documentation, 00008 * advertising materials, and other materials related to such 00009 * distribution and use acknowledge that the software was developed 00010 * by the University of California, Berkeley. The name of the 00011 * University may not be used to endorse or promote products derived 00012 * from this software without specific prior written permission. 00013 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 00014 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 00015 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00016 */ 00017 00018 #ifndef lint 00019 static char sccsid[] = "@(#)cmds.c 5.18 (Berkeley) 4/20/89"; 00020 #endif /* not lint */ 00021 00022 /* 00023 * FTP User Program -- Command Routines. 00024 */ 00025 //#include <sys/param.h> 00026 //#include <sys/wait.h> 00027 00028 #include "precomp.h" 00029 00030 extern char *globerr; 00031 extern char home[]; 00032 static const char *remglob(const char *argv[], int doswitch); 00033 extern int allbinary; 00034 extern off_t restart_point; 00035 extern char reply_string[]; 00036 00037 const char *mname; 00038 jmp_buf jabort; 00039 const char *dotrans(const char *name); 00040 const char *domap(const char *name); 00041 00042 extern short portnum; 00043 extern char *hostname; 00044 extern int autologin; 00045 /* 00046 * Connect to peer server and 00047 * auto-login, if possible. 00048 */ 00049 void setpeer(int argc, const char *argv[]) 00050 { 00051 char *host; 00052 00053 if (connected) { 00054 printf("Already connected to %s, use close first.\n", 00055 hostname); 00056 (void) fflush(stdout); 00057 code = -1; 00058 return; 00059 } 00060 if (argc < 2) { 00061 (void) strcat(line, " "); 00062 printf("(to) "); 00063 (void) fflush(stdout); 00064 (void) gets(&line[strlen(line)]); 00065 makeargv(); 00066 argc = margc; 00067 argv = margv; 00068 } 00069 if (argc > 3) { 00070 printf("usage: %s host-name [port]\n", argv[0]); 00071 (void) fflush(stdout); 00072 code = -1; 00073 return; 00074 } 00075 if (argc > 2) { 00076 portnum = atoi(argv[2]); 00077 if (portnum <= 0) { 00078 printf("%s: bad port number-- %s\n", argv[1], argv[2]); 00079 printf ("usage: %s host-name [port]\n", argv[0]); 00080 (void) fflush(stdout); 00081 code = -1; 00082 return; 00083 } 00084 portnum = htons(portnum); 00085 } 00086 host = hookup(argv[1], portnum); 00087 if (host) { 00088 #if defined(unix) && NBBY == 8 00089 int overbose; 00090 #endif 00091 connected = 1; 00092 if (autologin) 00093 (void) login(argv[1]); 00094 00095 #if defined(unix) && NBBY == 8 00096 /* 00097 * this ifdef is to keep someone form "porting" this to an incompatible 00098 * system and not checking this out. This way they have to think about it. 00099 */ 00100 overbose = verbose; 00101 if (debug == 0) 00102 verbose = -1; 00103 allbinary = 0; 00104 if (command("SYST") == COMPLETE && overbose) { 00105 register char *cp, c; 00106 cp = index(reply_string+4, ' '); 00107 if (cp == NULL) 00108 cp = index(reply_string+4, '\r'); 00109 if (cp) { 00110 if (cp[-1] == '.') 00111 cp--; 00112 c = *cp; 00113 *cp = '\0'; 00114 } 00115 00116 printf("Remote system type is %s.\n", 00117 reply_string+4); 00118 if (cp) 00119 *cp = c; 00120 } 00121 if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 00122 setbinary(); 00123 /* allbinary = 1; this violates the RFC */ 00124 if (overbose) 00125 printf("Using %s mode to transfer files.\n", 00126 typename); 00127 } else if (overbose && 00128 !strncmp(reply_string, "215 TOPS20", 10)) { 00129 printf( 00130 "Remember to set tenex mode when transfering binary files from this machine.\n"); 00131 } 00132 verbose = overbose; 00133 #endif /* unix */ 00134 } 00135 (void) fflush(stdout); 00136 } 00137 00138 struct types { 00139 const char *t_name; 00140 const char *t_mode; 00141 int t_type; 00142 char *t_arg; 00143 } types[] = { 00144 { "ascii", "A", TYPE_A, 0 }, 00145 { "binary", "I", TYPE_I, 0 }, 00146 { "image", "I", TYPE_I, 0 }, 00147 { "ebcdic", "E", TYPE_E, 0 }, 00148 { "tenex", "L", TYPE_L, bytename }, 00149 {0 } 00150 }; 00151 00152 /* 00153 * Set transfer type. 00154 */ 00155 void settype(int argc, const char *argv[]) 00156 { 00157 register struct types *p; 00158 int comret; 00159 00160 if (argc > 2) { 00161 const char *sep; 00162 00163 printf("usage: %s [", argv[0]); 00164 sep = " "; 00165 for (p = types; p->t_name; p++) { 00166 printf("%s%s", sep, p->t_name); 00167 if (*sep == ' ') 00168 sep = " | "; 00169 } 00170 printf(" ]\n"); 00171 (void) fflush(stdout); 00172 code = -1; 00173 return; 00174 } 00175 if (argc < 2) { 00176 printf("Using %s mode to transfer files.\n", typename); 00177 (void) fflush(stdout); 00178 code = 0; 00179 return; 00180 } 00181 for (p = types; p->t_name; p++) 00182 if (strcmp(argv[1], p->t_name) == 0) 00183 break; 00184 if (p->t_name == 0) { 00185 printf("%s: unknown mode\n", argv[1]); 00186 (void) fflush(stdout); 00187 code = -1; 00188 return; 00189 } 00190 if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 00191 comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 00192 else 00193 comret = command("TYPE %s", p->t_mode); 00194 if (comret == COMPLETE) { 00195 (void) strcpy(typename, p->t_name); 00196 type = p->t_type; 00197 } 00198 } 00199 00200 const char *stype[] = { 00201 "type", 00202 "", 00203 0 00204 }; 00205 00206 /* 00207 * Set binary transfer type. 00208 */ 00209 /*VARARGS*/ 00210 void setbinary(int argc, const char *argv[]) 00211 { 00212 stype[1] = "binary"; 00213 settype(2, stype); 00214 } 00215 00216 /* 00217 * Set ascii transfer type. 00218 */ 00219 /*VARARGS*/ 00220 void setascii(int argc, const char *argv[]) 00221 { 00222 stype[1] = "ascii"; 00223 settype(2, stype); 00224 } 00225 00226 /* 00227 * Set tenex transfer type. 00228 */ 00229 /*VARARGS*/ 00230 void settenex(int argc, const char *argv[]) 00231 { 00232 stype[1] = "tenex"; 00233 settype(2, stype); 00234 } 00235 00236 /* 00237 * Set ebcdic transfer type. 00238 */ 00239 /*VARARGS*/ 00240 void setebcdic() 00241 { 00242 stype[1] = "ebcdic"; 00243 settype(2, stype); 00244 } 00245 00246 /* 00247 * Set file transfer mode. 00248 */ 00249 00250 /*ARGSUSED*/ 00251 void fsetmode(int argc, const char *argv[]) 00252 { 00253 00254 printf("We only support %s mode, sorry.\n", modename); 00255 (void) fflush(stdout); 00256 code = -1; 00257 } 00258 00259 00260 /* 00261 * Set file transfer format. 00262 */ 00263 /*ARGSUSED*/ 00264 void setform(int argc, const char *argv[]) 00265 { 00266 00267 printf("We only support %s format, sorry.\n", formname); 00268 (void) fflush(stdout); 00269 code = -1; 00270 } 00271 00272 /* 00273 * Set file transfer structure. 00274 */ 00275 /*ARGSUSED*/ 00276 void setstruct(int argc, const char *argv[]) 00277 { 00278 00279 printf("We only support %s structure, sorry.\n", structname); 00280 (void) fflush(stdout); 00281 code = -1; 00282 } 00283 00284 /* 00285 * Send a single file. 00286 */ 00287 void put(int argc, const char *argv[]) 00288 { 00289 const char *cmd; 00290 int loc = 0; 00291 const char *oldargv1, *oldargv2; 00292 00293 if (argc == 2) { 00294 argc++; 00295 argv[2] = argv[1]; 00296 loc++; 00297 } 00298 if (argc < 2) { 00299 (void) strcat(line, " "); 00300 printf("(local-file) "); 00301 (void) fflush(stdout); 00302 (void) gets(&line[strlen(line)]); 00303 makeargv(); 00304 argc = margc; 00305 argv = margv; 00306 } 00307 if (argc < 2) { 00308 usage: 00309 printf("usage:%s local-file remote-file\n", argv[0]); 00310 (void) fflush(stdout); 00311 code = -1; 00312 return; 00313 } 00314 if (argc < 3) { 00315 (void) strcat(line, " "); 00316 printf("(remote-file) "); 00317 (void) fflush(stdout); 00318 (void) gets(&line[strlen(line)]); 00319 makeargv(); 00320 argc = margc; 00321 argv = margv; 00322 } 00323 if (argc < 3) 00324 goto usage; 00325 oldargv1 = argv[1]; 00326 oldargv2 = argv[2]; 00327 if (!globulize(&argv[1])) { 00328 code = -1; 00329 return; 00330 } 00331 /* 00332 * If "globulize" modifies argv[1], and argv[2] is a copy of 00333 * the old argv[1], make it a copy of the new argv[1]. 00334 */ 00335 if (argv[1] != oldargv1 && argv[2] == oldargv1) { 00336 argv[2] = argv[1]; 00337 } 00338 cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 00339 if (loc && ntflag) { 00340 argv[2] = dotrans(argv[2]); 00341 } 00342 if (loc && mapflag) { 00343 argv[2] = domap(argv[2]); 00344 } 00345 sendrequest(cmd, argv[1], argv[2], 00346 argv[1] != oldargv1 || argv[2] != oldargv2); 00347 } 00348 00349 /* 00350 * Send multiple files. 00351 */ 00352 void mput(int argc, const char *argv[]) 00353 { 00354 register int i; 00355 int ointer; 00356 extern jmp_buf jabort; 00357 const char *tp; 00358 00359 if (argc < 2) { 00360 (void) strcat(line, " "); 00361 printf("(local-files) "); 00362 (void) fflush(stdout); 00363 (void) gets(&line[strlen(line)]); 00364 makeargv(); 00365 argc = margc; 00366 argv = margv; 00367 } 00368 if (argc < 2) { 00369 printf("usage:%s local-files\n", argv[0]); 00370 (void) fflush(stdout); 00371 code = -1; 00372 return; 00373 } 00374 mname = argv[0]; 00375 mflag = 1; 00376 // oldintr = signal(SIGINT, mabort); 00377 (void) setjmp(jabort); 00378 if (proxy) { 00379 const char *cp; 00380 char *tp2, tmpbuf[MAXPATHLEN]; 00381 00382 while ((cp = remglob(argv,0)) != NULL) { 00383 if (*cp == 0) { 00384 mflag = 0; 00385 continue; 00386 } 00387 if (mflag && confirm(argv[0], cp)) { 00388 tp = cp; 00389 if (mcase) { 00390 while (*tp && !islower(*tp)) { 00391 tp++; 00392 } 00393 if (!*tp) { 00394 tp = cp; 00395 tp2 = tmpbuf; 00396 while ((*tp2 = *tp)) { 00397 if (isupper(*tp2)) { 00398 *tp2 = 'a' + *tp2 - 'A'; 00399 } 00400 tp++; 00401 tp2++; 00402 } 00403 } 00404 tp = tmpbuf; 00405 } 00406 if (ntflag) { 00407 tp = dotrans(tp); 00408 } 00409 if (mapflag) { 00410 tp = domap(tp); 00411 } 00412 sendrequest((sunique) ? "STOU" : "STOR", 00413 cp, tp, cp != tp || !interactive); 00414 if (!mflag && fromatty) { 00415 ointer = interactive; 00416 interactive = 1; 00417 if (confirm("Continue with","mput")) { 00418 mflag++; 00419 } 00420 interactive = ointer; 00421 } 00422 } 00423 } 00424 // (void) signal(SIGINT, oldintr); 00425 mflag = 0; 00426 return; 00427 } 00428 for (i = 1; i < argc; i++) { 00429 register char **cpp, **gargs; 00430 00431 if (!doglob) { 00432 if (mflag && confirm(argv[0], argv[i])) { 00433 tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 00434 tp = (mapflag) ? domap(tp) : tp; 00435 sendrequest((sunique) ? "STOU" : "STOR", 00436 argv[i], tp, tp != argv[i] || !interactive); 00437 if (!mflag && fromatty) { 00438 ointer = interactive; 00439 interactive = 1; 00440 if (confirm("Continue with","mput")) { 00441 mflag++; 00442 } 00443 interactive = ointer; 00444 } 00445 } 00446 continue; 00447 } 00448 gargs = glob(argv[i]); 00449 if (globerr != NULL) { 00450 printf("%s\n", globerr); 00451 (void) fflush(stdout); 00452 if (gargs) { 00453 blkfree(gargs); 00454 free((char *)gargs); 00455 } 00456 continue; 00457 } 00458 for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 00459 if (mflag && confirm(argv[0], *cpp)) { 00460 tp = (ntflag) ? dotrans(*cpp) : *cpp; 00461 tp = (mapflag) ? domap(tp) : tp; 00462 sendrequest((sunique) ? "STOU" : "STOR", 00463 *cpp, tp, *cpp != tp || !interactive); 00464 if (!mflag && fromatty) { 00465 ointer = interactive; 00466 interactive = 1; 00467 if (confirm("Continue with","mput")) { 00468 mflag++; 00469 } 00470 interactive = ointer; 00471 } 00472 } 00473 } 00474 if (gargs != NULL) { 00475 blkfree(gargs); 00476 free((char *)gargs); 00477 } 00478 } 00479 // (void) signal(SIGINT, oldintr); 00480 mflag = 0; 00481 } 00482 00483 void reget(int argc, const char *argv[]) 00484 { 00485 (void) getit(argc, argv, 1, "r+w"); 00486 } 00487 00488 void get(int argc, const char *argv[]) 00489 { 00490 (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 00491 } 00492 00493 /* 00494 * Receive one file. 00495 */ 00496 int getit(int argc, const char *argv[], int restartit, const char *mode) 00497 { 00498 int loc = 0; 00499 const char *oldargv1, *oldargv2; 00500 00501 if (argc == 2) { 00502 argc++; 00503 argv[2] = argv[1]; 00504 loc++; 00505 } 00506 if (argc < 2) { 00507 (void) strcat(line, " "); 00508 printf("(remote-file) "); 00509 (void) fflush(stdout); 00510 (void) gets(&line[strlen(line)]); 00511 makeargv(); 00512 argc = margc; 00513 argv = margv; 00514 } 00515 if (argc < 2) { 00516 usage: 00517 printf("usage: %s remote-file [ local-file ]\n", argv[0]); 00518 (void) fflush(stdout); 00519 code = -1; 00520 return (0); 00521 } 00522 if (argc < 3) { 00523 (void) strcat(line, " "); 00524 printf("(local-file) "); 00525 (void) fflush(stdout); 00526 (void) gets(&line[strlen(line)]); 00527 makeargv(); 00528 argc = margc; 00529 argv = margv; 00530 } 00531 if (argc < 3) 00532 goto usage; 00533 oldargv1 = argv[1]; 00534 oldargv2 = argv[2]; 00535 if (!globulize(&argv[2])) { 00536 code = -1; 00537 return (0); 00538 } 00539 if (loc && mcase) { 00540 const char *tp = argv[1]; 00541 char *tp2, tmpbuf[MAXPATHLEN]; 00542 00543 while (*tp && !islower(*tp)) { 00544 tp++; 00545 } 00546 if (!*tp) { 00547 tp = argv[2]; 00548 tp2 = tmpbuf; 00549 while ((*tp2 = *tp)) { 00550 if (isupper(*tp2)) { 00551 *tp2 = 'a' + *tp2 - 'A'; 00552 } 00553 tp++; 00554 tp2++; 00555 } 00556 argv[2] = tmpbuf; 00557 } 00558 } 00559 if (loc && ntflag) 00560 argv[2] = dotrans(argv[2]); 00561 if (loc && mapflag) 00562 argv[2] = domap(argv[2]); 00563 if (restartit) { 00564 struct stat stbuf; 00565 int ret; 00566 00567 ret = stat(argv[2], &stbuf); 00568 if (restartit == 1) { 00569 if (ret < 0) { 00570 perror(argv[2]); 00571 return (0); 00572 } 00573 restart_point = stbuf.st_size; 00574 } else { 00575 if (ret == 0) { 00576 int overbose; 00577 00578 overbose = verbose; 00579 if (debug == 0) 00580 verbose = -1; 00581 if (command("MDTM %s", argv[1]) == COMPLETE) { 00582 int yy, mo, day, hour, min, sec; 00583 struct tm *tm; 00584 verbose = overbose; 00585 sscanf(reply_string, 00586 "%*s %04d%02d%02d%02d%02d%02d", 00587 &yy, &mo, &day, &hour, &min, &sec); 00588 tm = gmtime(&stbuf.st_mtime); 00589 tm->tm_mon++; 00590 if (tm->tm_year > yy%100) 00591 return (1); 00592 else if (tm->tm_year == yy%100) { 00593 if (tm->tm_mon > mo) 00594 return (1); 00595 } else if (tm->tm_mon == mo) { 00596 if (tm->tm_mday > day) 00597 return (1); 00598 } else if (tm->tm_mday == day) { 00599 if (tm->tm_hour > hour) 00600 return (1); 00601 } else if (tm->tm_hour == hour) { 00602 if (tm->tm_min > min) 00603 return (1); 00604 } else if (tm->tm_min == min) { 00605 if (tm->tm_sec > sec) 00606 return (1); 00607 } 00608 } else { 00609 printf("%s\n", reply_string); 00610 (void) fflush(stdout); 00611 verbose = overbose; 00612 return (0); 00613 } 00614 } 00615 } 00616 } 00617 00618 recvrequest("RETR", argv[2], argv[1], mode, 00619 argv[1] != oldargv1 || argv[2] != oldargv2); 00620 restart_point = 0; 00621 return (0); 00622 } 00623 00624 #if 0 00625 static void 00626 mabort() 00627 { 00628 int ointer; 00629 extern jmp_buf jabort; 00630 00631 printf("\n"); 00632 (void) fflush(stdout); 00633 if (mflag && fromatty) { 00634 ointer = interactive; 00635 interactive = 1; 00636 if (confirm("Continue with", mname)) { 00637 interactive = ointer; 00638 longjmp(jabort,0); 00639 } 00640 interactive = ointer; 00641 } 00642 mflag = 0; 00643 longjmp(jabort,0); 00644 } 00645 #endif 00646 00647 /* 00648 * Get multiple files. 00649 */ 00650 void mget(int argc, const char *argv[]) 00651 { 00652 const char *cp, *tp; 00653 char *tp2, tmpbuf[MAXPATHLEN]; 00654 int ointer; 00655 extern jmp_buf jabort; 00656 00657 if (argc < 2) { 00658 (void) strcat(line, " "); 00659 printf("(remote-files) "); 00660 (void) fflush(stdout); 00661 (void) gets(&line[strlen(line)]); 00662 makeargv(); 00663 argc = margc; 00664 argv = margv; 00665 } 00666 if (argc < 2) { 00667 printf("usage:%s remote-files\n", argv[0]); 00668 (void) fflush(stdout); 00669 code = -1; 00670 return; 00671 } 00672 mname = argv[0]; 00673 mflag = 1; 00674 // oldintr = signal(SIGINT,mabort); 00675 (void) setjmp(jabort); 00676 while ((cp = remglob(argv,proxy)) != NULL) { 00677 if (*cp == '\0') { 00678 mflag = 0; 00679 continue; 00680 } 00681 if (mflag && confirm(argv[0], cp)) { 00682 tp = cp; 00683 if (mcase) { 00684 while (*tp && !islower(*tp)) { 00685 tp++; 00686 } 00687 if (!*tp) { 00688 tp = cp; 00689 tp2 = tmpbuf; 00690 while ((*tp2 = *tp)) { 00691 if (isupper(*tp2)) { 00692 *tp2 = 'a' + *tp2 - 'A'; 00693 } 00694 tp++; 00695 tp2++; 00696 } 00697 } 00698 tp = tmpbuf; 00699 } 00700 if (ntflag) { 00701 tp = dotrans(tp); 00702 } 00703 if (mapflag) { 00704 tp = domap(tp); 00705 } 00706 recvrequest("RETR", tp, cp, "w", 00707 tp != cp || !interactive); 00708 if (!mflag && fromatty) { 00709 ointer = interactive; 00710 interactive = 1; 00711 if (confirm("Continue with","mget")) { 00712 mflag++; 00713 } 00714 interactive = ointer; 00715 } 00716 } 00717 } 00718 // (void) signal(SIGINT,oldintr); 00719 mflag = 0; 00720 } 00721 00722 const char * 00723 remglob(const char *argv[], int doswitch) 00724 { 00725 char temp[16]; 00726 static char buf[MAXPATHLEN]; 00727 static FILE *ftemp = NULL; 00728 static const char **args; 00729 int oldverbose, oldhash; 00730 const char *cp; 00731 const char *mode; 00732 char *terminator; 00733 00734 if (!mflag) { 00735 if (!doglob) { 00736 args = NULL; 00737 } 00738 else { 00739 if (ftemp) { 00740 (void) fclose(ftemp); 00741 ftemp = NULL; 00742 } 00743 } 00744 return(NULL); 00745 } 00746 if (!doglob) { 00747 if (args == NULL) 00748 args = argv; 00749 if ((cp = *++args) == NULL) 00750 args = NULL; 00751 return (cp); 00752 } 00753 if (ftemp == NULL) { 00754 (void) strcpy(temp, _PATH_TMP); 00755 (void) mktemp(temp); 00756 oldverbose = verbose, verbose = 0; 00757 oldhash = hash, hash = 0; 00758 if (doswitch) { 00759 pswitch(!proxy); 00760 } 00761 for (mode = "w"; *++argv != NULL; mode = "a") 00762 recvrequest ("NLST", temp, *argv, mode, 0); 00763 if (doswitch) { 00764 pswitch(!proxy); 00765 } 00766 verbose = oldverbose; hash = oldhash; 00767 ftemp = fopen(temp, "r"); 00768 (void) unlink(temp); 00769 if (ftemp == NULL) { 00770 printf("can't find list of remote files, oops\n"); 00771 (void) fflush(stdout); 00772 return (NULL); 00773 } 00774 } 00775 if (fgets(buf, sizeof (buf), ftemp) == NULL) { 00776 (void) fclose(ftemp), ftemp = NULL; 00777 return (NULL); 00778 } 00779 if ((terminator = index(buf, '\n')) != NULL) 00780 *terminator = '\0'; 00781 return (buf); 00782 } 00783 00784 static const char * 00785 onoff(int bool) 00786 { 00787 return (bool ? "on" : "off"); 00788 } 00789 00790 /* 00791 * Show status. 00792 */ 00793 /*ARGSUSED*/ 00794 void status(int argc, const char *argv[]) 00795 { 00796 int i; 00797 00798 if (connected) 00799 printf("Connected to %s.\n", hostname); 00800 else 00801 printf("Not connected.\n"); 00802 if (!proxy) { 00803 pswitch(1); 00804 if (connected) { 00805 printf("Connected for proxy commands to %s.\n", hostname); 00806 } 00807 else { 00808 printf("No proxy connection.\n"); 00809 } 00810 pswitch(0); 00811 } 00812 printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 00813 modename, typename, formname, structname); 00814 printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 00815 onoff(verbose), onoff(bell), onoff(interactive), 00816 onoff(doglob)); 00817 printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 00818 onoff(runique)); 00819 printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 00820 if (ntflag) { 00821 printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 00822 } 00823 else { 00824 printf("Ntrans: off\n"); 00825 } 00826 if (mapflag) { 00827 printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 00828 } 00829 else { 00830 printf("Nmap: off\n"); 00831 } 00832 printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 00833 onoff(hash), onoff(sendport)); 00834 if (macnum > 0) { 00835 printf("Macros:\n"); 00836 for (i=0; i<macnum; i++) { 00837 printf("\t%s\n",macros[i].mac_name); 00838 } 00839 } 00840 (void) fflush(stdout); 00841 code = 0; 00842 } 00843 00844 /* 00845 * Set beep on cmd completed mode. 00846 */ 00847 /*VARARGS*/ 00848 void setbell(int argc, const char *argv[]) 00849 { 00850 00851 bell = !bell; 00852 printf("Bell mode %s.\n", onoff(bell)); 00853 (void) fflush(stdout); 00854 code = bell; 00855 } 00856 00857 /* 00858 * Turn on packet tracing. 00859 */ 00860 /*VARARGS*/ 00861 void settrace(int argc, const char *argv[]) 00862 { 00863 00864 trace = !trace; 00865 printf("Packet tracing %s.\n", onoff(trace)); 00866 (void) fflush(stdout); 00867 code = trace; 00868 } 00869 00870 /* 00871 * Toggle hash mark printing during transfers. 00872 */ 00873 /*VARARGS*/ 00874 void sethash(int argc, const char *argv[]) 00875 { 00876 00877 hash = !hash; 00878 printf("Hash mark printing %s", onoff(hash)); 00879 code = hash; 00880 if (hash) 00881 printf(" (%d bytes/hash mark)", 1024); 00882 printf(".\n"); 00883 (void) fflush(stdout); 00884 } 00885 00886 /* 00887 * Turn on printing of server echo's. 00888 */ 00889 /*VARARGS*/ 00890 void setverbose(int argc, const char *argv[]) 00891 { 00892 00893 verbose = !verbose; 00894 printf("Verbose mode %s.\n", onoff(verbose)); 00895 (void) fflush(stdout); 00896 code = verbose; 00897 } 00898 00899 /* 00900 * Toggle PORT cmd use before each data connection. 00901 */ 00902 /*VARARGS*/ 00903 void setport(int argc, const char *argv[]) 00904 { 00905 00906 sendport = !sendport; 00907 printf("Use of PORT cmds %s.\n", onoff(sendport)); 00908 (void) fflush(stdout); 00909 code = sendport; 00910 } 00911 00912 /* 00913 * Turn on interactive prompting 00914 * during mget, mput, and mdelete. 00915 */ 00916 /*VARARGS*/ 00917 void setprompt(int argc, const char *argv[]) 00918 { 00919 00920 interactive = !interactive; 00921 printf("Interactive mode %s.\n", onoff(interactive)); 00922 (void) fflush(stdout); 00923 code = interactive; 00924 } 00925 00926 /* 00927 * Toggle metacharacter interpretation 00928 * on local file names. 00929 */ 00930 /*VARARGS*/ 00931 void setglob(int argc, const char *argv[]) 00932 { 00933 00934 doglob = !doglob; 00935 printf("Globbing %s.\n", onoff(doglob)); 00936 (void) fflush(stdout); 00937 code = doglob; 00938 } 00939 00940 /* 00941 * Set debugging mode on/off and/or 00942 * set level of debugging. 00943 */ 00944 /*VARARGS*/ 00945 void setdebug(int argc, const char *argv[]) 00946 { 00947 int val; 00948 00949 if (argc > 1) { 00950 val = atoi(argv[1]); 00951 if (val < 0) { 00952 printf("%s: bad debugging value.\n", argv[1]); 00953 (void) fflush(stdout); 00954 code = -1; 00955 return; 00956 } 00957 } else 00958 val = !debug; 00959 debug = val; 00960 if (debug) 00961 options |= SO_DEBUG; 00962 else 00963 options &= ~SO_DEBUG; 00964 printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 00965 (void) fflush(stdout); 00966 code = debug > 0; 00967 } 00968 00969 /* 00970 * Set current working directory 00971 * on remote machine. 00972 */ 00973 void cd(int argc, const char *argv[]) 00974 { 00975 00976 if (argc < 2) { 00977 (void) strcat(line, " "); 00978 printf("(remote-directory) "); 00979 (void) fflush(stdout); 00980 (void) gets(&line[strlen(line)]); 00981 makeargv(); 00982 argc = margc; 00983 argv = margv; 00984 } 00985 if (argc < 2) { 00986 printf("usage:%s remote-directory\n", argv[0]); 00987 (void) fflush(stdout); 00988 code = -1; 00989 return; 00990 } 00991 if (command("CWD %s", argv[1]) == ERROR && code == 500) { 00992 if (verbose) { 00993 printf("CWD command not recognized, trying XCWD\n"); 00994 (void) fflush(stdout); 00995 } 00996 (void) command("XCWD %s", argv[1]); 00997 } 00998 } 00999 01000 /* 01001 * Set current working directory 01002 * on local machine. 01003 */ 01004 void lcd(int argc, const char *argv[]) 01005 { 01006 char buf[MAXPATHLEN]; 01007 01008 if (argc < 2) 01009 argc++, argv[1] = home; 01010 if (argc != 2) { 01011 printf("usage:%s local-directory\n", argv[0]); 01012 (void) fflush(stdout); 01013 code = -1; 01014 return; 01015 } 01016 if (!globulize(&argv[1])) { 01017 code = -1; 01018 return; 01019 } 01020 if (chdir(argv[1]) < 0) { 01021 perror(argv[1]); 01022 code = -1; 01023 return; 01024 } 01025 printf("Local directory now %s\n", getcwd(buf,sizeof(buf))); 01026 (void) fflush(stdout); 01027 code = 0; 01028 } 01029 01030 /* 01031 * Delete a single file. 01032 */ 01033 void delete(int argc, const char *argv[]) 01034 { 01035 01036 if (argc < 2) { 01037 (void) strcat(line, " "); 01038 printf("(remote-file) "); 01039 (void) fflush(stdout); 01040 (void) gets(&line[strlen(line)]); 01041 makeargv(); 01042 argc = margc; 01043 argv = margv; 01044 } 01045 if (argc < 2) { 01046 printf("usage:%s remote-file\n", argv[0]); 01047 (void) fflush(stdout); 01048 code = -1; 01049 return; 01050 } 01051 (void) command("DELE %s", argv[1]); 01052 } 01053 01054 /* 01055 * Delete multiple files. 01056 */ 01057 void mdelete(int argc, const char *argv[]) 01058 { 01059 const char *cp; 01060 int ointer; 01061 extern jmp_buf jabort; 01062 01063 if (argc < 2) { 01064 (void) strcat(line, " "); 01065 printf("(remote-files) "); 01066 (void) fflush(stdout); 01067 (void) gets(&line[strlen(line)]); 01068 makeargv(); 01069 argc = margc; 01070 argv = margv; 01071 } 01072 if (argc < 2) { 01073 printf("usage:%s remote-files\n", argv[0]); 01074 (void) fflush(stdout); 01075 code = -1; 01076 return; 01077 } 01078 mname = argv[0]; 01079 mflag = 1; 01080 // oldintr = signal(SIGINT, mabort); 01081 (void) setjmp(jabort); 01082 while ((cp = remglob(argv,0)) != NULL) { 01083 if (*cp == '\0') { 01084 mflag = 0; 01085 continue; 01086 } 01087 if (mflag && confirm(argv[0], cp)) { 01088 (void) command("DELE %s", cp); 01089 if (!mflag && fromatty) { 01090 ointer = interactive; 01091 interactive = 1; 01092 if (confirm("Continue with", "mdelete")) { 01093 mflag++; 01094 } 01095 interactive = ointer; 01096 } 01097 } 01098 } 01099 // (void) signal(SIGINT, oldintr); 01100 mflag = 0; 01101 } 01102 01103 /* 01104 * Rename a remote file. 01105 */ 01106 void renamefile(int argc, const char *argv[]) 01107 { 01108 01109 if (argc < 2) { 01110 (void) strcat(line, " "); 01111 printf("(from-name) "); 01112 (void) fflush(stdout); 01113 (void) gets(&line[strlen(line)]); 01114 makeargv(); 01115 argc = margc; 01116 argv = margv; 01117 } 01118 if (argc < 2) { 01119 usage: 01120 printf("%s from-name to-name\n", argv[0]); 01121 (void) fflush(stdout); 01122 code = -1; 01123 return; 01124 } 01125 if (argc < 3) { 01126 (void) strcat(line, " "); 01127 printf("(to-name) "); 01128 (void) fflush(stdout); 01129 (void) gets(&line[strlen(line)]); 01130 makeargv(); 01131 argc = margc; 01132 argv = margv; 01133 } 01134 if (argc < 3) 01135 goto usage; 01136 if (command("RNFR %s", argv[1]) == CONTINUE) 01137 (void) command("RNTO %s", argv[2]); 01138 } 01139 01140 /* 01141 * Get a directory listing 01142 * of remote files. 01143 */ 01144 void ls(int argc, const char *argv[]) 01145 { 01146 const char *cmd; 01147 01148 if (argc < 2) 01149 argc++, argv[1] = NULL; 01150 if (argc < 3) 01151 argc++, argv[2] = "-"; 01152 if (argc > 3) { 01153 printf("usage: %s remote-directory local-file\n", argv[0]); 01154 (void) fflush(stdout); 01155 code = -1; 01156 return; 01157 } 01158 cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 01159 // cmd = argv[0][0] == 'n' ? "NLST -CF" : "NLST -CF"; 01160 if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 01161 code = -1; 01162 return; 01163 } 01164 if (strcmp(argv[2], "-") && *argv[2] != '|') 01165 if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 01166 code = -1; 01167 return; 01168 } 01169 recvrequest(cmd, argv[2], argv[1], "w", 0); 01170 } 01171 01172 /* 01173 * Get a directory listing 01174 * of multiple remote files. 01175 */ 01176 void mls(int argc, const char *argv[]) 01177 { 01178 const char *cmd, *dest; 01179 char mode[1]; 01180 int ointer, i; 01181 extern jmp_buf jabort; 01182 01183 if (argc < 2) { 01184 (void) strcat(line, " "); 01185 printf("(remote-files) "); 01186 (void) fflush(stdout); 01187 (void) gets(&line[strlen(line)]); 01188 makeargv(); 01189 argc = margc; 01190 argv = margv; 01191 } 01192 if (argc < 3) { 01193 (void) strcat(line, " "); 01194 printf("(local-file) "); 01195 (void) fflush(stdout); 01196 (void) gets(&line[strlen(line)]); 01197 makeargv(); 01198 argc = margc; 01199 argv = margv; 01200 } 01201 if (argc < 3) { 01202 printf("usage:%s remote-files local-file\n", argv[0]); 01203 (void) fflush(stdout); 01204 code = -1; 01205 return; 01206 } 01207 dest = argv[argc - 1]; 01208 argv[argc - 1] = NULL; 01209 if (strcmp(dest, "-") && *dest != '|') 01210 if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 01211 code = -1; 01212 return; 01213 } 01214 cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 01215 mname = argv[0]; 01216 mflag = 1; 01217 // oldintr = signal(SIGINT, mabort); 01218 (void) setjmp(jabort); 01219 for (i = 1; mflag && i < argc-1; ++i) { 01220 *mode = (i == 1) ? 'w' : 'a'; 01221 recvrequest(cmd, dest, argv[i], mode, 0); 01222 if (!mflag && fromatty) { 01223 ointer = interactive; 01224 interactive = 1; 01225 if (confirm("Continue with", argv[0])) { 01226 mflag ++; 01227 } 01228 interactive = ointer; 01229 } 01230 } 01231 // (void) signal(SIGINT, oldintr); 01232 mflag = 0; 01233 } 01234 01235 /* 01236 * Do a shell escape 01237 */ 01238 /*ARGSUSED*/ 01239 void shell(int argc, const char *argv[]) 01240 { 01241 #if 0 01242 int pid; 01243 sig_t (*old1)(), (*old2)(); 01244 char shellnam[40], *shell, *namep; 01245 union wait status; 01246 01247 old1 = signal (SIGINT, SIG_IGN); 01248 old2 = signal (SIGQUIT, SIG_IGN); 01249 if ((pid = fork()) == 0) { 01250 for (pid = 3; pid < 20; pid++) 01251 (void) close(pid); 01252 (void) signal(SIGINT, SIG_DFL); 01253 (void) signal(SIGQUIT, SIG_DFL); 01254 shell = getenv("SHELL"); 01255 if (shell == NULL) 01256 shell = _PATH_BSHELL; 01257 namep = rindex(shell,'/'); 01258 if (namep == NULL) 01259 namep = shell; 01260 (void) strcpy(shellnam,"-"); 01261 (void) strcat(shellnam, ++namep); 01262 if (strcmp(namep, "sh") != 0) 01263 shellnam[0] = '+'; 01264 if (debug) { 01265 printf ("%s\n", shell); 01266 (void) fflush (stdout); 01267 } 01268 if (argc > 1) { 01269 execl(shell,shellnam,"-c",altarg,(char *)0); 01270 } 01271 else { 01272 execl(shell,shellnam,(char *)0); 01273 } 01274 perror(shell); 01275 code = -1; 01276 exit(1); 01277 } 01278 if (pid > 0) 01279 while (wait(&status) != pid) 01280 ; 01281 (void) signal(SIGINT, old1); 01282 (void) signal(SIGQUIT, old2); 01283 if (pid == -1) { 01284 perror("Try again later"); 01285 code = -1; 01286 } 01287 else { 01288 code = 0; 01289 } 01290 #endif 01291 01292 char * AppName; 01293 char ShellCmd[MAX_PATH]; 01294 char CmdLine[MAX_PATH]; 01295 int i; 01296 PROCESS_INFORMATION ProcessInformation; 01297 BOOL Result; 01298 STARTUPINFO StartupInfo; 01299 char ShellName[] = "COMSPEC"; 01300 int NumBytes; 01301 01302 NumBytes = GetEnvironmentVariable( ShellName, ShellCmd, MAX_PATH); 01303 01304 if (NumBytes == 0) 01305 { 01306 return; 01307 } 01308 01309 AppName = ShellCmd; 01310 strcpy( CmdLine, ShellCmd ); 01311 01312 if (argc > 1) 01313 { 01314 strncat(CmdLine, " /C", MAX_PATH); 01315 } 01316 01317 for (i=1; i<argc; i++) 01318 { 01319 strncat(CmdLine, " ", MAX_PATH); 01320 strncat(CmdLine, argv[i], MAX_PATH); 01321 } 01322 01323 StartupInfo.cb = sizeof( StartupInfo ); 01324 StartupInfo.lpReserved = NULL; 01325 StartupInfo.lpDesktop = NULL; 01326 StartupInfo.lpTitle = NULL; 01327 StartupInfo.dwX = 0; 01328 StartupInfo.dwY = 0; 01329 StartupInfo.dwXSize = 0; 01330 StartupInfo.dwYSize = 0; 01331 StartupInfo.dwFlags = 0; 01332 StartupInfo.wShowWindow = 0; 01333 StartupInfo.cbReserved2 = 0; 01334 StartupInfo.lpReserved2 = NULL; 01335 01336 Result = CreateProcess( AppName, // cmd name 01337 CmdLine, // cmd line arguments 01338 NULL, 01339 NULL, // security attributes 01340 FALSE, // inherit flags 01341 0, // Creation flags 01342 NULL, // Environment 01343 NULL, // Current directory 01344 &StartupInfo, // Startup info structure 01345 &ProcessInformation); // processInfo structure 01346 01347 if (Result) 01348 { 01349 WaitForSingleObject( ProcessInformation.hProcess, 0xffffffff); 01350 01351 CloseHandle( ProcessInformation.hProcess); 01352 } 01353 } 01354 01355 /* 01356 * Send new user information (re-login) 01357 */ 01358 void user(int argc, const char *argv[]) 01359 { 01360 char acct[80], *getpass(); 01361 int n, aflag = 0; 01362 01363 if (argc < 2) { 01364 (void) strcat(line, " "); 01365 printf("(username) "); 01366 (void) fflush(stdout); 01367 (void) gets(&line[strlen(line)]); 01368 makeargv(); 01369 argc = margc; 01370 argv = margv; 01371 } 01372 if (argc > 4) { 01373 printf("usage: %s username [password] [account]\n", argv[0]); 01374 (void) fflush(stdout); 01375 code = -1; 01376 return; 01377 } 01378 n = command("USER %s", argv[1]); 01379 if (n == CONTINUE) { 01380 if (argc < 3 ) 01381 argv[2] = getpass("Password: "), argc++; 01382 n = command("PASS %s", argv[2]); 01383 } 01384 if (n == CONTINUE) { 01385 if (argc < 4) { 01386 printf("Account: "); (void) fflush(stdout); 01387 (void) fflush(stdout); 01388 (void) fgets(acct, sizeof(acct) - 1, stdin); 01389 acct[strlen(acct) - 1] = '\0'; 01390 argv[3] = acct; argc++; 01391 } 01392 n = command("ACCT %s", argv[3]); 01393 aflag++; 01394 } 01395 if (n != COMPLETE) { 01396 fprintf(stdout, "Login failed.\n"); 01397 (void) fflush(stdout); 01398 return; 01399 } 01400 if (!aflag && argc == 4) { 01401 (void) command("ACCT %s", argv[3]); 01402 } 01403 } 01404 01405 /* 01406 * Print working directory. 01407 */ 01408 /*VARARGS*/ 01409 void pwd(int argc, const char *argv[]) 01410 { 01411 int oldverbose = verbose; 01412 01413 /* 01414 * If we aren't verbose, this doesn't do anything! 01415 */ 01416 verbose = 1; 01417 if (command("PWD") == ERROR && code == 500) { 01418 printf("PWD command not recognized, trying XPWD\n"); 01419 (void) fflush(stdout); 01420 (void) command("XPWD"); 01421 } 01422 verbose = oldverbose; 01423 } 01424 01425 /* 01426 * Make a directory. 01427 */ 01428 void makedir(int argc, const char *argv[]) 01429 { 01430 01431 if (argc < 2) { 01432 (void) strcat(line, " "); 01433 printf("(directory-name) "); 01434 (void) fflush(stdout); 01435 (void) gets(&line[strlen(line)]); 01436 makeargv(); 01437 argc = margc; 01438 argv = margv; 01439 } 01440 if (argc < 2) { 01441 printf("usage: %s directory-name\n", argv[0]); 01442 (void) fflush(stdout); 01443 code = -1; 01444 return; 01445 } 01446 if (command("MKD %s", argv[1]) == ERROR && code == 500) { 01447 if (verbose) { 01448 printf("MKD command not recognized, trying XMKD\n"); 01449 (void) fflush(stdout); 01450 } 01451 (void) command("XMKD %s", argv[1]); 01452 } 01453 } 01454 01455 /* 01456 * Remove a directory. 01457 */ 01458 void removedir(int argc, const char *argv[]) 01459 { 01460 01461 if (argc < 2) { 01462 (void) strcat(line, " "); 01463 printf("(directory-name) "); 01464 (void) fflush(stdout); 01465 (void) gets(&line[strlen(line)]); 01466 makeargv(); 01467 argc = margc; 01468 argv = margv; 01469 } 01470 if (argc < 2) { 01471 printf("usage: %s directory-name\n", argv[0]); 01472 (void) fflush(stdout); 01473 code = -1; 01474 return; 01475 } 01476 if (command("RMD %s", argv[1]) == ERROR && code == 500) { 01477 if (verbose) { 01478 printf("RMD command not recognized, trying XRMD\n"); 01479 (void) fflush(stdout); 01480 } 01481 (void) command("XRMD %s", argv[1]); 01482 } 01483 } 01484 01485 /* 01486 * Send a line, verbatim, to the remote machine. 01487 */ 01488 void quote(int argc, const char *argv[]) 01489 { 01490 int i; 01491 char buf[BUFSIZ]; 01492 01493 if (argc < 2) { 01494 (void) strcat(line, " "); 01495 printf("(command line to send) "); 01496 (void) fflush(stdout); 01497 (void) gets(&line[strlen(line)]); 01498 makeargv(); 01499 argc = margc; 01500 argv = margv; 01501 } 01502 if (argc < 2) { 01503 printf("usage: %s line-to-send\n", argv[0]); 01504 (void) fflush(stdout); 01505 code = -1; 01506 return; 01507 } 01508 (void) strcpy(buf, argv[1]); 01509 for (i = 2; i < argc; i++) { 01510 (void) strcat(buf, " "); 01511 (void) strcat(buf, argv[i]); 01512 } 01513 if (command(buf) == PRELIM) { 01514 while (getreply(0) == PRELIM); 01515 } 01516 } 01517 01518 /* 01519 * Send a SITE command to the remote machine. The line 01520 * is sent almost verbatim to the remote machine, the 01521 * first argument is changed to SITE. 01522 */ 01523 void site(int argc, const char *argv[]) 01524 { 01525 int i; 01526 char buf[BUFSIZ]; 01527 01528 if (argc < 2) { 01529 (void) strcat(line, " "); 01530 printf("(arguments to SITE command) "); 01531 (void) fflush(stdout); 01532 (void) gets(&line[strlen(line)]); 01533 makeargv(); 01534 argc = margc; 01535 argv = margv; 01536 } 01537 if (argc < 2) { 01538 printf("usage: %s line-to-send\n", argv[0]); 01539 (void) fflush(stdout); 01540 code = -1; 01541 return; 01542 } 01543 (void) strcpy(buf, "SITE "); 01544 (void) strcat(buf, argv[1]); 01545 for (i = 2; i < argc; i++) { 01546 (void) strcat(buf, " "); 01547 (void) strcat(buf, argv[i]); 01548 } 01549 if (command(buf) == PRELIM) { 01550 while (getreply(0) == PRELIM); 01551 } 01552 } 01553 01554 void do_chmod(int argc, const char *argv[]) 01555 { 01556 if (argc == 2) { 01557 printf("usage: %s mode file-name\n", argv[0]); 01558 (void) fflush(stdout); 01559 code = -1; 01560 return; 01561 } 01562 if (argc < 3) { 01563 (void) strcat(line, " "); 01564 printf("(mode and file-name) "); 01565 (void) fflush(stdout); 01566 (void) gets(&line[strlen(line)]); 01567 makeargv(); 01568 argc = margc; 01569 argv = margv; 01570 } 01571 if (argc != 3) { 01572 printf("usage: %s mode file-name\n", argv[0]); 01573 (void) fflush(stdout); 01574 code = -1; 01575 return; 01576 } 01577 (void)command("SITE CHMOD %s %s", argv[1], argv[2]); 01578 } 01579 01580 void do_umask(int argc, const char *argv[]) 01581 { 01582 int oldverbose = verbose; 01583 01584 verbose = 1; 01585 (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); 01586 verbose = oldverbose; 01587 } 01588 01589 void idle(int argc, const char *argv[]) 01590 { 01591 int oldverbose = verbose; 01592 01593 verbose = 1; 01594 (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); 01595 verbose = oldverbose; 01596 } 01597 01598 /* 01599 * Ask the other side for help. 01600 */ 01601 void rmthelp(int argc, const char *argv[]) 01602 { 01603 int oldverbose = verbose; 01604 01605 verbose = 1; 01606 (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 01607 verbose = oldverbose; 01608 } 01609 01610 /* 01611 * Terminate session and exit. 01612 */ 01613 /*VARARGS*/ 01614 void quit(int argc, const char *argv[]) 01615 { 01616 if (connected) 01617 disconnect(0, NULL); 01618 pswitch(1); 01619 if (connected) { 01620 disconnect(0, NULL); 01621 } 01622 exit(0); 01623 } 01624 01625 /* 01626 * Terminate session, but don't exit. 01627 */ 01628 void disconnect(int argc, const char *argv[]) 01629 { 01630 extern SOCKET cout; 01631 extern int data; 01632 01633 if (!connected) 01634 return; 01635 (void) command("QUIT"); 01636 cout = 0; 01637 connected = 0; 01638 data = -1; 01639 if (!proxy) { 01640 macnum = 0; 01641 } 01642 } 01643 01644 int confirm(const char *cmd, const char *file) 01645 { 01646 char line[BUFSIZ]; 01647 01648 if (!interactive) 01649 return (1); 01650 printf("%s %s? ", cmd, file); 01651 (void) fflush(stdout); 01652 (void) gets(line); 01653 return (*line != 'n' && *line != 'N'); 01654 } 01655 01656 #if 0 01657 static void fatal(const char *msg) 01658 { 01659 01660 fprintf(stderr, "ftp: %s\n", msg); 01661 exit(1); 01662 } 01663 #endif 01664 01665 /* 01666 * Glob a local file name specification with 01667 * the expectation of a single return value. 01668 * Can't control multiple values being expanded 01669 * from the expression, we return only the first. 01670 */ 01671 int globulize(const char **cpp) 01672 { 01673 char **globbed; 01674 01675 if (!doglob) 01676 return (1); 01677 globbed = glob(*cpp); 01678 if (globerr != NULL) { 01679 printf("%s: %s\n", *cpp, globerr); 01680 (void) fflush(stdout); 01681 if (globbed) { 01682 blkfree(globbed); 01683 free((char *)globbed); 01684 } 01685 return (0); 01686 } 01687 if (globbed) { 01688 *cpp = *globbed++; 01689 /* don't waste too much memory */ 01690 if (*globbed) { 01691 blkfree(globbed); 01692 free((char *)globbed); 01693 } 01694 } 01695 return (1); 01696 } 01697 01698 void account(int argc, const char *argv[]) 01699 { 01700 char acct[50], *getpass(), *ap; 01701 01702 if (argc > 1) { 01703 ++argv; 01704 --argc; 01705 (void) strncpy(acct,*argv,49); 01706 acct[49] = '\0'; 01707 while (argc > 1) { 01708 --argc; 01709 ++argv; 01710 (void) strncat(acct,*argv, 49-strlen(acct)); 01711 } 01712 ap = acct; 01713 } 01714 else { 01715 ap = getpass("Account:"); 01716 } 01717 (void) command("ACCT %s", ap); 01718 } 01719 01720 jmp_buf abortprox; 01721 01722 #if 0 01723 static void 01724 proxabort() 01725 { 01726 extern int proxy; 01727 01728 if (!proxy) { 01729 pswitch(1); 01730 } 01731 if (connected) { 01732 proxflag = 1; 01733 } 01734 else { 01735 proxflag = 0; 01736 } 01737 pswitch(0); 01738 longjmp(abortprox,1); 01739 } 01740 #endif 01741 01742 void doproxy(int argc, const char *argv[]) 01743 { 01744 register struct cmd *c; 01745 struct cmd *getcmd(); 01746 // extern struct cmd cmdtab[]; 01747 extern jmp_buf abortprox; 01748 01749 if (argc < 2) { 01750 (void) strcat(line, " "); 01751 printf("(command) "); 01752 (void) fflush(stdout); 01753 (void) gets(&line[strlen(line)]); 01754 makeargv(); 01755 argc = margc; 01756 argv = margv; 01757 } 01758 if (argc < 2) { 01759 printf("usage:%s command\n", argv[0]); 01760 (void) fflush(stdout); 01761 code = -1; 01762 return; 01763 } 01764 c = getcmd(argv[1]); 01765 if (c == (struct cmd *) -1) { 01766 printf("?Ambiguous command\n"); 01767 (void) fflush(stdout); 01768 code = -1; 01769 return; 01770 } 01771 if (c == 0) { 01772 printf("?Invalid command\n"); 01773 (void) fflush(stdout); 01774 code = -1; 01775 return; 01776 } 01777 if (!c->c_proxy) { 01778 printf("?Invalid proxy command\n"); 01779 (void) fflush(stdout); 01780 code = -1; 01781 return; 01782 } 01783 if (setjmp(abortprox)) { 01784 code = -1; 01785 return; 01786 } 01787 // oldintr = signal(SIGINT, proxabort); 01788 pswitch(1); 01789 if (c->c_conn && !connected) { 01790 printf("Not connected\n"); 01791 (void) fflush(stdout); 01792 pswitch(0); 01793 // (void) signal(SIGINT, oldintr); 01794 code = -1; 01795 return; 01796 } 01797 (*c->c_handler)(argc-1, argv+1); 01798 if (connected) { 01799 proxflag = 1; 01800 } 01801 else { 01802 proxflag = 0; 01803 } 01804 pswitch(0); 01805 // (void) signal(SIGINT, oldintr); 01806 } 01807 01808 void setcase(int argc, const char *argv[]) 01809 { 01810 mcase = !mcase; 01811 printf("Case mapping %s.\n", onoff(mcase)); 01812 (void) fflush(stdout); 01813 code = mcase; 01814 } 01815 01816 void setcr(int argc, const char *argv[]) 01817 { 01818 crflag = !crflag; 01819 printf("Carriage Return stripping %s.\n", onoff(crflag)); 01820 (void) fflush(stdout); 01821 code = crflag; 01822 } 01823 01824 void setntrans(int argc, const char *argv[]) 01825 { 01826 if (argc == 1) { 01827 ntflag = 0; 01828 printf("Ntrans off.\n"); 01829 (void) fflush(stdout); 01830 code = ntflag; 01831 return; 01832 } 01833 ntflag++; 01834 code = ntflag; 01835 (void) strncpy(ntin, argv[1], 16); 01836 ntin[16] = '\0'; 01837 if (argc == 2) { 01838 ntout[0] = '\0'; 01839 return; 01840 } 01841 (void) strncpy(ntout, argv[2], 16); 01842 ntout[16] = '\0'; 01843 } 01844 01845 const char * 01846 dotrans(const char *name) 01847 { 01848 static char new[MAXPATHLEN]; 01849 const char *cp1; 01850 char *cp2 = new; 01851 register int i, ostop, found; 01852 01853 for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 01854 for (cp1 = name; *cp1; cp1++) { 01855 found = 0; 01856 for (i = 0; *(ntin + i) && i < 16; i++) { 01857 if (*cp1 == *(ntin + i)) { 01858 found++; 01859 if (i < ostop) { 01860 *cp2++ = *(ntout + i); 01861 } 01862 break; 01863 } 01864 } 01865 if (!found) { 01866 *cp2++ = *cp1; 01867 } 01868 } 01869 *cp2 = '\0'; 01870 return(new); 01871 } 01872 01873 void setpassive(int argc, const char *argv[]) 01874 { 01875 passivemode = !passivemode; 01876 printf("Passive mode %s.\n", onoff(passivemode)); 01877 (void) fflush(stdout); 01878 code = passivemode; 01879 } 01880 01881 void setnmap(int argc, const char *argv[]) 01882 { 01883 char *cp; 01884 01885 if (argc == 1) { 01886 mapflag = 0; 01887 printf("Nmap off.\n"); 01888 (void) fflush(stdout); 01889 code = mapflag; 01890 return; 01891 } 01892 if (argc < 3) { 01893 (void) strcat(line, " "); 01894 printf("(mapout) "); 01895 (void) fflush(stdout); 01896 (void) gets(&line[strlen(line)]); 01897 makeargv(); 01898 argc = margc; 01899 argv = margv; 01900 } 01901 if (argc < 3) { 01902 printf("Usage: %s [mapin mapout]\n",argv[0]); 01903 (void) fflush(stdout); 01904 code = -1; 01905 return; 01906 } 01907 mapflag = 1; 01908 code = 1; 01909 cp = index(altarg, ' '); 01910 if (proxy) { 01911 while(*++cp == ' '); 01912 altarg = cp; 01913 cp = index(altarg, ' '); 01914 } 01915 *cp = '\0'; 01916 (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 01917 while (*++cp == ' '); 01918 (void) strncpy(mapout, cp, MAXPATHLEN - 1); 01919 } 01920 01921 const char * 01922 domap(const char *name) 01923 { 01924 static char new[MAXPATHLEN]; 01925 const char *cp1 = name; 01926 char *cpn, *cp2 = mapin; 01927 const char *tp[9], *te[9]; 01928 int i, toks[9], toknum = 0, match = 1; 01929 01930 for (i=0; i < 9; ++i) { 01931 toks[i] = 0; 01932 } 01933 while (match && *cp1 && *cp2) { 01934 switch (*cp2) { 01935 case '\\': 01936 if (*++cp2 != *cp1) { 01937 match = 0; 01938 } 01939 break; 01940 case '$': 01941 if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 01942 if (*cp1 != *(++cp2+1)) { 01943 toks[toknum = *cp2 - '1']++; 01944 tp[toknum] = cp1; 01945 while (*++cp1 && *(cp2+1) 01946 != *cp1); 01947 te[toknum] = cp1; 01948 } 01949 cp2++; 01950 break; 01951 } 01952 /* FALLTHROUGH */ 01953 default: 01954 if (*cp2 != *cp1) { 01955 match = 0; 01956 } 01957 break; 01958 } 01959 if (match && *cp1) { 01960 cp1++; 01961 } 01962 if (match && *cp2) { 01963 cp2++; 01964 } 01965 } 01966 if (!match && *cp1) /* last token mismatch */ 01967 { 01968 toks[toknum] = 0; 01969 } 01970 01971 cpn = new; 01972 *cpn = '\0'; 01973 cp2 = mapout; 01974 while (*cp2) { 01975 match = 0; 01976 switch (*cp2) { 01977 case '\\': 01978 if (*(cp2 + 1)) { 01979 *cpn++ = *++cp2; 01980 } 01981 break; 01982 case '[': 01983 LOOP: 01984 if (*++cp2 == '$' && isdigit(*(cp2+1))) { 01985 if (*++cp2 == '0') { 01986 const char *cp3 = name; 01987 01988 while (*cp3) { 01989 *cpn++ = *cp3++; 01990 } 01991 match = 1; 01992 } 01993 else if (toks[toknum = *cp2 - '1']) { 01994 const char *cp3 = tp[toknum]; 01995 01996 while (cp3 != te[toknum]) { 01997 *cpn++ = *cp3++; 01998 } 01999 match = 1; 02000 } 02001 } 02002 else { 02003 while (*cp2 && *cp2 != ',' && 02004 *cp2 != ']') { 02005 if (*cp2 == '\\') { 02006 cp2++; 02007 } 02008 else if (*cp2 == '$' && 02009 isdigit(*(cp2+1))) { 02010 if (*++cp2 == '0') { 02011 const char *cp3 = name; 02012 02013 while (*cp3) { 02014 *cpn++ = *cp3++; 02015 } 02016 } 02017 else if (toks[toknum = 02018 *cp2 - '1']) { 02019 const char *cp3=tp[toknum]; 02020 02021 while (cp3 != 02022 te[toknum]) { 02023 *cpn++ = *cp3++; 02024 } 02025 } 02026 } 02027 else if (*cp2) { 02028 *cpn++ = *cp2++; 02029 } 02030 } 02031 if (!*cp2) { 02032 printf("nmap: unbalanced brackets\n"); 02033 (void) fflush(stdout); 02034 return(name); 02035 } 02036 match = 1; 02037 cp2--; 02038 } 02039 if (match) { 02040 while (*++cp2 && *cp2 != ']') { 02041 if (*cp2 == '\\' && *(cp2 + 1)) { 02042 cp2++; 02043 } 02044 } 02045 if (!*cp2) { 02046 printf("nmap: unbalanced brackets\n"); 02047 (void) fflush(stdout); 02048 return(name); 02049 } 02050 break; 02051 } 02052 switch (*++cp2) { 02053 case ',': 02054 goto LOOP; 02055 case ']': 02056 break; 02057 default: 02058 cp2--; 02059 goto LOOP; 02060 } 02061 break; 02062 case '$': 02063 if (isdigit(*(cp2 + 1))) { 02064 if (*++cp2 == '0') { 02065 const char *cp3 = name; 02066 02067 while (*cp3) { 02068 *cpn++ = *cp3++; 02069 } 02070 } 02071 else if (toks[toknum = *cp2 - '1']) { 02072 const char *cp3 = tp[toknum]; 02073 02074 while (cp3 != te[toknum]) { 02075 *cpn++ = *cp3++; 02076 } 02077 } 02078 break; 02079 } 02080 /* intentional drop through */ 02081 default: 02082 *cpn++ = *cp2; 02083 break; 02084 } 02085 cp2++; 02086 } 02087 *cpn = '\0'; 02088 if (!*new) { 02089 return(name); 02090 } 02091 return(new); 02092 } 02093 02094 void setsunique(int argc, const char *argv[]) 02095 { 02096 sunique = !sunique; 02097 printf("Store unique %s.\n", onoff(sunique)); 02098 (void) fflush(stdout); 02099 code = sunique; 02100 } 02101 02102 void setrunique(int argc, const char *argv[]) 02103 { 02104 runique = !runique; 02105 printf("Receive unique %s.\n", onoff(runique)); 02106 (void) fflush(stdout); 02107 code = runique; 02108 } 02109 02110 /* change directory to perent directory */ 02111 void cdup(int argc, const char *argv[]) 02112 { 02113 if (command("CDUP") == ERROR && code == 500) { 02114 if (verbose) { 02115 printf("CDUP command not recognized, trying XCUP\n"); 02116 (void) fflush(stdout); 02117 } 02118 (void) command("XCUP"); 02119 } 02120 } 02121 02122 /* restart transfer at specific point */ 02123 void restart(int argc, const char *argv[]) 02124 { 02125 if (argc != 2) 02126 printf("restart: offset not specified\n"); 02127 else { 02128 restart_point = atol(argv[1]); 02129 printf("restarting at %ld. %s\n", restart_point, 02130 "execute get, put or append to initiate transfer"); 02131 } 02132 (void) fflush(stdout); 02133 } 02134 02135 /* show remote system type */ 02136 void syst(int argc, const char *argv[]) 02137 { 02138 (void) command("SYST"); 02139 } 02140 02141 void macdef(int argc, const char *argv[]) 02142 { 02143 char *tmp; 02144 int c; 02145 02146 if (macnum == 16) { 02147 printf("Limit of 16 macros have already been defined\n"); 02148 (void) fflush(stdout); 02149 code = -1; 02150 return; 02151 } 02152 if (argc < 2) { 02153 (void) strcat(line, " "); 02154 printf("(macro name) "); 02155 (void) fflush(stdout); 02156 (void) gets(&line[strlen(line)]); 02157 makeargv(); 02158 argc = margc; 02159 argv = margv; 02160 } 02161 if (argc != 2) { 02162 printf("Usage: %s macro_name\n",argv[0]); 02163 (void) fflush(stdout); 02164 code = -1; 02165 return; 02166 } 02167 if (interactive) { 02168 printf("Enter macro line by line, terminating it with a null line\n"); 02169 (void) fflush(stdout); 02170 } 02171 (void) strncpy(macros[macnum].mac_name, argv[1], 8); 02172 if (macnum == 0) { 02173 macros[macnum].mac_start = macbuf; 02174 } 02175 else { 02176 macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 02177 } 02178 tmp = macros[macnum].mac_start; 02179 while (tmp != macbuf+4096) { 02180 if ((c = getchar()) == EOF) { 02181 printf("macdef:end of file encountered\n"); 02182 (void) fflush(stdout); 02183 code = -1; 02184 return; 02185 } 02186 if ((*tmp = c) == '\n') { 02187 if (tmp == macros[macnum].mac_start) { 02188 macros[macnum++].mac_end = tmp; 02189 code = 0; 02190 return; 02191 } 02192 if (*(tmp-1) == '\0') { 02193 macros[macnum++].mac_end = tmp - 1; 02194 code = 0; 02195 return; 02196 } 02197 *tmp = '\0'; 02198 } 02199 tmp++; 02200 } 02201 while (1) { 02202 while ((c = getchar()) != '\n' && c != EOF) 02203 /* LOOP */; 02204 if (c == EOF || getchar() == '\n') { 02205 printf("Macro not defined - 4k buffer exceeded\n"); 02206 (void) fflush(stdout); 02207 code = -1; 02208 return; 02209 } 02210 } 02211 } 02212 02213 /* 02214 * get size of file on remote machine 02215 */ 02216 void sizecmd(int argc, const char *argv[]) 02217 { 02218 02219 if (argc < 2) { 02220 (void) strcat(line, " "); 02221 printf("(filename) "); 02222 (void) fflush(stdout); 02223 (void) gets(&line[strlen(line)]); 02224 makeargv(); 02225 argc = margc; 02226 argv = margv; 02227 } 02228 if (argc < 2) { 02229 printf("usage:%s filename\n", argv[0]); 02230 (void) fflush(stdout); 02231 code = -1; 02232 return; 02233 } 02234 (void) command("SIZE %s", argv[1]); 02235 } 02236 02237 /* 02238 * get last modification time of file on remote machine 02239 */ 02240 void modtime(int argc, const char *argv[]) 02241 { 02242 int overbose; 02243 02244 if (argc < 2) { 02245 (void) strcat(line, " "); 02246 printf("(filename) "); 02247 (void) fflush(stdout); 02248 (void) gets(&line[strlen(line)]); 02249 makeargv(); 02250 argc = margc; 02251 argv = margv; 02252 } 02253 if (argc < 2) { 02254 printf("usage:%s filename\n", argv[0]); 02255 (void) fflush(stdout); 02256 code = -1; 02257 return; 02258 } 02259 overbose = verbose; 02260 if (debug == 0) 02261 verbose = -1; 02262 if (command("MDTM %s", argv[1]) == COMPLETE) { 02263 int yy, mo, day, hour, min, sec; 02264 sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 02265 &day, &hour, &min, &sec); 02266 /* might want to print this in local time */ 02267 printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 02268 mo, day, yy, hour, min, sec); 02269 } else 02270 printf("%s\n", reply_string); 02271 verbose = overbose; 02272 (void) fflush(stdout); 02273 } 02274 02275 /* 02276 * show status on reomte machine 02277 */ 02278 void rmtstatus(int argc, const char *argv[]) 02279 { 02280 (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 02281 } 02282 02283 /* 02284 * get file if modtime is more recent than current file 02285 */ 02286 void newer(int argc, const char *argv[]) 02287 { 02288 if (getit(argc, argv, -1, "w")) { 02289 printf("Local file \"%s\" is newer than remote file \"%s\"\n", 02290 argv[1], argv[2]); 02291 (void) fflush(stdout); 02292 } 02293 } Generated on Thu May 24 2012 04:17:25 for ReactOS by
1.7.6.1
|