121737Sdist /* 236942Skarels * Copyright (c) 1985, 1989 Regents of the University of California. 333737Sbostic * All rights reserved. 433737Sbostic * 533737Sbostic * Redistribution and use in source and binary forms are permitted 634901Sbostic * provided that the above copyright notice and this paragraph are 734901Sbostic * duplicated in all such forms and that any documentation, 834901Sbostic * advertising materials, and other materials related to such 934901Sbostic * distribution and use acknowledge that the software was developed 1034901Sbostic * by the University of California, Berkeley. The name of the 1134901Sbostic * University may not be used to endorse or promote products derived 1234901Sbostic * from this software without specific prior written permission. 1334901Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434901Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*37224Skarels static char sccsid[] = "@(#)cmds.c 5.15 (Berkeley) 03/21/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2536940Skarels #include <sys/param.h> 2636940Skarels #include <sys/wait.h> 2736940Skarels #include <sys/stat.h> 2810294Ssam #include <sys/socket.h> 2910294Ssam 3012396Ssam #include <arpa/ftp.h> 3112396Ssam 3210294Ssam #include <signal.h> 3310294Ssam #include <stdio.h> 3410294Ssam #include <errno.h> 3510294Ssam #include <netdb.h> 3626049Sminshall #include <ctype.h> 3736935Skarels #include <time.h> 3810294Ssam 3936940Skarels #include "ftp_var.h" 4010294Ssam 4136940Skarels 4211353Ssam extern char *globerr; 4311353Ssam extern char **glob(); 4411756Ssam extern char *home; 4511756Ssam extern char *remglob(); 4611756Ssam extern char *getenv(); 4711756Ssam extern char *index(); 4811756Ssam extern char *rindex(); 49*37224Skarels extern off_t restart_point; 5036935Skarels extern char reply_string[]; 5136935Skarels 5226049Sminshall char *mname; 5326049Sminshall jmp_buf jabort; 5426049Sminshall char *dotrans(), *domap(); 5510294Ssam 5610294Ssam /* 5710294Ssam * Connect to peer server and 5810294Ssam * auto-login, if possible. 5910294Ssam */ 6010294Ssam setpeer(argc, argv) 6110294Ssam int argc; 6210294Ssam char *argv[]; 6310294Ssam { 6425903Skarels char *host, *hookup(); 6510294Ssam int port; 6610294Ssam 6710294Ssam if (connected) { 6826049Sminshall printf("Already connected to %s, use close first.\n", 6910294Ssam hostname); 7026049Sminshall code = -1; 7110294Ssam return; 7210294Ssam } 7310294Ssam if (argc < 2) { 7426497Sminshall (void) strcat(line, " "); 7510294Ssam printf("(to) "); 7626497Sminshall (void) gets(&line[strlen(line)]); 7710294Ssam makeargv(); 7810294Ssam argc = margc; 7910294Ssam argv = margv; 8010294Ssam } 8110294Ssam if (argc > 3) { 8210294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8326049Sminshall code = -1; 8410294Ssam return; 8510294Ssam } 8610294Ssam port = sp->s_port; 8710294Ssam if (argc > 2) { 8811218Ssam port = atoi(argv[2]); 8910294Ssam if (port <= 0) { 9011218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9111218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9226049Sminshall code = -1; 9310294Ssam return; 9410294Ssam } 9510294Ssam port = htons(port); 9610294Ssam } 9710294Ssam host = hookup(argv[1], port); 9810294Ssam if (host) { 9910294Ssam connected = 1; 10036935Skarels if (autologin) { 10136935Skarels int overbose; 10236940Skarels 10326497Sminshall (void) login(argv[1]); 10436935Skarels #if defined(unix) && NBBY == 8 10536935Skarels /* 10636935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 10736935Skarels * system and not checking this out. This way they have to think about it. 10836935Skarels */ 10936940Skarels overbose = verbose; 11036940Skarels if (debug == 0) 11136940Skarels verbose = -1; 11236935Skarels if (command("SYST") == COMPLETE && overbose) { 11336935Skarels register char *cp, c; 11436935Skarels cp = index(reply_string+4, ' '); 11536935Skarels if (cp == NULL) 11636935Skarels cp = index(reply_string+4, '\r'); 11736935Skarels if (cp) { 11836935Skarels if (cp[-1] == '.') 11936935Skarels cp--; 12036935Skarels c = *cp; 12136935Skarels *cp = '\0'; 12236935Skarels } 12336935Skarels 12436935Skarels printf("Remote system type is %s.\n", 12536935Skarels reply_string+4); 12636935Skarels if (cp) 12736935Skarels *cp = c; 12836935Skarels } 12936935Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 13036935Skarels setbinary(); 13136935Skarels if (overbose) 13236940Skarels printf("Using %s mode to transfer files.\n", 13336940Skarels typename); 13436935Skarels } else if (overbose && 13536935Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 13636940Skarels printf( 13736940Skarels "Remember to set tenex mode when transfering binary files from this machine.\n"); 13836935Skarels } 13936935Skarels verbose = overbose; 14036935Skarels #endif /* unix */ 14136935Skarels } 14210294Ssam } 14310294Ssam } 14410294Ssam 14510294Ssam struct types { 14610294Ssam char *t_name; 14710294Ssam char *t_mode; 14810294Ssam int t_type; 14911218Ssam char *t_arg; 15010294Ssam } types[] = { 15111218Ssam { "ascii", "A", TYPE_A, 0 }, 15211218Ssam { "binary", "I", TYPE_I, 0 }, 15311218Ssam { "image", "I", TYPE_I, 0 }, 15411218Ssam { "ebcdic", "E", TYPE_E, 0 }, 15511218Ssam { "tenex", "L", TYPE_L, bytename }, 15610294Ssam 0 15710294Ssam }; 15810294Ssam 15910294Ssam /* 16010294Ssam * Set transfer type. 16110294Ssam */ 16210294Ssam settype(argc, argv) 16310294Ssam char *argv[]; 16410294Ssam { 16510294Ssam register struct types *p; 16611218Ssam int comret; 16710294Ssam 16810294Ssam if (argc > 2) { 16910294Ssam char *sep; 17010294Ssam 17110294Ssam printf("usage: %s [", argv[0]); 17210294Ssam sep = " "; 17310294Ssam for (p = types; p->t_name; p++) { 17410294Ssam printf("%s%s", sep, p->t_name); 17510294Ssam if (*sep == ' ') 17610294Ssam sep = " | "; 17710294Ssam } 17810294Ssam printf(" ]\n"); 17926049Sminshall code = -1; 18010294Ssam return; 18110294Ssam } 18210294Ssam if (argc < 2) { 18310294Ssam printf("Using %s mode to transfer files.\n", typename); 18426049Sminshall code = 0; 18510294Ssam return; 18610294Ssam } 18710294Ssam for (p = types; p->t_name; p++) 18810294Ssam if (strcmp(argv[1], p->t_name) == 0) 18910294Ssam break; 19010294Ssam if (p->t_name == 0) { 19110294Ssam printf("%s: unknown mode\n", argv[1]); 19226049Sminshall code = -1; 19310294Ssam return; 19410294Ssam } 19511218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 19611218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 19711218Ssam else 19811218Ssam comret = command("TYPE %s", p->t_mode); 19911218Ssam if (comret == COMPLETE) { 20026497Sminshall (void) strcpy(typename, p->t_name); 20110294Ssam type = p->t_type; 20210294Ssam } 20310294Ssam } 20410294Ssam 20510294Ssam /* 20610294Ssam * Set binary transfer type. 20710294Ssam */ 20810294Ssam /*VARARGS*/ 20910294Ssam setbinary() 21010294Ssam { 21110294Ssam 21210294Ssam call(settype, "type", "binary", 0); 21310294Ssam } 21410294Ssam 21510294Ssam /* 21610294Ssam * Set ascii transfer type. 21710294Ssam */ 21810294Ssam /*VARARGS*/ 21910294Ssam setascii() 22010294Ssam { 22110294Ssam 22210294Ssam call(settype, "type", "ascii", 0); 22310294Ssam } 22410294Ssam 22510294Ssam /* 22610294Ssam * Set tenex transfer type. 22710294Ssam */ 22810294Ssam /*VARARGS*/ 22910294Ssam settenex() 23010294Ssam { 23110294Ssam 23210294Ssam call(settype, "type", "tenex", 0); 23310294Ssam } 23410294Ssam 23510294Ssam /* 23610294Ssam * Set ebcdic transfer type. 23710294Ssam */ 23810294Ssam /*VARARGS*/ 23910294Ssam setebcdic() 24010294Ssam { 24110294Ssam 24210294Ssam call(settype, "type", "ebcdic", 0); 24310294Ssam } 24410294Ssam 24510294Ssam /* 24610294Ssam * Set file transfer mode. 24710294Ssam */ 24826497Sminshall /*ARGSUSED*/ 24910294Ssam setmode(argc, argv) 25010294Ssam char *argv[]; 25110294Ssam { 25210294Ssam 25310294Ssam printf("We only support %s mode, sorry.\n", modename); 25426049Sminshall code = -1; 25510294Ssam } 25610294Ssam 25710294Ssam /* 25810294Ssam * Set file transfer format. 25910294Ssam */ 26026497Sminshall /*ARGSUSED*/ 26110294Ssam setform(argc, argv) 26210294Ssam char *argv[]; 26310294Ssam { 26410294Ssam 26510294Ssam printf("We only support %s format, sorry.\n", formname); 26626049Sminshall code = -1; 26710294Ssam } 26810294Ssam 26910294Ssam /* 27010294Ssam * Set file transfer structure. 27110294Ssam */ 27226497Sminshall /*ARGSUSED*/ 27310294Ssam setstruct(argc, argv) 27410294Ssam char *argv[]; 27510294Ssam { 27610294Ssam 27710294Ssam printf("We only support %s structure, sorry.\n", structname); 27826049Sminshall code = -1; 27910294Ssam } 28010294Ssam 28118286Sralph /* 28218286Sralph * Send a single file. 28318286Sralph */ 28410294Ssam put(argc, argv) 28511756Ssam int argc; 28610294Ssam char *argv[]; 28710294Ssam { 28811650Ssam char *cmd; 28926049Sminshall int loc = 0; 29025908Smckusick char *oldargv1; 29111650Ssam 29226049Sminshall if (argc == 2) { 29326049Sminshall argc++; 29426049Sminshall argv[2] = argv[1]; 29526049Sminshall loc++; 29626049Sminshall } 29710294Ssam if (argc < 2) { 29826497Sminshall (void) strcat(line, " "); 29910294Ssam printf("(local-file) "); 30026497Sminshall (void) gets(&line[strlen(line)]); 30110294Ssam makeargv(); 30210294Ssam argc = margc; 30310294Ssam argv = margv; 30410294Ssam } 30510294Ssam if (argc < 2) { 30610294Ssam usage: 30726049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 30826049Sminshall code = -1; 30910294Ssam return; 31010294Ssam } 31110294Ssam if (argc < 3) { 31226497Sminshall (void) strcat(line, " "); 31310294Ssam printf("(remote-file) "); 31426497Sminshall (void) gets(&line[strlen(line)]); 31510294Ssam makeargv(); 31610294Ssam argc = margc; 31710294Ssam argv = margv; 31810294Ssam } 31910294Ssam if (argc < 3) 32010294Ssam goto usage; 32125908Smckusick oldargv1 = argv[1]; 32226049Sminshall if (!globulize(&argv[1])) { 32326049Sminshall code = -1; 32411353Ssam return; 32526049Sminshall } 32625908Smckusick /* 32725908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 32825908Smckusick * the old argv[1], make it a copy of the new argv[1]. 32925908Smckusick */ 33026049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 33125908Smckusick argv[2] = argv[1]; 33226049Sminshall } 33326049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 33426049Sminshall if (loc && ntflag) { 33526049Sminshall argv[2] = dotrans(argv[2]); 33626049Sminshall } 33726049Sminshall if (loc && mapflag) { 33826049Sminshall argv[2] = domap(argv[2]); 33926049Sminshall } 34011650Ssam sendrequest(cmd, argv[1], argv[2]); 34110294Ssam } 34210294Ssam 34310294Ssam /* 34411756Ssam * Send multiple files. 34510294Ssam */ 34611353Ssam mput(argc, argv) 34711353Ssam char *argv[]; 34811353Ssam { 34913212Ssam register int i; 35026049Sminshall int ointer, (*oldintr)(), mabort(); 35126049Sminshall extern jmp_buf jabort; 35226049Sminshall char *tp; 35311353Ssam 35411650Ssam if (argc < 2) { 35526497Sminshall (void) strcat(line, " "); 35611650Ssam printf("(local-files) "); 35726497Sminshall (void) gets(&line[strlen(line)]); 35811650Ssam makeargv(); 35911650Ssam argc = margc; 36011650Ssam argv = margv; 36111353Ssam } 36211353Ssam if (argc < 2) { 36326049Sminshall printf("usage:%s local-files\n", argv[0]); 36426049Sminshall code = -1; 36511353Ssam return; 36611353Ssam } 36726049Sminshall mname = argv[0]; 36826049Sminshall mflag = 1; 36926049Sminshall oldintr = signal(SIGINT, mabort); 37026049Sminshall (void) setjmp(jabort); 37126049Sminshall if (proxy) { 37226049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 37326049Sminshall 37426497Sminshall while ((cp = remglob(argv,0)) != NULL) { 37526049Sminshall if (*cp == 0) { 37626049Sminshall mflag = 0; 37726049Sminshall continue; 37826049Sminshall } 37926049Sminshall if (mflag && confirm(argv[0], cp)) { 38026049Sminshall tp = cp; 38126049Sminshall if (mcase) { 38226049Sminshall while (*tp && !islower(*tp)) { 38326049Sminshall tp++; 38426049Sminshall } 38526049Sminshall if (!*tp) { 38626049Sminshall tp = cp; 38726049Sminshall tp2 = tmpbuf; 38826049Sminshall while ((*tp2 = *tp) != NULL) { 38926049Sminshall if (isupper(*tp2)) { 39026049Sminshall *tp2 = 'a' + *tp2 - 'A'; 39126049Sminshall } 39226049Sminshall tp++; 39326049Sminshall tp2++; 39426049Sminshall } 39526049Sminshall } 39626049Sminshall tp = tmpbuf; 39726049Sminshall } 39826049Sminshall if (ntflag) { 39926049Sminshall tp = dotrans(tp); 40026049Sminshall } 40126049Sminshall if (mapflag) { 40226049Sminshall tp = domap(tp); 40326049Sminshall } 40426049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 40526049Sminshall if (!mflag && fromatty) { 40626049Sminshall ointer = interactive; 40726049Sminshall interactive = 1; 40826049Sminshall if (confirm("Continue with","mput")) { 40926049Sminshall mflag++; 41026049Sminshall } 41126049Sminshall interactive = ointer; 41226049Sminshall } 41326049Sminshall } 41426049Sminshall } 41526049Sminshall (void) signal(SIGINT, oldintr); 41626049Sminshall mflag = 0; 41726049Sminshall return; 41826049Sminshall } 41913212Ssam for (i = 1; i < argc; i++) { 42013212Ssam register char **cpp, **gargs; 42113212Ssam 42213212Ssam if (!doglob) { 42326049Sminshall if (mflag && confirm(argv[0], argv[i])) { 42426049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 42526049Sminshall tp = (mapflag) ? domap(tp) : tp; 42626049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 42726049Sminshall argv[i], tp); 42826049Sminshall if (!mflag && fromatty) { 42926049Sminshall ointer = interactive; 43026049Sminshall interactive = 1; 43126049Sminshall if (confirm("Continue with","mput")) { 43226049Sminshall mflag++; 43326049Sminshall } 43426049Sminshall interactive = ointer; 43526049Sminshall } 43626049Sminshall } 43713212Ssam continue; 43813212Ssam } 43913212Ssam gargs = glob(argv[i]); 44011650Ssam if (globerr != NULL) { 44111650Ssam printf("%s\n", globerr); 44236421Sbostic if (gargs) { 44311650Ssam blkfree(gargs); 44436421Sbostic free(gargs); 44536421Sbostic } 44613212Ssam continue; 44711353Ssam } 44826049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 44926049Sminshall if (mflag && confirm(argv[0], *cpp)) { 45026049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 45126049Sminshall tp = (mapflag) ? domap(tp) : tp; 45226049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 45326049Sminshall *cpp, tp); 45426049Sminshall if (!mflag && fromatty) { 45526049Sminshall ointer = interactive; 45626049Sminshall interactive = 1; 45726049Sminshall if (confirm("Continue with","mput")) { 45826049Sminshall mflag++; 45926049Sminshall } 46026049Sminshall interactive = ointer; 46126049Sminshall } 46226049Sminshall } 46326049Sminshall } 46436421Sbostic if (gargs != NULL) { 46513212Ssam blkfree(gargs); 46636421Sbostic free(gargs); 46736421Sbostic } 46811353Ssam } 46926049Sminshall (void) signal(SIGINT, oldintr); 47026049Sminshall mflag = 0; 47111353Ssam } 47211353Ssam 473*37224Skarels reget(argc, argv) 474*37224Skarels char *argv[]; 475*37224Skarels { 476*37224Skarels (void) getit(argc, argv, 1, "r+w"); 477*37224Skarels } 47836935Skarels 479*37224Skarels get(argc, argv) 480*37224Skarels char *argv[]; 481*37224Skarels { 482*37224Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 483*37224Skarels } 484*37224Skarels 48511353Ssam /* 48611353Ssam * Receive one file. 48711353Ssam */ 488*37224Skarels getit(argc, argv, restartit, mode) 48910294Ssam char *argv[]; 490*37224Skarels char *mode; 49110294Ssam { 49226049Sminshall int loc = 0; 49310294Ssam 49426049Sminshall if (argc == 2) { 49526049Sminshall argc++; 49626049Sminshall argv[2] = argv[1]; 49726049Sminshall loc++; 49826049Sminshall } 49910294Ssam if (argc < 2) { 50026497Sminshall (void) strcat(line, " "); 50110294Ssam printf("(remote-file) "); 50226497Sminshall (void) gets(&line[strlen(line)]); 50310294Ssam makeargv(); 50410294Ssam argc = margc; 50510294Ssam argv = margv; 50610294Ssam } 50710294Ssam if (argc < 2) { 50810294Ssam usage: 50926049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 51026049Sminshall code = -1; 511*37224Skarels return (0); 51210294Ssam } 51310294Ssam if (argc < 3) { 51426497Sminshall (void) strcat(line, " "); 51510294Ssam printf("(local-file) "); 51626497Sminshall (void) gets(&line[strlen(line)]); 51710294Ssam makeargv(); 51810294Ssam argc = margc; 51910294Ssam argv = margv; 52010294Ssam } 52110294Ssam if (argc < 3) 52210294Ssam goto usage; 52326049Sminshall if (!globulize(&argv[2])) { 52426049Sminshall code = -1; 525*37224Skarels return (0); 52626049Sminshall } 52726049Sminshall if (loc && mcase) { 52826049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 52926049Sminshall 53026049Sminshall while (*tp && !islower(*tp)) { 53126049Sminshall tp++; 53226049Sminshall } 53326049Sminshall if (!*tp) { 53426049Sminshall tp = argv[2]; 53526049Sminshall tp2 = tmpbuf; 53626049Sminshall while ((*tp2 = *tp) != NULL) { 53726049Sminshall if (isupper(*tp2)) { 53826049Sminshall *tp2 = 'a' + *tp2 - 'A'; 53926049Sminshall } 54026049Sminshall tp++; 54126049Sminshall tp2++; 54226049Sminshall } 54326049Sminshall argv[2] = tmpbuf; 54426049Sminshall } 54526049Sminshall } 54636940Skarels if (loc && ntflag) 54726049Sminshall argv[2] = dotrans(argv[2]); 54836940Skarels if (loc && mapflag) 54926049Sminshall argv[2] = domap(argv[2]); 550*37224Skarels if (restartit) { 551*37224Skarels struct stat stbuf; 552*37224Skarels int ret; 553*37224Skarels 554*37224Skarels ret = stat(argv[2], &stbuf); 555*37224Skarels if (restartit == 1) { 556*37224Skarels if (ret < 0) { 557*37224Skarels perror(argv[2]); 558*37224Skarels return (0); 559*37224Skarels } 560*37224Skarels restart_point = stbuf.st_size; 561*37224Skarels } else { 562*37224Skarels if (ret == 0) { 563*37224Skarels int overbose; 564*37224Skarels 565*37224Skarels overbose = verbose; 566*37224Skarels if (debug == 0) 567*37224Skarels verbose = -1; 568*37224Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 569*37224Skarels int yy, mo, day, hour, min, sec; 570*37224Skarels struct tm *tm; 571*37224Skarels verbose = overbose; 572*37224Skarels sscanf(reply_string, 573*37224Skarels "%*s %04d%02d%02d%02d%02d%02d", 574*37224Skarels &yy, &mo, &day, &hour, &min, &sec); 575*37224Skarels tm = gmtime(&stbuf.st_mtime); 576*37224Skarels tm->tm_mon++; 577*37224Skarels if (tm->tm_year > yy%100) 578*37224Skarels return (1); 579*37224Skarels else if (tm->tm_year == yy%100) { 580*37224Skarels if (tm->tm_mon > mo) 581*37224Skarels return (1); 582*37224Skarels } else if (tm->tm_mon == mo) { 583*37224Skarels if (tm->tm_mday > day) 584*37224Skarels return (1); 585*37224Skarels } else if (tm->tm_mday == day) { 586*37224Skarels if (tm->tm_hour > hour) 587*37224Skarels return (1); 588*37224Skarels } else if (tm->tm_hour == hour) { 589*37224Skarels if (tm->tm_min > min) 590*37224Skarels return (1); 591*37224Skarels } else if (tm->tm_min == min) { 592*37224Skarels if (tm->tm_sec > sec) 593*37224Skarels return (1); 594*37224Skarels } 595*37224Skarels } else { 596*37224Skarels fputs(reply_string, stdout); 597*37224Skarels verbose = overbose; 598*37224Skarels return (0); 599*37224Skarels } 600*37224Skarels } 601*37224Skarels } 602*37224Skarels } 603*37224Skarels 604*37224Skarels recvrequest("RETR", argv[2], argv[1], mode); 605*37224Skarels restart_point = 0; 606*37224Skarels return (0); 60710294Ssam } 60810294Ssam 60926049Sminshall mabort() 61026049Sminshall { 61126049Sminshall int ointer; 61226049Sminshall extern jmp_buf jabort; 61326049Sminshall 61426049Sminshall printf("\n"); 61526049Sminshall (void) fflush(stdout); 61626049Sminshall if (mflag && fromatty) { 61726049Sminshall ointer = interactive; 61826049Sminshall interactive = 1; 61926049Sminshall if (confirm("Continue with", mname)) { 62026049Sminshall interactive = ointer; 62126049Sminshall longjmp(jabort,0); 62226049Sminshall } 62326049Sminshall interactive = ointer; 62426049Sminshall } 62526049Sminshall mflag = 0; 62626049Sminshall longjmp(jabort,0); 62726049Sminshall } 62826049Sminshall 62911353Ssam /* 63011353Ssam * Get multiple files. 63111353Ssam */ 63211353Ssam mget(argc, argv) 63311353Ssam char *argv[]; 63411353Ssam { 63526049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 63626049Sminshall int ointer, (*oldintr)(), mabort(); 63726049Sminshall extern jmp_buf jabort; 63811353Ssam 63911353Ssam if (argc < 2) { 64026497Sminshall (void) strcat(line, " "); 64111756Ssam printf("(remote-files) "); 64226497Sminshall (void) gets(&line[strlen(line)]); 64311353Ssam makeargv(); 64411353Ssam argc = margc; 64511353Ssam argv = margv; 64611353Ssam } 64711353Ssam if (argc < 2) { 64826049Sminshall printf("usage:%s remote-files\n", argv[0]); 64926049Sminshall code = -1; 65011353Ssam return; 65111353Ssam } 65226049Sminshall mname = argv[0]; 65326049Sminshall mflag = 1; 65426049Sminshall oldintr = signal(SIGINT,mabort); 65526049Sminshall (void) setjmp(jabort); 65626497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 65726049Sminshall if (*cp == '\0') { 65826049Sminshall mflag = 0; 65926049Sminshall continue; 66026049Sminshall } 66126049Sminshall if (mflag && confirm(argv[0], cp)) { 66226049Sminshall tp = cp; 66326049Sminshall if (mcase) { 66426049Sminshall while (*tp && !islower(*tp)) { 66526049Sminshall tp++; 66626049Sminshall } 66726049Sminshall if (!*tp) { 66826049Sminshall tp = cp; 66926049Sminshall tp2 = tmpbuf; 67026049Sminshall while ((*tp2 = *tp) != NULL) { 67126049Sminshall if (isupper(*tp2)) { 67226049Sminshall *tp2 = 'a' + *tp2 - 'A'; 67326049Sminshall } 67426049Sminshall tp++; 67526049Sminshall tp2++; 67626049Sminshall } 67726049Sminshall } 67826049Sminshall tp = tmpbuf; 67926049Sminshall } 68026049Sminshall if (ntflag) { 68126049Sminshall tp = dotrans(tp); 68226049Sminshall } 68326049Sminshall if (mapflag) { 68426049Sminshall tp = domap(tp); 68526049Sminshall } 68626049Sminshall recvrequest("RETR", tp, cp, "w"); 68726049Sminshall if (!mflag && fromatty) { 68826049Sminshall ointer = interactive; 68926049Sminshall interactive = 1; 69026049Sminshall if (confirm("Continue with","mget")) { 69126049Sminshall mflag++; 69226049Sminshall } 69326049Sminshall interactive = ointer; 69426049Sminshall } 69526049Sminshall } 69626049Sminshall } 69726049Sminshall (void) signal(SIGINT,oldintr); 69826049Sminshall mflag = 0; 69911650Ssam } 70011650Ssam 70111650Ssam char * 70226497Sminshall remglob(argv,doswitch) 70311650Ssam char *argv[]; 70426497Sminshall int doswitch; 70511650Ssam { 70611756Ssam char temp[16]; 70711650Ssam static char buf[MAXPATHLEN]; 70811650Ssam static FILE *ftemp = NULL; 70911650Ssam static char **args; 71013212Ssam int oldverbose, oldhash; 71111756Ssam char *cp, *mode; 71211650Ssam 71326049Sminshall if (!mflag) { 71426049Sminshall if (!doglob) { 71526049Sminshall args = NULL; 71626049Sminshall } 71726049Sminshall else { 71826049Sminshall if (ftemp) { 71926497Sminshall (void) fclose(ftemp); 72026049Sminshall ftemp = NULL; 72126049Sminshall } 72226049Sminshall } 72326049Sminshall return(NULL); 72426049Sminshall } 72511650Ssam if (!doglob) { 72611756Ssam if (args == NULL) 72711650Ssam args = argv; 72811650Ssam if ((cp = *++args) == NULL) 72911650Ssam args = NULL; 73011650Ssam return (cp); 73111353Ssam } 73211650Ssam if (ftemp == NULL) { 73326497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 73426497Sminshall (void) mktemp(temp); 73511650Ssam oldverbose = verbose, verbose = 0; 73613212Ssam oldhash = hash, hash = 0; 73726049Sminshall if (doswitch) { 73826049Sminshall pswitch(!proxy); 73926049Sminshall } 74011756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 74111756Ssam recvrequest ("NLST", temp, *argv, mode); 74226049Sminshall if (doswitch) { 74326049Sminshall pswitch(!proxy); 74426049Sminshall } 74513212Ssam verbose = oldverbose; hash = oldhash; 74611650Ssam ftemp = fopen(temp, "r"); 74726497Sminshall (void) unlink(temp); 74811650Ssam if (ftemp == NULL) { 74911650Ssam printf("can't find list of remote files, oops\n"); 75011756Ssam return (NULL); 75111353Ssam } 75211353Ssam } 75311650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 75426497Sminshall (void) fclose(ftemp), ftemp = NULL; 75511650Ssam return (NULL); 75611353Ssam } 75711650Ssam if ((cp = index(buf, '\n')) != NULL) 75811650Ssam *cp = '\0'; 75911650Ssam return (buf); 76011353Ssam } 76111353Ssam 76210294Ssam char * 76310294Ssam onoff(bool) 76410294Ssam int bool; 76510294Ssam { 76610294Ssam 76710294Ssam return (bool ? "on" : "off"); 76810294Ssam } 76910294Ssam 77010294Ssam /* 77110294Ssam * Show status. 77210294Ssam */ 77326497Sminshall /*ARGSUSED*/ 77410294Ssam status(argc, argv) 77510294Ssam char *argv[]; 77610294Ssam { 77726049Sminshall int i; 77810294Ssam 77910294Ssam if (connected) 78010294Ssam printf("Connected to %s.\n", hostname); 78110294Ssam else 78210294Ssam printf("Not connected.\n"); 78326049Sminshall if (!proxy) { 78426049Sminshall pswitch(1); 78526049Sminshall if (connected) { 78626049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 78726049Sminshall } 78826049Sminshall else { 78926049Sminshall printf("No proxy connection.\n"); 79026049Sminshall } 79126049Sminshall pswitch(0); 79226049Sminshall } 79310294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 79410294Ssam modename, typename, formname, structname); 79511353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 79611353Ssam onoff(verbose), onoff(bell), onoff(interactive), 79711353Ssam onoff(doglob)); 79826049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 79926049Sminshall onoff(runique)); 80026049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 80126049Sminshall if (ntflag) { 80226049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 80326049Sminshall } 80426049Sminshall else { 80526049Sminshall printf("Ntrans: off\n"); 80626049Sminshall } 80726049Sminshall if (mapflag) { 80826049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 80926049Sminshall } 81026049Sminshall else { 81126049Sminshall printf("Nmap: off\n"); 81226049Sminshall } 81314143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 81414143Ssam onoff(hash), onoff(sendport)); 81526049Sminshall if (macnum > 0) { 81626049Sminshall printf("Macros:\n"); 81726049Sminshall for (i=0; i<macnum; i++) { 81826049Sminshall printf("\t%s\n",macros[i].mac_name); 81926049Sminshall } 82026049Sminshall } 82126049Sminshall code = 0; 82210294Ssam } 82310294Ssam 82410294Ssam /* 82510294Ssam * Set beep on cmd completed mode. 82610294Ssam */ 82710294Ssam /*VARARGS*/ 82810294Ssam setbell() 82910294Ssam { 83010294Ssam 83110294Ssam bell = !bell; 83210294Ssam printf("Bell mode %s.\n", onoff(bell)); 83326049Sminshall code = bell; 83410294Ssam } 83510294Ssam 83610294Ssam /* 83710294Ssam * Turn on packet tracing. 83810294Ssam */ 83910294Ssam /*VARARGS*/ 84010294Ssam settrace() 84110294Ssam { 84210294Ssam 84310294Ssam trace = !trace; 84410294Ssam printf("Packet tracing %s.\n", onoff(trace)); 84526049Sminshall code = trace; 84610294Ssam } 84710294Ssam 84810294Ssam /* 84911650Ssam * Toggle hash mark printing during transfers. 85011650Ssam */ 85111650Ssam /*VARARGS*/ 85211650Ssam sethash() 85311650Ssam { 85411650Ssam 85511650Ssam hash = !hash; 85611650Ssam printf("Hash mark printing %s", onoff(hash)); 85726049Sminshall code = hash; 85811650Ssam if (hash) 859*37224Skarels printf(" (%d bytes/hash mark)", 1024); 86011650Ssam printf(".\n"); 86111650Ssam } 86211650Ssam 86311650Ssam /* 86410294Ssam * Turn on printing of server echo's. 86510294Ssam */ 86610294Ssam /*VARARGS*/ 86710294Ssam setverbose() 86810294Ssam { 86910294Ssam 87010294Ssam verbose = !verbose; 87110294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 87226049Sminshall code = verbose; 87310294Ssam } 87410294Ssam 87510294Ssam /* 87611650Ssam * Toggle PORT cmd use before each data connection. 87711650Ssam */ 87811650Ssam /*VARARGS*/ 87911650Ssam setport() 88011650Ssam { 88111650Ssam 88211650Ssam sendport = !sendport; 88311650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 88426049Sminshall code = sendport; 88511650Ssam } 88611650Ssam 88711650Ssam /* 88810294Ssam * Turn on interactive prompting 88910294Ssam * during mget, mput, and mdelete. 89010294Ssam */ 89110294Ssam /*VARARGS*/ 89210294Ssam setprompt() 89310294Ssam { 89410294Ssam 89510294Ssam interactive = !interactive; 89610294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 89726049Sminshall code = interactive; 89810294Ssam } 89910294Ssam 90010294Ssam /* 90111353Ssam * Toggle metacharacter interpretation 90211353Ssam * on local file names. 90311353Ssam */ 90411353Ssam /*VARARGS*/ 90511353Ssam setglob() 90611353Ssam { 90711353Ssam 90811353Ssam doglob = !doglob; 90911353Ssam printf("Globbing %s.\n", onoff(doglob)); 91026049Sminshall code = doglob; 91111353Ssam } 91211353Ssam 91311353Ssam /* 91410294Ssam * Set debugging mode on/off and/or 91510294Ssam * set level of debugging. 91610294Ssam */ 91711756Ssam /*VARARGS*/ 91810294Ssam setdebug(argc, argv) 91910294Ssam char *argv[]; 92010294Ssam { 92110294Ssam int val; 92210294Ssam 92310294Ssam if (argc > 1) { 92410294Ssam val = atoi(argv[1]); 92510294Ssam if (val < 0) { 92610294Ssam printf("%s: bad debugging value.\n", argv[1]); 92726049Sminshall code = -1; 92810294Ssam return; 92910294Ssam } 93010294Ssam } else 93110294Ssam val = !debug; 93210294Ssam debug = val; 93310294Ssam if (debug) 93410294Ssam options |= SO_DEBUG; 93510294Ssam else 93610294Ssam options &= ~SO_DEBUG; 93710294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 93826049Sminshall code = debug > 0; 93910294Ssam } 94010294Ssam 94110294Ssam /* 94210294Ssam * Set current working directory 94310294Ssam * on remote machine. 94410294Ssam */ 94510294Ssam cd(argc, argv) 94610294Ssam char *argv[]; 94710294Ssam { 94810294Ssam 94910294Ssam if (argc < 2) { 95026497Sminshall (void) strcat(line, " "); 95110294Ssam printf("(remote-directory) "); 95226497Sminshall (void) gets(&line[strlen(line)]); 95310294Ssam makeargv(); 95410294Ssam argc = margc; 95510294Ssam argv = margv; 95610294Ssam } 95710294Ssam if (argc < 2) { 95826049Sminshall printf("usage:%s remote-directory\n", argv[0]); 95926049Sminshall code = -1; 96010294Ssam return; 96110294Ssam } 962*37224Skarels if (command("CWD %s", argv[1]) == ERROR && code == 500) { 963*37224Skarels if (verbose) 964*37224Skarels printf("CWD command not recognized, trying XCWD\n"); 965*37224Skarels (void) command("XCWD %s", argv[1]); 966*37224Skarels } 96710294Ssam } 96810294Ssam 96910294Ssam /* 97010294Ssam * Set current working directory 97110294Ssam * on local machine. 97210294Ssam */ 97310294Ssam lcd(argc, argv) 97410294Ssam char *argv[]; 97510294Ssam { 97611353Ssam char buf[MAXPATHLEN]; 97710294Ssam 97811353Ssam if (argc < 2) 97911353Ssam argc++, argv[1] = home; 98010294Ssam if (argc != 2) { 98126049Sminshall printf("usage:%s local-directory\n", argv[0]); 98226049Sminshall code = -1; 98310294Ssam return; 98410294Ssam } 98526049Sminshall if (!globulize(&argv[1])) { 98626049Sminshall code = -1; 98711353Ssam return; 98826049Sminshall } 98911353Ssam if (chdir(argv[1]) < 0) { 99010294Ssam perror(argv[1]); 99126049Sminshall code = -1; 99211353Ssam return; 99311353Ssam } 99411353Ssam printf("Local directory now %s\n", getwd(buf)); 99526049Sminshall code = 0; 99610294Ssam } 99710294Ssam 99810294Ssam /* 99910294Ssam * Delete a single file. 100010294Ssam */ 100110294Ssam delete(argc, argv) 100210294Ssam char *argv[]; 100310294Ssam { 100410294Ssam 100510294Ssam if (argc < 2) { 100626497Sminshall (void) strcat(line, " "); 100710294Ssam printf("(remote-file) "); 100826497Sminshall (void) gets(&line[strlen(line)]); 100910294Ssam makeargv(); 101010294Ssam argc = margc; 101110294Ssam argv = margv; 101210294Ssam } 101310294Ssam if (argc < 2) { 101426049Sminshall printf("usage:%s remote-file\n", argv[0]); 101526049Sminshall code = -1; 101610294Ssam return; 101710294Ssam } 101810294Ssam (void) command("DELE %s", argv[1]); 101910294Ssam } 102010294Ssam 102110294Ssam /* 102211650Ssam * Delete multiple files. 102311650Ssam */ 102411650Ssam mdelete(argc, argv) 102511650Ssam char *argv[]; 102611650Ssam { 102711650Ssam char *cp; 102826049Sminshall int ointer, (*oldintr)(), mabort(); 102926049Sminshall extern jmp_buf jabort; 103011650Ssam 103111650Ssam if (argc < 2) { 103226497Sminshall (void) strcat(line, " "); 103311650Ssam printf("(remote-files) "); 103426497Sminshall (void) gets(&line[strlen(line)]); 103511650Ssam makeargv(); 103611650Ssam argc = margc; 103711650Ssam argv = margv; 103811650Ssam } 103911650Ssam if (argc < 2) { 104026049Sminshall printf("usage:%s remote-files\n", argv[0]); 104126049Sminshall code = -1; 104211650Ssam return; 104311650Ssam } 104426049Sminshall mname = argv[0]; 104526049Sminshall mflag = 1; 104626049Sminshall oldintr = signal(SIGINT, mabort); 104726049Sminshall (void) setjmp(jabort); 104826497Sminshall while ((cp = remglob(argv,0)) != NULL) { 104926049Sminshall if (*cp == '\0') { 105026049Sminshall mflag = 0; 105126049Sminshall continue; 105226049Sminshall } 105326049Sminshall if (mflag && confirm(argv[0], cp)) { 105411650Ssam (void) command("DELE %s", cp); 105526049Sminshall if (!mflag && fromatty) { 105626049Sminshall ointer = interactive; 105726049Sminshall interactive = 1; 105826049Sminshall if (confirm("Continue with", "mdelete")) { 105926049Sminshall mflag++; 106026049Sminshall } 106126049Sminshall interactive = ointer; 106226049Sminshall } 106326049Sminshall } 106426049Sminshall } 106526049Sminshall (void) signal(SIGINT, oldintr); 106626049Sminshall mflag = 0; 106711650Ssam } 106811756Ssam 106911650Ssam /* 107010294Ssam * Rename a remote file. 107110294Ssam */ 107210294Ssam renamefile(argc, argv) 107310294Ssam char *argv[]; 107410294Ssam { 107510294Ssam 107610294Ssam if (argc < 2) { 107726497Sminshall (void) strcat(line, " "); 107810294Ssam printf("(from-name) "); 107926497Sminshall (void) gets(&line[strlen(line)]); 108010294Ssam makeargv(); 108110294Ssam argc = margc; 108210294Ssam argv = margv; 108310294Ssam } 108410294Ssam if (argc < 2) { 108510294Ssam usage: 108610294Ssam printf("%s from-name to-name\n", argv[0]); 108726049Sminshall code = -1; 108810294Ssam return; 108910294Ssam } 109010294Ssam if (argc < 3) { 109126497Sminshall (void) strcat(line, " "); 109210294Ssam printf("(to-name) "); 109326497Sminshall (void) gets(&line[strlen(line)]); 109410294Ssam makeargv(); 109510294Ssam argc = margc; 109610294Ssam argv = margv; 109710294Ssam } 109810294Ssam if (argc < 3) 109910294Ssam goto usage; 110010294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 110110294Ssam (void) command("RNTO %s", argv[2]); 110210294Ssam } 110310294Ssam 110410294Ssam /* 110510294Ssam * Get a directory listing 110610294Ssam * of remote files. 110710294Ssam */ 110810294Ssam ls(argc, argv) 110910294Ssam char *argv[]; 111010294Ssam { 111111756Ssam char *cmd; 111210294Ssam 111310294Ssam if (argc < 2) 111410294Ssam argc++, argv[1] = NULL; 111510294Ssam if (argc < 3) 111610294Ssam argc++, argv[2] = "-"; 111711756Ssam if (argc > 3) { 111811756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 111926049Sminshall code = -1; 112011756Ssam return; 112111756Ssam } 112236935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 112326049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 112426049Sminshall code = -1; 112511353Ssam return; 112626049Sminshall } 112732344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 112832344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 112932344Scsvsj code = -1; 113032344Scsvsj return; 113132344Scsvsj } 113211756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 113310294Ssam } 113410294Ssam 113510294Ssam /* 113611756Ssam * Get a directory listing 113711756Ssam * of multiple remote files. 113811756Ssam */ 113911756Ssam mls(argc, argv) 114011756Ssam char *argv[]; 114111756Ssam { 114226049Sminshall char *cmd, mode[1], *dest; 114326049Sminshall int ointer, i, (*oldintr)(), mabort(); 114426049Sminshall extern jmp_buf jabort; 114511756Ssam 114613212Ssam if (argc < 2) { 114726497Sminshall (void) strcat(line, " "); 114813212Ssam printf("(remote-files) "); 114926497Sminshall (void) gets(&line[strlen(line)]); 115013212Ssam makeargv(); 115113212Ssam argc = margc; 115213212Ssam argv = margv; 115313212Ssam } 115413212Ssam if (argc < 3) { 115526497Sminshall (void) strcat(line, " "); 115613212Ssam printf("(local-file) "); 115726497Sminshall (void) gets(&line[strlen(line)]); 115813212Ssam makeargv(); 115913212Ssam argc = margc; 116013212Ssam argv = margv; 116113212Ssam } 116213212Ssam if (argc < 3) { 116326049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 116426049Sminshall code = -1; 116513212Ssam return; 116613212Ssam } 116713212Ssam dest = argv[argc - 1]; 116813212Ssam argv[argc - 1] = NULL; 116926049Sminshall if (strcmp(dest, "-") && *dest != '|') 117026049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 117126049Sminshall code = -1; 117213212Ssam return; 117326049Sminshall } 117436940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 117526049Sminshall mname = argv[0]; 117626049Sminshall mflag = 1; 117726049Sminshall oldintr = signal(SIGINT, mabort); 117826049Sminshall (void) setjmp(jabort); 117926049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 118026049Sminshall *mode = (i == 1) ? 'w' : 'a'; 118126049Sminshall recvrequest(cmd, dest, argv[i], mode); 118226049Sminshall if (!mflag && fromatty) { 118326049Sminshall ointer = interactive; 118426049Sminshall interactive = 1; 118526049Sminshall if (confirm("Continue with", argv[0])) { 118626049Sminshall mflag ++; 118726049Sminshall } 118826049Sminshall interactive = ointer; 118926049Sminshall } 119026049Sminshall } 119126049Sminshall (void) signal(SIGINT, oldintr); 119226049Sminshall mflag = 0; 119311756Ssam } 119411756Ssam 119511756Ssam /* 119610294Ssam * Do a shell escape 119710294Ssam */ 119826497Sminshall /*ARGSUSED*/ 119910294Ssam shell(argc, argv) 120010294Ssam char *argv[]; 120110294Ssam { 120226497Sminshall int pid, (*old1)(), (*old2)(); 120326049Sminshall char shellnam[40], *shell, *namep; 120426497Sminshall union wait status; 120510294Ssam 120611756Ssam old1 = signal (SIGINT, SIG_IGN); 120711756Ssam old2 = signal (SIGQUIT, SIG_IGN); 120811756Ssam if ((pid = fork()) == 0) { 120911756Ssam for (pid = 3; pid < 20; pid++) 121026497Sminshall (void) close(pid); 121126497Sminshall (void) signal(SIGINT, SIG_DFL); 121226497Sminshall (void) signal(SIGQUIT, SIG_DFL); 121325908Smckusick shell = getenv("SHELL"); 121425908Smckusick if (shell == NULL) 121525908Smckusick shell = "/bin/sh"; 121625908Smckusick namep = rindex(shell,'/'); 121725908Smckusick if (namep == NULL) 121825908Smckusick namep = shell; 121926497Sminshall (void) strcpy(shellnam,"-"); 122026497Sminshall (void) strcat(shellnam, ++namep); 122126049Sminshall if (strcmp(namep, "sh") != 0) 122226049Sminshall shellnam[0] = '+'; 122326049Sminshall if (debug) { 122426049Sminshall printf ("%s\n", shell); 122526497Sminshall (void) fflush (stdout); 122611756Ssam } 122726049Sminshall if (argc > 1) { 122826049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 122926049Sminshall } 123026049Sminshall else { 123126049Sminshall execl(shell,shellnam,(char *)0); 123226049Sminshall } 123325908Smckusick perror(shell); 123426049Sminshall code = -1; 123511756Ssam exit(1); 123626049Sminshall } 123711756Ssam if (pid > 0) 123811756Ssam while (wait(&status) != pid) 123911756Ssam ; 124026497Sminshall (void) signal(SIGINT, old1); 124126497Sminshall (void) signal(SIGQUIT, old2); 124226049Sminshall if (pid == -1) { 124311756Ssam perror("Try again later"); 124426049Sminshall code = -1; 124526049Sminshall } 124626049Sminshall else { 124726049Sminshall code = 0; 124826049Sminshall } 124911756Ssam return (0); 125010294Ssam } 125110294Ssam 125210294Ssam /* 125310294Ssam * Send new user information (re-login) 125410294Ssam */ 125510294Ssam user(argc, argv) 125610294Ssam int argc; 125710294Ssam char **argv; 125810294Ssam { 125935658Sbostic char acct[80], *getpass(); 126026049Sminshall int n, aflag = 0; 126110294Ssam 126210294Ssam if (argc < 2) { 126326497Sminshall (void) strcat(line, " "); 126410294Ssam printf("(username) "); 126526497Sminshall (void) gets(&line[strlen(line)]); 126610294Ssam makeargv(); 126710294Ssam argc = margc; 126810294Ssam argv = margv; 126910294Ssam } 127010294Ssam if (argc > 4) { 127110294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 127226049Sminshall code = -1; 127311756Ssam return (0); 127410294Ssam } 127510294Ssam n = command("USER %s", argv[1]); 127610294Ssam if (n == CONTINUE) { 127710294Ssam if (argc < 3 ) 127835658Sbostic argv[2] = getpass("Password: "), argc++; 127910294Ssam n = command("PASS %s", argv[2]); 128010294Ssam } 128110294Ssam if (n == CONTINUE) { 128210294Ssam if (argc < 4) { 128310294Ssam printf("Account: "); (void) fflush(stdout); 128410294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 128510294Ssam acct[strlen(acct) - 1] = '\0'; 128610294Ssam argv[3] = acct; argc++; 128710294Ssam } 128826049Sminshall n = command("ACCT %s", argv[3]); 128926049Sminshall aflag++; 129010294Ssam } 129110294Ssam if (n != COMPLETE) { 129226497Sminshall fprintf(stdout, "Login failed.\n"); 129310294Ssam return (0); 129410294Ssam } 129526049Sminshall if (!aflag && argc == 4) { 129626049Sminshall (void) command("ACCT %s", argv[3]); 129726049Sminshall } 129810294Ssam return (1); 129910294Ssam } 130010294Ssam 130110294Ssam /* 130210294Ssam * Print working directory. 130310294Ssam */ 130410294Ssam /*VARARGS*/ 130510294Ssam pwd() 130610294Ssam { 1307*37224Skarels int oldverbose = verbose; 130811756Ssam 1309*37224Skarels /* 1310*37224Skarels * If we aren't verbose, this doesn't do anything! 1311*37224Skarels */ 1312*37224Skarels verbose = 1; 1313*37224Skarels if (command("PWD") == ERROR && code == 500) { 1314*37224Skarels printf("PWD command not recognized, trying XPWD\n"); 1315*37224Skarels (void) command("XPWD"); 1316*37224Skarels } 1317*37224Skarels verbose = oldverbose; 131810294Ssam } 131910294Ssam 132010294Ssam /* 132110294Ssam * Make a directory. 132210294Ssam */ 132310294Ssam makedir(argc, argv) 132410294Ssam char *argv[]; 132510294Ssam { 132610294Ssam 132710294Ssam if (argc < 2) { 132826497Sminshall (void) strcat(line, " "); 132910294Ssam printf("(directory-name) "); 133026497Sminshall (void) gets(&line[strlen(line)]); 133110294Ssam makeargv(); 133210294Ssam argc = margc; 133310294Ssam argv = margv; 133410294Ssam } 133510294Ssam if (argc < 2) { 133626049Sminshall printf("usage: %s directory-name\n", argv[0]); 133726049Sminshall code = -1; 133810294Ssam return; 133910294Ssam } 1340*37224Skarels if (command("MKD %s", argv[1]) == ERROR && code == 500) { 1341*37224Skarels if (verbose) 1342*37224Skarels printf("MKD command not recognized, trying XMKD\n"); 1343*37224Skarels (void) command("XMKD %s", argv[1]); 1344*37224Skarels } 134510294Ssam } 134610294Ssam 134710294Ssam /* 134810294Ssam * Remove a directory. 134910294Ssam */ 135010294Ssam removedir(argc, argv) 135110294Ssam char *argv[]; 135210294Ssam { 135310294Ssam 135410294Ssam if (argc < 2) { 135526497Sminshall (void) strcat(line, " "); 135610294Ssam printf("(directory-name) "); 135726497Sminshall (void) gets(&line[strlen(line)]); 135810294Ssam makeargv(); 135910294Ssam argc = margc; 136010294Ssam argv = margv; 136110294Ssam } 136210294Ssam if (argc < 2) { 136326049Sminshall printf("usage: %s directory-name\n", argv[0]); 136426049Sminshall code = -1; 136510294Ssam return; 136610294Ssam } 1367*37224Skarels if (command("RMD %s", argv[1]) == ERROR && code == 500) { 1368*37224Skarels if (verbose) 1369*37224Skarels printf("RMD command not recognized, trying XRMD\n"); 1370*37224Skarels (void) command("XRMD %s", argv[1]); 1371*37224Skarels } 137210294Ssam } 137310294Ssam 137410294Ssam /* 137510294Ssam * Send a line, verbatim, to the remote machine. 137610294Ssam */ 137710294Ssam quote(argc, argv) 137810294Ssam char *argv[]; 137910294Ssam { 138010294Ssam int i; 138110294Ssam char buf[BUFSIZ]; 138210294Ssam 138310294Ssam if (argc < 2) { 138426497Sminshall (void) strcat(line, " "); 138510294Ssam printf("(command line to send) "); 138626497Sminshall (void) gets(&line[strlen(line)]); 138710294Ssam makeargv(); 138810294Ssam argc = margc; 138910294Ssam argv = margv; 139010294Ssam } 139110294Ssam if (argc < 2) { 139210294Ssam printf("usage: %s line-to-send\n", argv[0]); 139326049Sminshall code = -1; 139410294Ssam return; 139510294Ssam } 139626497Sminshall (void) strcpy(buf, argv[1]); 139710294Ssam for (i = 2; i < argc; i++) { 139826497Sminshall (void) strcat(buf, " "); 139926497Sminshall (void) strcat(buf, argv[i]); 140010294Ssam } 140126049Sminshall if (command(buf) == PRELIM) { 140226049Sminshall while (getreply(0) == PRELIM); 140326049Sminshall } 140410294Ssam } 140510294Ssam 140610294Ssam /* 1407*37224Skarels * Send a SITE command to the remote machine. The line 1408*37224Skarels * is sent almost verbatim to the remote machine, the 1409*37224Skarels * first argument is changed to SITE. 1410*37224Skarels */ 1411*37224Skarels 1412*37224Skarels site(argc, argv) 1413*37224Skarels char *argv[]; 1414*37224Skarels { 1415*37224Skarels int i; 1416*37224Skarels char buf[BUFSIZ]; 1417*37224Skarels 1418*37224Skarels if (argc < 2) { 1419*37224Skarels (void) strcat(line, " "); 1420*37224Skarels printf("(arguments to SITE command) "); 1421*37224Skarels (void) gets(&line[strlen(line)]); 1422*37224Skarels makeargv(); 1423*37224Skarels argc = margc; 1424*37224Skarels argv = margv; 1425*37224Skarels } 1426*37224Skarels if (argc < 2) { 1427*37224Skarels printf("usage: %s line-to-send\n", argv[0]); 1428*37224Skarels code = -1; 1429*37224Skarels return; 1430*37224Skarels } 1431*37224Skarels (void) strcpy(buf, "SITE "); 1432*37224Skarels (void) strcat(buf, argv[1]); 1433*37224Skarels for (i = 2; i < argc; i++) { 1434*37224Skarels (void) strcat(buf, " "); 1435*37224Skarels (void) strcat(buf, argv[i]); 1436*37224Skarels } 1437*37224Skarels if (command(buf) == PRELIM) { 1438*37224Skarels while (getreply(0) == PRELIM); 1439*37224Skarels } 1440*37224Skarels } 1441*37224Skarels 1442*37224Skarels do_chmod(argc, argv) 1443*37224Skarels char *argv[]; 1444*37224Skarels { 1445*37224Skarels if (argc == 2) { 1446*37224Skarels printf("usage: %s mode file-name\n", argv[0]); 1447*37224Skarels code = -1; 1448*37224Skarels return; 1449*37224Skarels } 1450*37224Skarels if (argc < 3) { 1451*37224Skarels (void) strcat(line, " "); 1452*37224Skarels printf("(mode and file-name) "); 1453*37224Skarels (void) gets(&line[strlen(line)]); 1454*37224Skarels makeargv(); 1455*37224Skarels argc = margc; 1456*37224Skarels argv = margv; 1457*37224Skarels } 1458*37224Skarels if (argc != 3) { 1459*37224Skarels printf("usage: %s mode file-name\n", argv[0]); 1460*37224Skarels code = -1; 1461*37224Skarels return; 1462*37224Skarels } 1463*37224Skarels (void)command("SITE CHMOD %s %s", argv[1], argv[2]); 1464*37224Skarels } 1465*37224Skarels 1466*37224Skarels do_umask(argc, argv) 1467*37224Skarels char *argv[]; 1468*37224Skarels { 1469*37224Skarels int oldverbose = verbose; 1470*37224Skarels 1471*37224Skarels verbose = 1; 1472*37224Skarels (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); 1473*37224Skarels verbose = oldverbose; 1474*37224Skarels } 1475*37224Skarels 1476*37224Skarels idle(argc, argv) 1477*37224Skarels char *argv[]; 1478*37224Skarels { 1479*37224Skarels int oldverbose = verbose; 1480*37224Skarels 1481*37224Skarels verbose = 1; 1482*37224Skarels (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); 1483*37224Skarels verbose = oldverbose; 1484*37224Skarels } 1485*37224Skarels 1486*37224Skarels /* 148710294Ssam * Ask the other side for help. 148810294Ssam */ 148910294Ssam rmthelp(argc, argv) 149010294Ssam char *argv[]; 149110294Ssam { 149210294Ssam int oldverbose = verbose; 149310294Ssam 149410294Ssam verbose = 1; 149510294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 149610294Ssam verbose = oldverbose; 149710294Ssam } 149810294Ssam 149910294Ssam /* 150010294Ssam * Terminate session and exit. 150110294Ssam */ 150210294Ssam /*VARARGS*/ 150310294Ssam quit() 150410294Ssam { 150510294Ssam 150618286Sralph if (connected) 150718286Sralph disconnect(); 150826049Sminshall pswitch(1); 150926049Sminshall if (connected) { 151026049Sminshall disconnect(); 151126049Sminshall } 151210294Ssam exit(0); 151310294Ssam } 151410294Ssam 151510294Ssam /* 151610294Ssam * Terminate session, but don't exit. 151710294Ssam */ 151810294Ssam disconnect() 151910294Ssam { 152010294Ssam extern FILE *cout; 152110294Ssam extern int data; 152210294Ssam 152310294Ssam if (!connected) 152410294Ssam return; 152510294Ssam (void) command("QUIT"); 152626049Sminshall if (cout) { 152726049Sminshall (void) fclose(cout); 152826049Sminshall } 152910294Ssam cout = NULL; 153010294Ssam connected = 0; 153110294Ssam data = -1; 153226049Sminshall if (!proxy) { 153326049Sminshall macnum = 0; 153426049Sminshall } 153510294Ssam } 153611353Ssam 153711650Ssam confirm(cmd, file) 153811353Ssam char *cmd, *file; 153911353Ssam { 154011353Ssam char line[BUFSIZ]; 154111353Ssam 154211353Ssam if (!interactive) 154311650Ssam return (1); 154411353Ssam printf("%s %s? ", cmd, file); 154526497Sminshall (void) fflush(stdout); 154626497Sminshall (void) gets(line); 154711650Ssam return (*line != 'n' && *line != 'N'); 154811353Ssam } 154911353Ssam 155011353Ssam fatal(msg) 155111353Ssam char *msg; 155211353Ssam { 155311353Ssam 155426497Sminshall fprintf(stderr, "ftp: %s\n", msg); 155511353Ssam exit(1); 155611353Ssam } 155711353Ssam 155811353Ssam /* 155911353Ssam * Glob a local file name specification with 156011353Ssam * the expectation of a single return value. 156111353Ssam * Can't control multiple values being expanded 156211353Ssam * from the expression, we return only the first. 156311353Ssam */ 156411353Ssam globulize(cpp) 156511353Ssam char **cpp; 156611353Ssam { 156711353Ssam char **globbed; 156811353Ssam 156911353Ssam if (!doglob) 157011353Ssam return (1); 157111353Ssam globbed = glob(*cpp); 157211353Ssam if (globerr != NULL) { 157311353Ssam printf("%s: %s\n", *cpp, globerr); 157436421Sbostic if (globbed) { 157511353Ssam blkfree(globbed); 157636421Sbostic free(globbed); 157736421Sbostic } 157811353Ssam return (0); 157911353Ssam } 158011353Ssam if (globbed) { 158111353Ssam *cpp = *globbed++; 158211353Ssam /* don't waste too much memory */ 158336421Sbostic if (*globbed) { 158411353Ssam blkfree(globbed); 158536421Sbostic free(globbed); 158636421Sbostic } 158711353Ssam } 158811353Ssam return (1); 158911353Ssam } 159026049Sminshall 159126049Sminshall account(argc,argv) 159226049Sminshall int argc; 159326049Sminshall char **argv; 159426049Sminshall { 159535658Sbostic char acct[50], *getpass(), *ap; 159626049Sminshall 159726049Sminshall if (argc > 1) { 159826049Sminshall ++argv; 159926049Sminshall --argc; 160026049Sminshall (void) strncpy(acct,*argv,49); 160136268Sbostic acct[49] = '\0'; 160226049Sminshall while (argc > 1) { 160326049Sminshall --argc; 160426049Sminshall ++argv; 160526049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 160626049Sminshall } 160726049Sminshall ap = acct; 160826049Sminshall } 160926049Sminshall else { 161035658Sbostic ap = getpass("Account:"); 161126049Sminshall } 161226049Sminshall (void) command("ACCT %s", ap); 161326049Sminshall } 161426049Sminshall 161526049Sminshall jmp_buf abortprox; 161626049Sminshall 161726049Sminshall proxabort() 161826049Sminshall { 161926049Sminshall extern int proxy; 162026049Sminshall 162126049Sminshall if (!proxy) { 162226049Sminshall pswitch(1); 162326049Sminshall } 162426049Sminshall if (connected) { 162526049Sminshall proxflag = 1; 162626049Sminshall } 162726049Sminshall else { 162826049Sminshall proxflag = 0; 162926049Sminshall } 163026049Sminshall pswitch(0); 163126049Sminshall longjmp(abortprox,1); 163226049Sminshall } 163326049Sminshall 163426049Sminshall doproxy(argc,argv) 163526049Sminshall int argc; 163626049Sminshall char *argv[]; 163726049Sminshall { 163826049Sminshall int (*oldintr)(), proxabort(); 163926049Sminshall register struct cmd *c; 164026049Sminshall struct cmd *getcmd(); 164126049Sminshall extern struct cmd cmdtab[]; 164226049Sminshall extern jmp_buf abortprox; 164326049Sminshall 164426049Sminshall if (argc < 2) { 164526497Sminshall (void) strcat(line, " "); 164626049Sminshall printf("(command) "); 164726497Sminshall (void) gets(&line[strlen(line)]); 164826049Sminshall makeargv(); 164926049Sminshall argc = margc; 165026049Sminshall argv = margv; 165126049Sminshall } 165226049Sminshall if (argc < 2) { 165326049Sminshall printf("usage:%s command\n", argv[0]); 165426049Sminshall code = -1; 165526049Sminshall return; 165626049Sminshall } 165726049Sminshall c = getcmd(argv[1]); 165826049Sminshall if (c == (struct cmd *) -1) { 165926049Sminshall printf("?Ambiguous command\n"); 166026497Sminshall (void) fflush(stdout); 166126049Sminshall code = -1; 166226049Sminshall return; 166326049Sminshall } 166426049Sminshall if (c == 0) { 166526049Sminshall printf("?Invalid command\n"); 166626497Sminshall (void) fflush(stdout); 166726049Sminshall code = -1; 166826049Sminshall return; 166926049Sminshall } 167026049Sminshall if (!c->c_proxy) { 167126049Sminshall printf("?Invalid proxy command\n"); 167226497Sminshall (void) fflush(stdout); 167326049Sminshall code = -1; 167426049Sminshall return; 167526049Sminshall } 167626049Sminshall if (setjmp(abortprox)) { 167726049Sminshall code = -1; 167826049Sminshall return; 167926049Sminshall } 168026049Sminshall oldintr = signal(SIGINT, proxabort); 168126049Sminshall pswitch(1); 168226049Sminshall if (c->c_conn && !connected) { 168326049Sminshall printf("Not connected\n"); 168426497Sminshall (void) fflush(stdout); 168526049Sminshall pswitch(0); 168626049Sminshall (void) signal(SIGINT, oldintr); 168726049Sminshall code = -1; 168826049Sminshall return; 168926049Sminshall } 169026049Sminshall (*c->c_handler)(argc-1, argv+1); 169126049Sminshall if (connected) { 169226049Sminshall proxflag = 1; 169326049Sminshall } 169426049Sminshall else { 169526049Sminshall proxflag = 0; 169626049Sminshall } 169726049Sminshall pswitch(0); 169826049Sminshall (void) signal(SIGINT, oldintr); 169926049Sminshall } 170026049Sminshall 170126049Sminshall setcase() 170226049Sminshall { 170326049Sminshall mcase = !mcase; 170426049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 170526049Sminshall code = mcase; 170626049Sminshall } 170726049Sminshall 170826049Sminshall setcr() 170926049Sminshall { 171026049Sminshall crflag = !crflag; 171126049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 171226049Sminshall code = crflag; 171326049Sminshall } 171426049Sminshall 171526049Sminshall setntrans(argc,argv) 171626049Sminshall int argc; 171726049Sminshall char *argv[]; 171826049Sminshall { 171926049Sminshall if (argc == 1) { 172026049Sminshall ntflag = 0; 172126049Sminshall printf("Ntrans off.\n"); 172226049Sminshall code = ntflag; 172326049Sminshall return; 172426049Sminshall } 172526049Sminshall ntflag++; 172626049Sminshall code = ntflag; 172726049Sminshall (void) strncpy(ntin, argv[1], 16); 172826049Sminshall ntin[16] = '\0'; 172926049Sminshall if (argc == 2) { 173026049Sminshall ntout[0] = '\0'; 173126049Sminshall return; 173226049Sminshall } 173326049Sminshall (void) strncpy(ntout, argv[2], 16); 173426049Sminshall ntout[16] = '\0'; 173526049Sminshall } 173626049Sminshall 173726049Sminshall char * 173826049Sminshall dotrans(name) 173926049Sminshall char *name; 174026049Sminshall { 174126049Sminshall static char new[MAXPATHLEN]; 174226049Sminshall char *cp1, *cp2 = new; 174326049Sminshall register int i, ostop, found; 174426049Sminshall 174526049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 174626049Sminshall for (cp1 = name; *cp1; cp1++) { 174726049Sminshall found = 0; 174826049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 174926049Sminshall if (*cp1 == *(ntin + i)) { 175026049Sminshall found++; 175126049Sminshall if (i < ostop) { 175226049Sminshall *cp2++ = *(ntout + i); 175326049Sminshall } 175426049Sminshall break; 175526049Sminshall } 175626049Sminshall } 175726049Sminshall if (!found) { 175826049Sminshall *cp2++ = *cp1; 175926049Sminshall } 176026049Sminshall } 176126049Sminshall *cp2 = '\0'; 176226049Sminshall return(new); 176326049Sminshall } 176426049Sminshall 176526049Sminshall setnmap(argc, argv) 176626049Sminshall int argc; 176726049Sminshall char *argv[]; 176826049Sminshall { 176926049Sminshall char *cp; 177026049Sminshall 177126049Sminshall if (argc == 1) { 177226049Sminshall mapflag = 0; 177326049Sminshall printf("Nmap off.\n"); 177426049Sminshall code = mapflag; 177526049Sminshall return; 177626049Sminshall } 177726049Sminshall if (argc < 3) { 177826497Sminshall (void) strcat(line, " "); 177926049Sminshall printf("(mapout) "); 178026497Sminshall (void) gets(&line[strlen(line)]); 178126049Sminshall makeargv(); 178226049Sminshall argc = margc; 178326049Sminshall argv = margv; 178426049Sminshall } 178526049Sminshall if (argc < 3) { 178626049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 178726049Sminshall code = -1; 178826049Sminshall return; 178926049Sminshall } 179026049Sminshall mapflag = 1; 179126049Sminshall code = 1; 179226049Sminshall cp = index(altarg, ' '); 179326049Sminshall if (proxy) { 179426049Sminshall while(*++cp == ' '); 179526049Sminshall altarg = cp; 179626049Sminshall cp = index(altarg, ' '); 179726049Sminshall } 179826049Sminshall *cp = '\0'; 179926049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 180026049Sminshall while (*++cp == ' '); 180126049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 180226049Sminshall } 180326049Sminshall 180426049Sminshall char * 180526049Sminshall domap(name) 180626049Sminshall char *name; 180726049Sminshall { 180826049Sminshall static char new[MAXPATHLEN]; 180926049Sminshall register char *cp1 = name, *cp2 = mapin; 181026049Sminshall char *tp[9], *te[9]; 181136689Scsvsj int i, toks[9], toknum = 0, match = 1; 181226049Sminshall 181326049Sminshall for (i=0; i < 9; ++i) { 181426049Sminshall toks[i] = 0; 181526049Sminshall } 181626049Sminshall while (match && *cp1 && *cp2) { 181726049Sminshall switch (*cp2) { 181826049Sminshall case '\\': 181926049Sminshall if (*++cp2 != *cp1) { 182026049Sminshall match = 0; 182126049Sminshall } 182226049Sminshall break; 182326049Sminshall case '$': 182426049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 182526049Sminshall if (*cp1 != *(++cp2+1)) { 182626049Sminshall toks[toknum = *cp2 - '1']++; 182726049Sminshall tp[toknum] = cp1; 182826049Sminshall while (*++cp1 && *(cp2+1) 182926049Sminshall != *cp1); 183026049Sminshall te[toknum] = cp1; 183126049Sminshall } 183226049Sminshall cp2++; 183326049Sminshall break; 183426049Sminshall } 183536935Skarels /* FALLTHROUGH */ 183626049Sminshall default: 183726049Sminshall if (*cp2 != *cp1) { 183826049Sminshall match = 0; 183926049Sminshall } 184026049Sminshall break; 184126049Sminshall } 184236689Scsvsj if (match && *cp1) { 184326049Sminshall cp1++; 184426049Sminshall } 184536689Scsvsj if (match && *cp2) { 184626049Sminshall cp2++; 184726049Sminshall } 184826049Sminshall } 184936689Scsvsj if (!match && *cp1) /* last token mismatch */ 185036689Scsvsj { 185136689Scsvsj toks[toknum] = 0; 185236689Scsvsj } 185326049Sminshall cp1 = new; 185426049Sminshall *cp1 = '\0'; 185526049Sminshall cp2 = mapout; 185626049Sminshall while (*cp2) { 185726049Sminshall match = 0; 185826049Sminshall switch (*cp2) { 185926049Sminshall case '\\': 186026049Sminshall if (*(cp2 + 1)) { 186126049Sminshall *cp1++ = *++cp2; 186226049Sminshall } 186326049Sminshall break; 186426049Sminshall case '[': 186526049Sminshall LOOP: 186626049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 186726049Sminshall if (*++cp2 == '0') { 186826049Sminshall char *cp3 = name; 186926049Sminshall 187026049Sminshall while (*cp3) { 187126049Sminshall *cp1++ = *cp3++; 187226049Sminshall } 187326049Sminshall match = 1; 187426049Sminshall } 187526049Sminshall else if (toks[toknum = *cp2 - '1']) { 187626049Sminshall char *cp3 = tp[toknum]; 187726049Sminshall 187826049Sminshall while (cp3 != te[toknum]) { 187926049Sminshall *cp1++ = *cp3++; 188026049Sminshall } 188126049Sminshall match = 1; 188226049Sminshall } 188326049Sminshall } 188426049Sminshall else { 188526049Sminshall while (*cp2 && *cp2 != ',' && 188626049Sminshall *cp2 != ']') { 188726049Sminshall if (*cp2 == '\\') { 188826049Sminshall cp2++; 188926049Sminshall } 189026049Sminshall else if (*cp2 == '$' && 189126049Sminshall isdigit(*(cp2+1))) { 189226049Sminshall if (*++cp2 == '0') { 189326049Sminshall char *cp3 = name; 189426049Sminshall 189526049Sminshall while (*cp3) { 189626049Sminshall *cp1++ = *cp3++; 189726049Sminshall } 189826049Sminshall } 189926049Sminshall else if (toks[toknum = 190026049Sminshall *cp2 - '1']) { 190126049Sminshall char *cp3=tp[toknum]; 190226049Sminshall 190326049Sminshall while (cp3 != 190426049Sminshall te[toknum]) { 190526049Sminshall *cp1++ = *cp3++; 190626049Sminshall } 190726049Sminshall } 190826049Sminshall } 190926049Sminshall else if (*cp2) { 191026049Sminshall *cp1++ = *cp2++; 191126049Sminshall } 191226049Sminshall } 191326049Sminshall if (!*cp2) { 191426049Sminshall printf("nmap: unbalanced brackets\n"); 191526049Sminshall return(name); 191626049Sminshall } 191726049Sminshall match = 1; 191826049Sminshall cp2--; 191926049Sminshall } 192026049Sminshall if (match) { 192126049Sminshall while (*++cp2 && *cp2 != ']') { 192226049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 192326049Sminshall cp2++; 192426049Sminshall } 192526049Sminshall } 192626049Sminshall if (!*cp2) { 192726049Sminshall printf("nmap: unbalanced brackets\n"); 192826049Sminshall return(name); 192926049Sminshall } 193026049Sminshall break; 193126049Sminshall } 193226049Sminshall switch (*++cp2) { 193326049Sminshall case ',': 193426049Sminshall goto LOOP; 193526049Sminshall case ']': 193626049Sminshall break; 193726049Sminshall default: 193826049Sminshall cp2--; 193926049Sminshall goto LOOP; 194026049Sminshall } 194126049Sminshall break; 194226049Sminshall case '$': 194326049Sminshall if (isdigit(*(cp2 + 1))) { 194426049Sminshall if (*++cp2 == '0') { 194526049Sminshall char *cp3 = name; 194626049Sminshall 194726049Sminshall while (*cp3) { 194826049Sminshall *cp1++ = *cp3++; 194926049Sminshall } 195026049Sminshall } 195126049Sminshall else if (toks[toknum = *cp2 - '1']) { 195226049Sminshall char *cp3 = tp[toknum]; 195326049Sminshall 195426049Sminshall while (cp3 != te[toknum]) { 195526049Sminshall *cp1++ = *cp3++; 195626049Sminshall } 195726049Sminshall } 195826049Sminshall break; 195926049Sminshall } 196026049Sminshall /* intentional drop through */ 196126049Sminshall default: 196226049Sminshall *cp1++ = *cp2; 196326049Sminshall break; 196426049Sminshall } 196526049Sminshall cp2++; 196626049Sminshall } 196726049Sminshall *cp1 = '\0'; 196826049Sminshall if (!*new) { 196926049Sminshall return(name); 197026049Sminshall } 197126049Sminshall return(new); 197226049Sminshall } 197326049Sminshall 197426049Sminshall setsunique() 197526049Sminshall { 197626049Sminshall sunique = !sunique; 197726049Sminshall printf("Store unique %s.\n", onoff(sunique)); 197826049Sminshall code = sunique; 197926049Sminshall } 198026049Sminshall 198126049Sminshall setrunique() 198226049Sminshall { 198326049Sminshall runique = !runique; 198426049Sminshall printf("Receive unique %s.\n", onoff(runique)); 198526049Sminshall code = runique; 198626049Sminshall } 198726049Sminshall 198826049Sminshall /* change directory to perent directory */ 198926049Sminshall cdup() 199026049Sminshall { 1991*37224Skarels if (command("CDUP") == ERROR && code == 500) { 1992*37224Skarels if (verbose) 1993*37224Skarels printf("CDUP command not recognized, trying XCUP\n"); 1994*37224Skarels (void) command("XCUP"); 1995*37224Skarels } 199626049Sminshall } 199726049Sminshall 1998*37224Skarels /* restart transfer at specific point */ 1999*37224Skarels restart(argc, argv) 2000*37224Skarels int argc; 2001*37224Skarels char *argv[]; 2002*37224Skarels { 2003*37224Skarels extern long atol(); 2004*37224Skarels if (argc != 2) 2005*37224Skarels printf("restart: offset not specified\n"); 2006*37224Skarels else { 2007*37224Skarels restart_point = atol(argv[1]); 2008*37224Skarels printf("restarting at %ld. %s\n", restart_point, 2009*37224Skarels "execute get, put or append to initiate transfer"); 2010*37224Skarels } 2011*37224Skarels } 201236935Skarels 201336935Skarels /* show remote system type */ 201436935Skarels syst() 201536935Skarels { 201636935Skarels (void) command("SYST"); 201736935Skarels } 201836935Skarels 201926049Sminshall macdef(argc, argv) 202026049Sminshall int argc; 202126049Sminshall char *argv[]; 202226049Sminshall { 202326049Sminshall char *tmp; 202426049Sminshall int c; 202526049Sminshall 202626049Sminshall if (macnum == 16) { 202726049Sminshall printf("Limit of 16 macros have already been defined\n"); 202826049Sminshall code = -1; 202926049Sminshall return; 203026049Sminshall } 203126049Sminshall if (argc < 2) { 203226497Sminshall (void) strcat(line, " "); 203326049Sminshall printf("(macro name) "); 203426497Sminshall (void) gets(&line[strlen(line)]); 203526049Sminshall makeargv(); 203626049Sminshall argc = margc; 203726049Sminshall argv = margv; 203826049Sminshall } 203926049Sminshall if (argc != 2) { 204026049Sminshall printf("Usage: %s macro_name\n",argv[0]); 204126049Sminshall code = -1; 204226049Sminshall return; 204326049Sminshall } 204426049Sminshall if (interactive) { 204526049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 204626049Sminshall } 204726497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 204826049Sminshall if (macnum == 0) { 204926049Sminshall macros[macnum].mac_start = macbuf; 205026049Sminshall } 205126049Sminshall else { 205226049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 205326049Sminshall } 205426049Sminshall tmp = macros[macnum].mac_start; 205526049Sminshall while (tmp != macbuf+4096) { 205626049Sminshall if ((c = getchar()) == EOF) { 205726049Sminshall printf("macdef:end of file encountered\n"); 205826049Sminshall code = -1; 205926049Sminshall return; 206026049Sminshall } 206126049Sminshall if ((*tmp = c) == '\n') { 206226049Sminshall if (tmp == macros[macnum].mac_start) { 206326049Sminshall macros[macnum++].mac_end = tmp; 206426049Sminshall code = 0; 206526049Sminshall return; 206626049Sminshall } 206726049Sminshall if (*(tmp-1) == '\0') { 206826049Sminshall macros[macnum++].mac_end = tmp - 1; 206926049Sminshall code = 0; 207026049Sminshall return; 207126049Sminshall } 207226049Sminshall *tmp = '\0'; 207326049Sminshall } 207426049Sminshall tmp++; 207526049Sminshall } 207626049Sminshall while (1) { 207736935Skarels while ((c = getchar()) != '\n' && c != EOF) 207836935Skarels /* LOOP */; 207926049Sminshall if (c == EOF || getchar() == '\n') { 208026049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 208126049Sminshall code = -1; 208226049Sminshall return; 208326049Sminshall } 208426049Sminshall } 208526049Sminshall } 208636935Skarels 208736935Skarels /* 208836935Skarels * get size of file on remote machine 208936935Skarels */ 209036935Skarels sizecmd(argc, argv) 209136935Skarels char *argv[]; 209236935Skarels { 209336935Skarels 209436935Skarels if (argc < 2) { 209536935Skarels (void) strcat(line, " "); 209636935Skarels printf("(filename) "); 209736935Skarels (void) gets(&line[strlen(line)]); 209836935Skarels makeargv(); 209936935Skarels argc = margc; 210036935Skarels argv = margv; 210136935Skarels } 210236935Skarels if (argc < 2) { 210336935Skarels printf("usage:%s filename\n", argv[0]); 210436935Skarels code = -1; 210536935Skarels return; 210636935Skarels } 210736935Skarels (void) command("SIZE %s", argv[1]); 210836935Skarels } 210936935Skarels 211036935Skarels /* 211136935Skarels * get last modification time of file on remote machine 211236935Skarels */ 211336935Skarels modtime(argc, argv) 211436935Skarels char *argv[]; 211536935Skarels { 211636935Skarels int overbose; 211736935Skarels 211836935Skarels if (argc < 2) { 211936935Skarels (void) strcat(line, " "); 212036935Skarels printf("(filename) "); 212136935Skarels (void) gets(&line[strlen(line)]); 212236935Skarels makeargv(); 212336935Skarels argc = margc; 212436935Skarels argv = margv; 212536935Skarels } 212636935Skarels if (argc < 2) { 212736935Skarels printf("usage:%s filename\n", argv[0]); 212836935Skarels code = -1; 212936935Skarels return; 213036935Skarels } 213136940Skarels overbose = verbose; 213236940Skarels if (debug == 0) 213336940Skarels verbose = -1; 213436935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 213536935Skarels int yy, mo, day, hour, min, sec; 213636935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 213736935Skarels &day, &hour, &min, &sec); 213836935Skarels /* might want to print this in local time */ 213936935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 214036935Skarels mo, day, yy, hour, min, sec); 214136935Skarels } else 214236935Skarels fputs(reply_string, stdout); 214336935Skarels verbose = overbose; 214436935Skarels } 214536935Skarels 214636935Skarels /* 2147*37224Skarels * show status on reomte machine 214836935Skarels */ 214936935Skarels rmtstatus(argc, argv) 215036935Skarels char *argv[]; 215136935Skarels { 215236935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 215336935Skarels } 2154*37224Skarels 2155*37224Skarels /* 2156*37224Skarels * get file if modtime is more recent than current file 2157*37224Skarels */ 2158*37224Skarels newer(argc, argv) 2159*37224Skarels char *argv[]; 2160*37224Skarels { 2161*37224Skarels if (getit(argc, argv, -1, "w")) 2162*37224Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 2163*37224Skarels argv[1], argv[2]); 2164*37224Skarels } 2165