121737Sdist /* 226049Sminshall * Copyright (c) 1985 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*36940Skarels static char sccsid[] = "@(#)cmds.c 5.14 (Berkeley) 03/01/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 25*36940Skarels #include <sys/param.h> 26*36940Skarels #include <sys/wait.h> 27*36940Skarels #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 39*36940Skarels #include "ftp_var.h" 4010294Ssam 41*36940Skarels 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(); 4936935Skarels 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; 102*36940Skarels 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 */ 109*36940Skarels overbose = verbose; 110*36940Skarels if (debug == 0) 111*36940Skarels 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) 132*36940Skarels printf("Using %s mode to transfer files.\n", 133*36940Skarels typename); 13436935Skarels } else if (overbose && 13536935Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 136*36940Skarels printf( 137*36940Skarels "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 47336935Skarels reget(argc, argv) 47436935Skarels char *argv[]; 47536935Skarels { 47636935Skarels (void) getit(argc, argv, 1, "r+w"); 47736935Skarels } 47836935Skarels 47936935Skarels get(argc, argv) 48036935Skarels char *argv[]; 48136935Skarels { 48236935Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 48336935Skarels } 48436935Skarels 48511353Ssam /* 48611353Ssam * Receive one file. 48711353Ssam */ 48836935Skarels getit(argc, argv, restartit, mode) 48910294Ssam char *argv[]; 49036935Skarels 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*36940Skarels 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*36940Skarels 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 } 546*36940Skarels if (loc && ntflag) 54726049Sminshall argv[2] = dotrans(argv[2]); 548*36940Skarels if (loc && mapflag) 54926049Sminshall argv[2] = domap(argv[2]); 55036935Skarels if (restartit) { 55136935Skarels struct stat stbuf; 55236935Skarels int ret; 553*36940Skarels 55436935Skarels ret = stat(argv[2], &stbuf); 55536935Skarels if (restartit == 1) { 55636935Skarels if (ret < 0) { 55736935Skarels perror(argv[2]); 558*36940Skarels return (0); 55936935Skarels } 56036935Skarels restart_point = stbuf.st_size; 56136935Skarels } else { 56236935Skarels if (ret == 0) { 56336935Skarels int overbose; 564*36940Skarels 565*36940Skarels overbose = verbose; 566*36940Skarels if (debug == 0) 567*36940Skarels verbose = -1; 56836935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 56936935Skarels int yy, mo, day, hour, min, sec; 57036935Skarels struct tm *tm; 57136935Skarels verbose = overbose; 57236935Skarels sscanf(reply_string, 57336935Skarels "%*s %04d%02d%02d%02d%02d%02d", 57436935Skarels &yy, &mo, &day, &hour, &min, &sec); 57536935Skarels tm = gmtime(&stbuf.st_mtime); 57636935Skarels tm->tm_mon++; 57736935Skarels if (tm->tm_year > yy%100) 578*36940Skarels return (1); 57936935Skarels else if (tm->tm_year == yy%100) { 58036935Skarels if (tm->tm_mon > mo) 581*36940Skarels return (1); 58236935Skarels } else if (tm->tm_mon == mo) { 58336935Skarels if (tm->tm_mday > day) 584*36940Skarels return (1); 58536935Skarels } else if (tm->tm_mday == day) { 58636935Skarels if (tm->tm_hour > hour) 587*36940Skarels return (1); 58836935Skarels } else if (tm->tm_hour == hour) { 58936935Skarels if (tm->tm_min > min) 590*36940Skarels return (1); 59136935Skarels } else if (tm->tm_min == min) { 59236935Skarels if (tm->tm_sec > sec) 593*36940Skarels return (1); 59436935Skarels } 59536935Skarels } else { 59636935Skarels fputs(reply_string, stdout); 59736935Skarels verbose = overbose; 598*36940Skarels return (0); 59936935Skarels } 60036935Skarels } 60136935Skarels } 60236935Skarels } 60336935Skarels 60436935Skarels recvrequest("RETR", argv[2], argv[1], mode); 60536935Skarels restart_point = 0; 606*36940Skarels 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) 85911650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 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 } 96210294Ssam (void) command("CWD %s", argv[1]); 96310294Ssam } 96410294Ssam 96510294Ssam /* 96610294Ssam * Set current working directory 96710294Ssam * on local machine. 96810294Ssam */ 96910294Ssam lcd(argc, argv) 97010294Ssam char *argv[]; 97110294Ssam { 97211353Ssam char buf[MAXPATHLEN]; 97310294Ssam 97411353Ssam if (argc < 2) 97511353Ssam argc++, argv[1] = home; 97610294Ssam if (argc != 2) { 97726049Sminshall printf("usage:%s local-directory\n", argv[0]); 97826049Sminshall code = -1; 97910294Ssam return; 98010294Ssam } 98126049Sminshall if (!globulize(&argv[1])) { 98226049Sminshall code = -1; 98311353Ssam return; 98426049Sminshall } 98511353Ssam if (chdir(argv[1]) < 0) { 98610294Ssam perror(argv[1]); 98726049Sminshall code = -1; 98811353Ssam return; 98911353Ssam } 99011353Ssam printf("Local directory now %s\n", getwd(buf)); 99126049Sminshall code = 0; 99210294Ssam } 99310294Ssam 99410294Ssam /* 99510294Ssam * Delete a single file. 99610294Ssam */ 99710294Ssam delete(argc, argv) 99810294Ssam char *argv[]; 99910294Ssam { 100010294Ssam 100110294Ssam if (argc < 2) { 100226497Sminshall (void) strcat(line, " "); 100310294Ssam printf("(remote-file) "); 100426497Sminshall (void) gets(&line[strlen(line)]); 100510294Ssam makeargv(); 100610294Ssam argc = margc; 100710294Ssam argv = margv; 100810294Ssam } 100910294Ssam if (argc < 2) { 101026049Sminshall printf("usage:%s remote-file\n", argv[0]); 101126049Sminshall code = -1; 101210294Ssam return; 101310294Ssam } 101410294Ssam (void) command("DELE %s", argv[1]); 101510294Ssam } 101610294Ssam 101710294Ssam /* 101811650Ssam * Delete multiple files. 101911650Ssam */ 102011650Ssam mdelete(argc, argv) 102111650Ssam char *argv[]; 102211650Ssam { 102311650Ssam char *cp; 102426049Sminshall int ointer, (*oldintr)(), mabort(); 102526049Sminshall extern jmp_buf jabort; 102611650Ssam 102711650Ssam if (argc < 2) { 102826497Sminshall (void) strcat(line, " "); 102911650Ssam printf("(remote-files) "); 103026497Sminshall (void) gets(&line[strlen(line)]); 103111650Ssam makeargv(); 103211650Ssam argc = margc; 103311650Ssam argv = margv; 103411650Ssam } 103511650Ssam if (argc < 2) { 103626049Sminshall printf("usage:%s remote-files\n", argv[0]); 103726049Sminshall code = -1; 103811650Ssam return; 103911650Ssam } 104026049Sminshall mname = argv[0]; 104126049Sminshall mflag = 1; 104226049Sminshall oldintr = signal(SIGINT, mabort); 104326049Sminshall (void) setjmp(jabort); 104426497Sminshall while ((cp = remglob(argv,0)) != NULL) { 104526049Sminshall if (*cp == '\0') { 104626049Sminshall mflag = 0; 104726049Sminshall continue; 104826049Sminshall } 104926049Sminshall if (mflag && confirm(argv[0], cp)) { 105011650Ssam (void) command("DELE %s", cp); 105126049Sminshall if (!mflag && fromatty) { 105226049Sminshall ointer = interactive; 105326049Sminshall interactive = 1; 105426049Sminshall if (confirm("Continue with", "mdelete")) { 105526049Sminshall mflag++; 105626049Sminshall } 105726049Sminshall interactive = ointer; 105826049Sminshall } 105926049Sminshall } 106026049Sminshall } 106126049Sminshall (void) signal(SIGINT, oldintr); 106226049Sminshall mflag = 0; 106311650Ssam } 106411756Ssam 106511650Ssam /* 106610294Ssam * Rename a remote file. 106710294Ssam */ 106810294Ssam renamefile(argc, argv) 106910294Ssam char *argv[]; 107010294Ssam { 107110294Ssam 107210294Ssam if (argc < 2) { 107326497Sminshall (void) strcat(line, " "); 107410294Ssam printf("(from-name) "); 107526497Sminshall (void) gets(&line[strlen(line)]); 107610294Ssam makeargv(); 107710294Ssam argc = margc; 107810294Ssam argv = margv; 107910294Ssam } 108010294Ssam if (argc < 2) { 108110294Ssam usage: 108210294Ssam printf("%s from-name to-name\n", argv[0]); 108326049Sminshall code = -1; 108410294Ssam return; 108510294Ssam } 108610294Ssam if (argc < 3) { 108726497Sminshall (void) strcat(line, " "); 108810294Ssam printf("(to-name) "); 108926497Sminshall (void) gets(&line[strlen(line)]); 109010294Ssam makeargv(); 109110294Ssam argc = margc; 109210294Ssam argv = margv; 109310294Ssam } 109410294Ssam if (argc < 3) 109510294Ssam goto usage; 109610294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 109710294Ssam (void) command("RNTO %s", argv[2]); 109810294Ssam } 109910294Ssam 110010294Ssam /* 110110294Ssam * Get a directory listing 110210294Ssam * of remote files. 110310294Ssam */ 110410294Ssam ls(argc, argv) 110510294Ssam char *argv[]; 110610294Ssam { 110711756Ssam char *cmd; 110810294Ssam 110910294Ssam if (argc < 2) 111010294Ssam argc++, argv[1] = NULL; 111110294Ssam if (argc < 3) 111210294Ssam argc++, argv[2] = "-"; 111311756Ssam if (argc > 3) { 111411756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 111526049Sminshall code = -1; 111611756Ssam return; 111711756Ssam } 111836935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 111926049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 112026049Sminshall code = -1; 112111353Ssam return; 112226049Sminshall } 112332344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 112432344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 112532344Scsvsj code = -1; 112632344Scsvsj return; 112732344Scsvsj } 112811756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 112910294Ssam } 113010294Ssam 113110294Ssam /* 113211756Ssam * Get a directory listing 113311756Ssam * of multiple remote files. 113411756Ssam */ 113511756Ssam mls(argc, argv) 113611756Ssam char *argv[]; 113711756Ssam { 113826049Sminshall char *cmd, mode[1], *dest; 113926049Sminshall int ointer, i, (*oldintr)(), mabort(); 114026049Sminshall extern jmp_buf jabort; 114111756Ssam 114213212Ssam if (argc < 2) { 114326497Sminshall (void) strcat(line, " "); 114413212Ssam printf("(remote-files) "); 114526497Sminshall (void) gets(&line[strlen(line)]); 114613212Ssam makeargv(); 114713212Ssam argc = margc; 114813212Ssam argv = margv; 114913212Ssam } 115013212Ssam if (argc < 3) { 115126497Sminshall (void) strcat(line, " "); 115213212Ssam printf("(local-file) "); 115326497Sminshall (void) gets(&line[strlen(line)]); 115413212Ssam makeargv(); 115513212Ssam argc = margc; 115613212Ssam argv = margv; 115713212Ssam } 115813212Ssam if (argc < 3) { 115926049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 116026049Sminshall code = -1; 116113212Ssam return; 116213212Ssam } 116313212Ssam dest = argv[argc - 1]; 116413212Ssam argv[argc - 1] = NULL; 116526049Sminshall if (strcmp(dest, "-") && *dest != '|') 116626049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 116726049Sminshall code = -1; 116813212Ssam return; 116926049Sminshall } 1170*36940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 117126049Sminshall mname = argv[0]; 117226049Sminshall mflag = 1; 117326049Sminshall oldintr = signal(SIGINT, mabort); 117426049Sminshall (void) setjmp(jabort); 117526049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 117626049Sminshall *mode = (i == 1) ? 'w' : 'a'; 117726049Sminshall recvrequest(cmd, dest, argv[i], mode); 117826049Sminshall if (!mflag && fromatty) { 117926049Sminshall ointer = interactive; 118026049Sminshall interactive = 1; 118126049Sminshall if (confirm("Continue with", argv[0])) { 118226049Sminshall mflag ++; 118326049Sminshall } 118426049Sminshall interactive = ointer; 118526049Sminshall } 118626049Sminshall } 118726049Sminshall (void) signal(SIGINT, oldintr); 118826049Sminshall mflag = 0; 118911756Ssam } 119011756Ssam 119111756Ssam /* 119210294Ssam * Do a shell escape 119310294Ssam */ 119426497Sminshall /*ARGSUSED*/ 119510294Ssam shell(argc, argv) 119610294Ssam char *argv[]; 119710294Ssam { 119826497Sminshall int pid, (*old1)(), (*old2)(); 119926049Sminshall char shellnam[40], *shell, *namep; 120026497Sminshall union wait status; 120110294Ssam 120211756Ssam old1 = signal (SIGINT, SIG_IGN); 120311756Ssam old2 = signal (SIGQUIT, SIG_IGN); 120411756Ssam if ((pid = fork()) == 0) { 120511756Ssam for (pid = 3; pid < 20; pid++) 120626497Sminshall (void) close(pid); 120726497Sminshall (void) signal(SIGINT, SIG_DFL); 120826497Sminshall (void) signal(SIGQUIT, SIG_DFL); 120925908Smckusick shell = getenv("SHELL"); 121025908Smckusick if (shell == NULL) 121125908Smckusick shell = "/bin/sh"; 121225908Smckusick namep = rindex(shell,'/'); 121325908Smckusick if (namep == NULL) 121425908Smckusick namep = shell; 121526497Sminshall (void) strcpy(shellnam,"-"); 121626497Sminshall (void) strcat(shellnam, ++namep); 121726049Sminshall if (strcmp(namep, "sh") != 0) 121826049Sminshall shellnam[0] = '+'; 121926049Sminshall if (debug) { 122026049Sminshall printf ("%s\n", shell); 122126497Sminshall (void) fflush (stdout); 122211756Ssam } 122326049Sminshall if (argc > 1) { 122426049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 122526049Sminshall } 122626049Sminshall else { 122726049Sminshall execl(shell,shellnam,(char *)0); 122826049Sminshall } 122925908Smckusick perror(shell); 123026049Sminshall code = -1; 123111756Ssam exit(1); 123226049Sminshall } 123311756Ssam if (pid > 0) 123411756Ssam while (wait(&status) != pid) 123511756Ssam ; 123626497Sminshall (void) signal(SIGINT, old1); 123726497Sminshall (void) signal(SIGQUIT, old2); 123826049Sminshall if (pid == -1) { 123911756Ssam perror("Try again later"); 124026049Sminshall code = -1; 124126049Sminshall } 124226049Sminshall else { 124326049Sminshall code = 0; 124426049Sminshall } 124511756Ssam return (0); 124610294Ssam } 124710294Ssam 124810294Ssam /* 124910294Ssam * Send new user information (re-login) 125010294Ssam */ 125110294Ssam user(argc, argv) 125210294Ssam int argc; 125310294Ssam char **argv; 125410294Ssam { 125535658Sbostic char acct[80], *getpass(); 125626049Sminshall int n, aflag = 0; 125710294Ssam 125810294Ssam if (argc < 2) { 125926497Sminshall (void) strcat(line, " "); 126010294Ssam printf("(username) "); 126126497Sminshall (void) gets(&line[strlen(line)]); 126210294Ssam makeargv(); 126310294Ssam argc = margc; 126410294Ssam argv = margv; 126510294Ssam } 126610294Ssam if (argc > 4) { 126710294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 126826049Sminshall code = -1; 126911756Ssam return (0); 127010294Ssam } 127110294Ssam n = command("USER %s", argv[1]); 127210294Ssam if (n == CONTINUE) { 127310294Ssam if (argc < 3 ) 127435658Sbostic argv[2] = getpass("Password: "), argc++; 127510294Ssam n = command("PASS %s", argv[2]); 127610294Ssam } 127710294Ssam if (n == CONTINUE) { 127810294Ssam if (argc < 4) { 127910294Ssam printf("Account: "); (void) fflush(stdout); 128010294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 128110294Ssam acct[strlen(acct) - 1] = '\0'; 128210294Ssam argv[3] = acct; argc++; 128310294Ssam } 128426049Sminshall n = command("ACCT %s", argv[3]); 128526049Sminshall aflag++; 128610294Ssam } 128710294Ssam if (n != COMPLETE) { 128826497Sminshall fprintf(stdout, "Login failed.\n"); 128910294Ssam return (0); 129010294Ssam } 129126049Sminshall if (!aflag && argc == 4) { 129226049Sminshall (void) command("ACCT %s", argv[3]); 129326049Sminshall } 129410294Ssam return (1); 129510294Ssam } 129610294Ssam 129710294Ssam /* 129810294Ssam * Print working directory. 129910294Ssam */ 130010294Ssam /*VARARGS*/ 130110294Ssam pwd() 130210294Ssam { 130311756Ssam 130426049Sminshall (void) command("PWD"); 130510294Ssam } 130610294Ssam 130710294Ssam /* 130810294Ssam * Make a directory. 130910294Ssam */ 131010294Ssam makedir(argc, argv) 131110294Ssam char *argv[]; 131210294Ssam { 131310294Ssam 131410294Ssam if (argc < 2) { 131526497Sminshall (void) strcat(line, " "); 131610294Ssam printf("(directory-name) "); 131726497Sminshall (void) gets(&line[strlen(line)]); 131810294Ssam makeargv(); 131910294Ssam argc = margc; 132010294Ssam argv = margv; 132110294Ssam } 132210294Ssam if (argc < 2) { 132326049Sminshall printf("usage: %s directory-name\n", argv[0]); 132426049Sminshall code = -1; 132510294Ssam return; 132610294Ssam } 132726049Sminshall (void) command("MKD %s", argv[1]); 132810294Ssam } 132910294Ssam 133010294Ssam /* 133110294Ssam * Remove a directory. 133210294Ssam */ 133310294Ssam removedir(argc, argv) 133410294Ssam char *argv[]; 133510294Ssam { 133610294Ssam 133710294Ssam if (argc < 2) { 133826497Sminshall (void) strcat(line, " "); 133910294Ssam printf("(directory-name) "); 134026497Sminshall (void) gets(&line[strlen(line)]); 134110294Ssam makeargv(); 134210294Ssam argc = margc; 134310294Ssam argv = margv; 134410294Ssam } 134510294Ssam if (argc < 2) { 134626049Sminshall printf("usage: %s directory-name\n", argv[0]); 134726049Sminshall code = -1; 134810294Ssam return; 134910294Ssam } 135026049Sminshall (void) command("RMD %s", argv[1]); 135110294Ssam } 135210294Ssam 135310294Ssam /* 135410294Ssam * Send a line, verbatim, to the remote machine. 135510294Ssam */ 135610294Ssam quote(argc, argv) 135710294Ssam char *argv[]; 135810294Ssam { 135910294Ssam int i; 136010294Ssam char buf[BUFSIZ]; 136110294Ssam 136210294Ssam if (argc < 2) { 136326497Sminshall (void) strcat(line, " "); 136410294Ssam printf("(command line to send) "); 136526497Sminshall (void) gets(&line[strlen(line)]); 136610294Ssam makeargv(); 136710294Ssam argc = margc; 136810294Ssam argv = margv; 136910294Ssam } 137010294Ssam if (argc < 2) { 137110294Ssam printf("usage: %s line-to-send\n", argv[0]); 137226049Sminshall code = -1; 137310294Ssam return; 137410294Ssam } 137526497Sminshall (void) strcpy(buf, argv[1]); 137610294Ssam for (i = 2; i < argc; i++) { 137726497Sminshall (void) strcat(buf, " "); 137826497Sminshall (void) strcat(buf, argv[i]); 137910294Ssam } 138026049Sminshall if (command(buf) == PRELIM) { 138126049Sminshall while (getreply(0) == PRELIM); 138226049Sminshall } 138310294Ssam } 138410294Ssam 138510294Ssam /* 138610294Ssam * Ask the other side for help. 138710294Ssam */ 138810294Ssam rmthelp(argc, argv) 138910294Ssam char *argv[]; 139010294Ssam { 139110294Ssam int oldverbose = verbose; 139210294Ssam 139310294Ssam verbose = 1; 139410294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 139510294Ssam verbose = oldverbose; 139610294Ssam } 139710294Ssam 139810294Ssam /* 139910294Ssam * Terminate session and exit. 140010294Ssam */ 140110294Ssam /*VARARGS*/ 140210294Ssam quit() 140310294Ssam { 140410294Ssam 140518286Sralph if (connected) 140618286Sralph disconnect(); 140726049Sminshall pswitch(1); 140826049Sminshall if (connected) { 140926049Sminshall disconnect(); 141026049Sminshall } 141110294Ssam exit(0); 141210294Ssam } 141310294Ssam 141410294Ssam /* 141510294Ssam * Terminate session, but don't exit. 141610294Ssam */ 141710294Ssam disconnect() 141810294Ssam { 141910294Ssam extern FILE *cout; 142010294Ssam extern int data; 142110294Ssam 142210294Ssam if (!connected) 142310294Ssam return; 142410294Ssam (void) command("QUIT"); 142526049Sminshall if (cout) { 142626049Sminshall (void) fclose(cout); 142726049Sminshall } 142810294Ssam cout = NULL; 142910294Ssam connected = 0; 143010294Ssam data = -1; 143126049Sminshall if (!proxy) { 143226049Sminshall macnum = 0; 143326049Sminshall } 143410294Ssam } 143511353Ssam 143611650Ssam confirm(cmd, file) 143711353Ssam char *cmd, *file; 143811353Ssam { 143911353Ssam char line[BUFSIZ]; 144011353Ssam 144111353Ssam if (!interactive) 144211650Ssam return (1); 144311353Ssam printf("%s %s? ", cmd, file); 144426497Sminshall (void) fflush(stdout); 144526497Sminshall (void) gets(line); 144611650Ssam return (*line != 'n' && *line != 'N'); 144711353Ssam } 144811353Ssam 144911353Ssam fatal(msg) 145011353Ssam char *msg; 145111353Ssam { 145211353Ssam 145326497Sminshall fprintf(stderr, "ftp: %s\n", msg); 145411353Ssam exit(1); 145511353Ssam } 145611353Ssam 145711353Ssam /* 145811353Ssam * Glob a local file name specification with 145911353Ssam * the expectation of a single return value. 146011353Ssam * Can't control multiple values being expanded 146111353Ssam * from the expression, we return only the first. 146211353Ssam */ 146311353Ssam globulize(cpp) 146411353Ssam char **cpp; 146511353Ssam { 146611353Ssam char **globbed; 146711353Ssam 146811353Ssam if (!doglob) 146911353Ssam return (1); 147011353Ssam globbed = glob(*cpp); 147111353Ssam if (globerr != NULL) { 147211353Ssam printf("%s: %s\n", *cpp, globerr); 147336421Sbostic if (globbed) { 147411353Ssam blkfree(globbed); 147536421Sbostic free(globbed); 147636421Sbostic } 147711353Ssam return (0); 147811353Ssam } 147911353Ssam if (globbed) { 148011353Ssam *cpp = *globbed++; 148111353Ssam /* don't waste too much memory */ 148236421Sbostic if (*globbed) { 148311353Ssam blkfree(globbed); 148436421Sbostic free(globbed); 148536421Sbostic } 148611353Ssam } 148711353Ssam return (1); 148811353Ssam } 148926049Sminshall 149026049Sminshall account(argc,argv) 149126049Sminshall int argc; 149226049Sminshall char **argv; 149326049Sminshall { 149435658Sbostic char acct[50], *getpass(), *ap; 149526049Sminshall 149626049Sminshall if (argc > 1) { 149726049Sminshall ++argv; 149826049Sminshall --argc; 149926049Sminshall (void) strncpy(acct,*argv,49); 150036268Sbostic acct[49] = '\0'; 150126049Sminshall while (argc > 1) { 150226049Sminshall --argc; 150326049Sminshall ++argv; 150426049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 150526049Sminshall } 150626049Sminshall ap = acct; 150726049Sminshall } 150826049Sminshall else { 150935658Sbostic ap = getpass("Account:"); 151026049Sminshall } 151126049Sminshall (void) command("ACCT %s", ap); 151226049Sminshall } 151326049Sminshall 151426049Sminshall jmp_buf abortprox; 151526049Sminshall 151626049Sminshall proxabort() 151726049Sminshall { 151826049Sminshall extern int proxy; 151926049Sminshall 152026049Sminshall if (!proxy) { 152126049Sminshall pswitch(1); 152226049Sminshall } 152326049Sminshall if (connected) { 152426049Sminshall proxflag = 1; 152526049Sminshall } 152626049Sminshall else { 152726049Sminshall proxflag = 0; 152826049Sminshall } 152926049Sminshall pswitch(0); 153026049Sminshall longjmp(abortprox,1); 153126049Sminshall } 153226049Sminshall 153326049Sminshall doproxy(argc,argv) 153426049Sminshall int argc; 153526049Sminshall char *argv[]; 153626049Sminshall { 153726049Sminshall int (*oldintr)(), proxabort(); 153826049Sminshall register struct cmd *c; 153926049Sminshall struct cmd *getcmd(); 154026049Sminshall extern struct cmd cmdtab[]; 154126049Sminshall extern jmp_buf abortprox; 154226049Sminshall 154326049Sminshall if (argc < 2) { 154426497Sminshall (void) strcat(line, " "); 154526049Sminshall printf("(command) "); 154626497Sminshall (void) gets(&line[strlen(line)]); 154726049Sminshall makeargv(); 154826049Sminshall argc = margc; 154926049Sminshall argv = margv; 155026049Sminshall } 155126049Sminshall if (argc < 2) { 155226049Sminshall printf("usage:%s command\n", argv[0]); 155326049Sminshall code = -1; 155426049Sminshall return; 155526049Sminshall } 155626049Sminshall c = getcmd(argv[1]); 155726049Sminshall if (c == (struct cmd *) -1) { 155826049Sminshall printf("?Ambiguous command\n"); 155926497Sminshall (void) fflush(stdout); 156026049Sminshall code = -1; 156126049Sminshall return; 156226049Sminshall } 156326049Sminshall if (c == 0) { 156426049Sminshall printf("?Invalid command\n"); 156526497Sminshall (void) fflush(stdout); 156626049Sminshall code = -1; 156726049Sminshall return; 156826049Sminshall } 156926049Sminshall if (!c->c_proxy) { 157026049Sminshall printf("?Invalid proxy command\n"); 157126497Sminshall (void) fflush(stdout); 157226049Sminshall code = -1; 157326049Sminshall return; 157426049Sminshall } 157526049Sminshall if (setjmp(abortprox)) { 157626049Sminshall code = -1; 157726049Sminshall return; 157826049Sminshall } 157926049Sminshall oldintr = signal(SIGINT, proxabort); 158026049Sminshall pswitch(1); 158126049Sminshall if (c->c_conn && !connected) { 158226049Sminshall printf("Not connected\n"); 158326497Sminshall (void) fflush(stdout); 158426049Sminshall pswitch(0); 158526049Sminshall (void) signal(SIGINT, oldintr); 158626049Sminshall code = -1; 158726049Sminshall return; 158826049Sminshall } 158926049Sminshall (*c->c_handler)(argc-1, argv+1); 159026049Sminshall if (connected) { 159126049Sminshall proxflag = 1; 159226049Sminshall } 159326049Sminshall else { 159426049Sminshall proxflag = 0; 159526049Sminshall } 159626049Sminshall pswitch(0); 159726049Sminshall (void) signal(SIGINT, oldintr); 159826049Sminshall } 159926049Sminshall 160026049Sminshall setcase() 160126049Sminshall { 160226049Sminshall mcase = !mcase; 160326049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 160426049Sminshall code = mcase; 160526049Sminshall } 160626049Sminshall 160726049Sminshall setcr() 160826049Sminshall { 160926049Sminshall crflag = !crflag; 161026049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 161126049Sminshall code = crflag; 161226049Sminshall } 161326049Sminshall 161426049Sminshall setntrans(argc,argv) 161526049Sminshall int argc; 161626049Sminshall char *argv[]; 161726049Sminshall { 161826049Sminshall if (argc == 1) { 161926049Sminshall ntflag = 0; 162026049Sminshall printf("Ntrans off.\n"); 162126049Sminshall code = ntflag; 162226049Sminshall return; 162326049Sminshall } 162426049Sminshall ntflag++; 162526049Sminshall code = ntflag; 162626049Sminshall (void) strncpy(ntin, argv[1], 16); 162726049Sminshall ntin[16] = '\0'; 162826049Sminshall if (argc == 2) { 162926049Sminshall ntout[0] = '\0'; 163026049Sminshall return; 163126049Sminshall } 163226049Sminshall (void) strncpy(ntout, argv[2], 16); 163326049Sminshall ntout[16] = '\0'; 163426049Sminshall } 163526049Sminshall 163626049Sminshall char * 163726049Sminshall dotrans(name) 163826049Sminshall char *name; 163926049Sminshall { 164026049Sminshall static char new[MAXPATHLEN]; 164126049Sminshall char *cp1, *cp2 = new; 164226049Sminshall register int i, ostop, found; 164326049Sminshall 164426049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 164526049Sminshall for (cp1 = name; *cp1; cp1++) { 164626049Sminshall found = 0; 164726049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 164826049Sminshall if (*cp1 == *(ntin + i)) { 164926049Sminshall found++; 165026049Sminshall if (i < ostop) { 165126049Sminshall *cp2++ = *(ntout + i); 165226049Sminshall } 165326049Sminshall break; 165426049Sminshall } 165526049Sminshall } 165626049Sminshall if (!found) { 165726049Sminshall *cp2++ = *cp1; 165826049Sminshall } 165926049Sminshall } 166026049Sminshall *cp2 = '\0'; 166126049Sminshall return(new); 166226049Sminshall } 166326049Sminshall 166426049Sminshall setnmap(argc, argv) 166526049Sminshall int argc; 166626049Sminshall char *argv[]; 166726049Sminshall { 166826049Sminshall char *cp; 166926049Sminshall 167026049Sminshall if (argc == 1) { 167126049Sminshall mapflag = 0; 167226049Sminshall printf("Nmap off.\n"); 167326049Sminshall code = mapflag; 167426049Sminshall return; 167526049Sminshall } 167626049Sminshall if (argc < 3) { 167726497Sminshall (void) strcat(line, " "); 167826049Sminshall printf("(mapout) "); 167926497Sminshall (void) gets(&line[strlen(line)]); 168026049Sminshall makeargv(); 168126049Sminshall argc = margc; 168226049Sminshall argv = margv; 168326049Sminshall } 168426049Sminshall if (argc < 3) { 168526049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 168626049Sminshall code = -1; 168726049Sminshall return; 168826049Sminshall } 168926049Sminshall mapflag = 1; 169026049Sminshall code = 1; 169126049Sminshall cp = index(altarg, ' '); 169226049Sminshall if (proxy) { 169326049Sminshall while(*++cp == ' '); 169426049Sminshall altarg = cp; 169526049Sminshall cp = index(altarg, ' '); 169626049Sminshall } 169726049Sminshall *cp = '\0'; 169826049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 169926049Sminshall while (*++cp == ' '); 170026049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 170126049Sminshall } 170226049Sminshall 170326049Sminshall char * 170426049Sminshall domap(name) 170526049Sminshall char *name; 170626049Sminshall { 170726049Sminshall static char new[MAXPATHLEN]; 170826049Sminshall register char *cp1 = name, *cp2 = mapin; 170926049Sminshall char *tp[9], *te[9]; 171036689Scsvsj int i, toks[9], toknum = 0, match = 1; 171126049Sminshall 171226049Sminshall for (i=0; i < 9; ++i) { 171326049Sminshall toks[i] = 0; 171426049Sminshall } 171526049Sminshall while (match && *cp1 && *cp2) { 171626049Sminshall switch (*cp2) { 171726049Sminshall case '\\': 171826049Sminshall if (*++cp2 != *cp1) { 171926049Sminshall match = 0; 172026049Sminshall } 172126049Sminshall break; 172226049Sminshall case '$': 172326049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 172426049Sminshall if (*cp1 != *(++cp2+1)) { 172526049Sminshall toks[toknum = *cp2 - '1']++; 172626049Sminshall tp[toknum] = cp1; 172726049Sminshall while (*++cp1 && *(cp2+1) 172826049Sminshall != *cp1); 172926049Sminshall te[toknum] = cp1; 173026049Sminshall } 173126049Sminshall cp2++; 173226049Sminshall break; 173326049Sminshall } 173436935Skarels /* FALLTHROUGH */ 173526049Sminshall default: 173626049Sminshall if (*cp2 != *cp1) { 173726049Sminshall match = 0; 173826049Sminshall } 173926049Sminshall break; 174026049Sminshall } 174136689Scsvsj if (match && *cp1) { 174226049Sminshall cp1++; 174326049Sminshall } 174436689Scsvsj if (match && *cp2) { 174526049Sminshall cp2++; 174626049Sminshall } 174726049Sminshall } 174836689Scsvsj if (!match && *cp1) /* last token mismatch */ 174936689Scsvsj { 175036689Scsvsj toks[toknum] = 0; 175136689Scsvsj } 175226049Sminshall cp1 = new; 175326049Sminshall *cp1 = '\0'; 175426049Sminshall cp2 = mapout; 175526049Sminshall while (*cp2) { 175626049Sminshall match = 0; 175726049Sminshall switch (*cp2) { 175826049Sminshall case '\\': 175926049Sminshall if (*(cp2 + 1)) { 176026049Sminshall *cp1++ = *++cp2; 176126049Sminshall } 176226049Sminshall break; 176326049Sminshall case '[': 176426049Sminshall LOOP: 176526049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 176626049Sminshall if (*++cp2 == '0') { 176726049Sminshall char *cp3 = name; 176826049Sminshall 176926049Sminshall while (*cp3) { 177026049Sminshall *cp1++ = *cp3++; 177126049Sminshall } 177226049Sminshall match = 1; 177326049Sminshall } 177426049Sminshall else if (toks[toknum = *cp2 - '1']) { 177526049Sminshall char *cp3 = tp[toknum]; 177626049Sminshall 177726049Sminshall while (cp3 != te[toknum]) { 177826049Sminshall *cp1++ = *cp3++; 177926049Sminshall } 178026049Sminshall match = 1; 178126049Sminshall } 178226049Sminshall } 178326049Sminshall else { 178426049Sminshall while (*cp2 && *cp2 != ',' && 178526049Sminshall *cp2 != ']') { 178626049Sminshall if (*cp2 == '\\') { 178726049Sminshall cp2++; 178826049Sminshall } 178926049Sminshall else if (*cp2 == '$' && 179026049Sminshall isdigit(*(cp2+1))) { 179126049Sminshall if (*++cp2 == '0') { 179226049Sminshall char *cp3 = name; 179326049Sminshall 179426049Sminshall while (*cp3) { 179526049Sminshall *cp1++ = *cp3++; 179626049Sminshall } 179726049Sminshall } 179826049Sminshall else if (toks[toknum = 179926049Sminshall *cp2 - '1']) { 180026049Sminshall char *cp3=tp[toknum]; 180126049Sminshall 180226049Sminshall while (cp3 != 180326049Sminshall te[toknum]) { 180426049Sminshall *cp1++ = *cp3++; 180526049Sminshall } 180626049Sminshall } 180726049Sminshall } 180826049Sminshall else if (*cp2) { 180926049Sminshall *cp1++ = *cp2++; 181026049Sminshall } 181126049Sminshall } 181226049Sminshall if (!*cp2) { 181326049Sminshall printf("nmap: unbalanced brackets\n"); 181426049Sminshall return(name); 181526049Sminshall } 181626049Sminshall match = 1; 181726049Sminshall cp2--; 181826049Sminshall } 181926049Sminshall if (match) { 182026049Sminshall while (*++cp2 && *cp2 != ']') { 182126049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 182226049Sminshall cp2++; 182326049Sminshall } 182426049Sminshall } 182526049Sminshall if (!*cp2) { 182626049Sminshall printf("nmap: unbalanced brackets\n"); 182726049Sminshall return(name); 182826049Sminshall } 182926049Sminshall break; 183026049Sminshall } 183126049Sminshall switch (*++cp2) { 183226049Sminshall case ',': 183326049Sminshall goto LOOP; 183426049Sminshall case ']': 183526049Sminshall break; 183626049Sminshall default: 183726049Sminshall cp2--; 183826049Sminshall goto LOOP; 183926049Sminshall } 184026049Sminshall break; 184126049Sminshall case '$': 184226049Sminshall if (isdigit(*(cp2 + 1))) { 184326049Sminshall if (*++cp2 == '0') { 184426049Sminshall char *cp3 = name; 184526049Sminshall 184626049Sminshall while (*cp3) { 184726049Sminshall *cp1++ = *cp3++; 184826049Sminshall } 184926049Sminshall } 185026049Sminshall else if (toks[toknum = *cp2 - '1']) { 185126049Sminshall char *cp3 = tp[toknum]; 185226049Sminshall 185326049Sminshall while (cp3 != te[toknum]) { 185426049Sminshall *cp1++ = *cp3++; 185526049Sminshall } 185626049Sminshall } 185726049Sminshall break; 185826049Sminshall } 185926049Sminshall /* intentional drop through */ 186026049Sminshall default: 186126049Sminshall *cp1++ = *cp2; 186226049Sminshall break; 186326049Sminshall } 186426049Sminshall cp2++; 186526049Sminshall } 186626049Sminshall *cp1 = '\0'; 186726049Sminshall if (!*new) { 186826049Sminshall return(name); 186926049Sminshall } 187026049Sminshall return(new); 187126049Sminshall } 187226049Sminshall 187326049Sminshall setsunique() 187426049Sminshall { 187526049Sminshall sunique = !sunique; 187626049Sminshall printf("Store unique %s.\n", onoff(sunique)); 187726049Sminshall code = sunique; 187826049Sminshall } 187926049Sminshall 188026049Sminshall setrunique() 188126049Sminshall { 188226049Sminshall runique = !runique; 188326049Sminshall printf("Receive unique %s.\n", onoff(runique)); 188426049Sminshall code = runique; 188526049Sminshall } 188626049Sminshall 188726049Sminshall /* change directory to perent directory */ 188826049Sminshall cdup() 188926049Sminshall { 189026049Sminshall (void) command("CDUP"); 189126049Sminshall } 189226049Sminshall 189336935Skarels /* restart transfer at specific point */ 189436935Skarels restart(argc, argv) 189536935Skarels int argc; 189636935Skarels char *argv[]; 189736935Skarels { 189836935Skarels extern long atol(); 189936935Skarels if (argc != 2) 190036935Skarels printf("restart: offset not specified\n"); 190136935Skarels else { 190236935Skarels restart_point = atol(argv[1]); 1903*36940Skarels printf("restarting at %ld. %s\n", restart_point, 1904*36940Skarels "execute get, put or append to initiate transfer"); 190536935Skarels } 190636935Skarels } 190736935Skarels 190836935Skarels /* show remote system type */ 190936935Skarels syst() 191036935Skarels { 191136935Skarels (void) command("SYST"); 191236935Skarels } 191336935Skarels 191426049Sminshall macdef(argc, argv) 191526049Sminshall int argc; 191626049Sminshall char *argv[]; 191726049Sminshall { 191826049Sminshall char *tmp; 191926049Sminshall int c; 192026049Sminshall 192126049Sminshall if (macnum == 16) { 192226049Sminshall printf("Limit of 16 macros have already been defined\n"); 192326049Sminshall code = -1; 192426049Sminshall return; 192526049Sminshall } 192626049Sminshall if (argc < 2) { 192726497Sminshall (void) strcat(line, " "); 192826049Sminshall printf("(macro name) "); 192926497Sminshall (void) gets(&line[strlen(line)]); 193026049Sminshall makeargv(); 193126049Sminshall argc = margc; 193226049Sminshall argv = margv; 193326049Sminshall } 193426049Sminshall if (argc != 2) { 193526049Sminshall printf("Usage: %s macro_name\n",argv[0]); 193626049Sminshall code = -1; 193726049Sminshall return; 193826049Sminshall } 193926049Sminshall if (interactive) { 194026049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 194126049Sminshall } 194226497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 194326049Sminshall if (macnum == 0) { 194426049Sminshall macros[macnum].mac_start = macbuf; 194526049Sminshall } 194626049Sminshall else { 194726049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 194826049Sminshall } 194926049Sminshall tmp = macros[macnum].mac_start; 195026049Sminshall while (tmp != macbuf+4096) { 195126049Sminshall if ((c = getchar()) == EOF) { 195226049Sminshall printf("macdef:end of file encountered\n"); 195326049Sminshall code = -1; 195426049Sminshall return; 195526049Sminshall } 195626049Sminshall if ((*tmp = c) == '\n') { 195726049Sminshall if (tmp == macros[macnum].mac_start) { 195826049Sminshall macros[macnum++].mac_end = tmp; 195926049Sminshall code = 0; 196026049Sminshall return; 196126049Sminshall } 196226049Sminshall if (*(tmp-1) == '\0') { 196326049Sminshall macros[macnum++].mac_end = tmp - 1; 196426049Sminshall code = 0; 196526049Sminshall return; 196626049Sminshall } 196726049Sminshall *tmp = '\0'; 196826049Sminshall } 196926049Sminshall tmp++; 197026049Sminshall } 197126049Sminshall while (1) { 197236935Skarels while ((c = getchar()) != '\n' && c != EOF) 197336935Skarels /* LOOP */; 197426049Sminshall if (c == EOF || getchar() == '\n') { 197526049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 197626049Sminshall code = -1; 197726049Sminshall return; 197826049Sminshall } 197926049Sminshall } 198026049Sminshall } 198136935Skarels 198236935Skarels /* 198336935Skarels * get size of file on remote machine 198436935Skarels */ 198536935Skarels sizecmd(argc, argv) 198636935Skarels char *argv[]; 198736935Skarels { 198836935Skarels 198936935Skarels if (argc < 2) { 199036935Skarels (void) strcat(line, " "); 199136935Skarels printf("(filename) "); 199236935Skarels (void) gets(&line[strlen(line)]); 199336935Skarels makeargv(); 199436935Skarels argc = margc; 199536935Skarels argv = margv; 199636935Skarels } 199736935Skarels if (argc < 2) { 199836935Skarels printf("usage:%s filename\n", argv[0]); 199936935Skarels code = -1; 200036935Skarels return; 200136935Skarels } 200236935Skarels (void) command("SIZE %s", argv[1]); 200336935Skarels } 200436935Skarels 200536935Skarels /* 200636935Skarels * get last modification time of file on remote machine 200736935Skarels */ 200836935Skarels modtime(argc, argv) 200936935Skarels char *argv[]; 201036935Skarels { 201136935Skarels int overbose; 201236935Skarels 201336935Skarels if (argc < 2) { 201436935Skarels (void) strcat(line, " "); 201536935Skarels printf("(filename) "); 201636935Skarels (void) gets(&line[strlen(line)]); 201736935Skarels makeargv(); 201836935Skarels argc = margc; 201936935Skarels argv = margv; 202036935Skarels } 202136935Skarels if (argc < 2) { 202236935Skarels printf("usage:%s filename\n", argv[0]); 202336935Skarels code = -1; 202436935Skarels return; 202536935Skarels } 2026*36940Skarels overbose = verbose; 2027*36940Skarels if (debug == 0) 2028*36940Skarels verbose = -1; 202936935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 203036935Skarels int yy, mo, day, hour, min, sec; 203136935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 203236935Skarels &day, &hour, &min, &sec); 203336935Skarels /* might want to print this in local time */ 203436935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 203536935Skarels mo, day, yy, hour, min, sec); 203636935Skarels } else 203736935Skarels fputs(reply_string, stdout); 203836935Skarels verbose = overbose; 203936935Skarels } 204036935Skarels 204136935Skarels /* 204236935Skarels * show status on reomte machine 204336935Skarels */ 204436935Skarels rmtstatus(argc, argv) 204536935Skarels char *argv[]; 204636935Skarels { 204736935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 204836935Skarels } 204936935Skarels 205036935Skarels /* 205136935Skarels * get file if modtime is more recent than current file 205236935Skarels */ 205336935Skarels newer(argc, argv) 205436935Skarels char *argv[]; 205536935Skarels { 205636935Skarels if (getit(argc, argv, -1, "w")) 205736935Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 205836935Skarels argv[1], argv[2]); 205936935Skarels } 2060