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 15*36935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*36935Skarels static char sccsid[] = "@(#)cmds.c 5.13 (Berkeley) 02/28/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2526049Sminshall #include "ftp_var.h" 2610294Ssam #include <sys/socket.h> 2710294Ssam 2812396Ssam #include <arpa/ftp.h> 2912396Ssam 3010294Ssam #include <signal.h> 3110294Ssam #include <stdio.h> 3210294Ssam #include <errno.h> 3310294Ssam #include <netdb.h> 3426049Sminshall #include <ctype.h> 35*36935Skarels #include <time.h> 3626497Sminshall #include <sys/wait.h> 37*36935Skarels #include <sys/stat.h> 38*36935Skarels #include <sys/param.h> 3910294Ssam 4010294Ssam 4111353Ssam extern char *globerr; 4211353Ssam extern char **glob(); 4311756Ssam extern char *home; 4411756Ssam extern char *remglob(); 4511756Ssam extern char *getenv(); 4611756Ssam extern char *index(); 4711756Ssam extern char *rindex(); 48*36935Skarels extern off_t restart_point; 49*36935Skarels extern char reply_string[]; 50*36935Skarels 5126049Sminshall char *mname; 5226049Sminshall jmp_buf jabort; 5326049Sminshall char *dotrans(), *domap(); 5410294Ssam 5510294Ssam /* 5610294Ssam * Connect to peer server and 5710294Ssam * auto-login, if possible. 5810294Ssam */ 5910294Ssam setpeer(argc, argv) 6010294Ssam int argc; 6110294Ssam char *argv[]; 6210294Ssam { 6325903Skarels char *host, *hookup(); 6410294Ssam int port; 6510294Ssam 6610294Ssam if (connected) { 6726049Sminshall printf("Already connected to %s, use close first.\n", 6810294Ssam hostname); 6926049Sminshall code = -1; 7010294Ssam return; 7110294Ssam } 7210294Ssam if (argc < 2) { 7326497Sminshall (void) strcat(line, " "); 7410294Ssam printf("(to) "); 7526497Sminshall (void) gets(&line[strlen(line)]); 7610294Ssam makeargv(); 7710294Ssam argc = margc; 7810294Ssam argv = margv; 7910294Ssam } 8010294Ssam if (argc > 3) { 8110294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8226049Sminshall code = -1; 8310294Ssam return; 8410294Ssam } 8510294Ssam port = sp->s_port; 8610294Ssam if (argc > 2) { 8711218Ssam port = atoi(argv[2]); 8810294Ssam if (port <= 0) { 8911218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9011218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9126049Sminshall code = -1; 9210294Ssam return; 9310294Ssam } 9410294Ssam port = htons(port); 9510294Ssam } 9610294Ssam host = hookup(argv[1], port); 9710294Ssam if (host) { 9810294Ssam connected = 1; 99*36935Skarels if (autologin) { 100*36935Skarels int overbose; 10126497Sminshall (void) login(argv[1]); 102*36935Skarels #if defined(unix) && NBBY == 8 103*36935Skarels /* 104*36935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 105*36935Skarels * system and not checking this out. This way they have to think about it. 106*36935Skarels */ 107*36935Skarels overbose = verbose, verbose = -1; 108*36935Skarels if (command("SYST") == COMPLETE && overbose) { 109*36935Skarels register char *cp, c; 110*36935Skarels cp = index(reply_string+4, ' '); 111*36935Skarels if (cp == NULL) 112*36935Skarels cp = index(reply_string+4, '\r'); 113*36935Skarels if (cp) { 114*36935Skarels if (cp[-1] == '.') 115*36935Skarels cp--; 116*36935Skarels c = *cp; 117*36935Skarels *cp = '\0'; 118*36935Skarels } 119*36935Skarels 120*36935Skarels printf("Remote system type is %s.\n", 121*36935Skarels reply_string+4); 122*36935Skarels if (cp) 123*36935Skarels *cp = c; 124*36935Skarels } 125*36935Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 126*36935Skarels setbinary(); 127*36935Skarels if (overbose) 128*36935Skarels printf("Using %s mode to transfer files.\n", 129*36935Skarels typename); 130*36935Skarels } else if (overbose && 131*36935Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 132*36935Skarels printf("Remember to set tenex mode when transfering binary files from this machine.\n"); 133*36935Skarels } 134*36935Skarels verbose = overbose; 135*36935Skarels #endif /* unix */ 136*36935Skarels } 13710294Ssam } 13810294Ssam } 13910294Ssam 14010294Ssam struct types { 14110294Ssam char *t_name; 14210294Ssam char *t_mode; 14310294Ssam int t_type; 14411218Ssam char *t_arg; 14510294Ssam } types[] = { 14611218Ssam { "ascii", "A", TYPE_A, 0 }, 14711218Ssam { "binary", "I", TYPE_I, 0 }, 14811218Ssam { "image", "I", TYPE_I, 0 }, 14911218Ssam { "ebcdic", "E", TYPE_E, 0 }, 15011218Ssam { "tenex", "L", TYPE_L, bytename }, 15110294Ssam 0 15210294Ssam }; 15310294Ssam 15410294Ssam /* 15510294Ssam * Set transfer type. 15610294Ssam */ 15710294Ssam settype(argc, argv) 15810294Ssam char *argv[]; 15910294Ssam { 16010294Ssam register struct types *p; 16111218Ssam int comret; 16210294Ssam 16310294Ssam if (argc > 2) { 16410294Ssam char *sep; 16510294Ssam 16610294Ssam printf("usage: %s [", argv[0]); 16710294Ssam sep = " "; 16810294Ssam for (p = types; p->t_name; p++) { 16910294Ssam printf("%s%s", sep, p->t_name); 17010294Ssam if (*sep == ' ') 17110294Ssam sep = " | "; 17210294Ssam } 17310294Ssam printf(" ]\n"); 17426049Sminshall code = -1; 17510294Ssam return; 17610294Ssam } 17710294Ssam if (argc < 2) { 17810294Ssam printf("Using %s mode to transfer files.\n", typename); 17926049Sminshall code = 0; 18010294Ssam return; 18110294Ssam } 18210294Ssam for (p = types; p->t_name; p++) 18310294Ssam if (strcmp(argv[1], p->t_name) == 0) 18410294Ssam break; 18510294Ssam if (p->t_name == 0) { 18610294Ssam printf("%s: unknown mode\n", argv[1]); 18726049Sminshall code = -1; 18810294Ssam return; 18910294Ssam } 19011218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 19111218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 19211218Ssam else 19311218Ssam comret = command("TYPE %s", p->t_mode); 19411218Ssam if (comret == COMPLETE) { 19526497Sminshall (void) strcpy(typename, p->t_name); 19610294Ssam type = p->t_type; 19710294Ssam } 19810294Ssam } 19910294Ssam 20010294Ssam /* 20110294Ssam * Set binary transfer type. 20210294Ssam */ 20310294Ssam /*VARARGS*/ 20410294Ssam setbinary() 20510294Ssam { 20610294Ssam 20710294Ssam call(settype, "type", "binary", 0); 20810294Ssam } 20910294Ssam 21010294Ssam /* 21110294Ssam * Set ascii transfer type. 21210294Ssam */ 21310294Ssam /*VARARGS*/ 21410294Ssam setascii() 21510294Ssam { 21610294Ssam 21710294Ssam call(settype, "type", "ascii", 0); 21810294Ssam } 21910294Ssam 22010294Ssam /* 22110294Ssam * Set tenex transfer type. 22210294Ssam */ 22310294Ssam /*VARARGS*/ 22410294Ssam settenex() 22510294Ssam { 22610294Ssam 22710294Ssam call(settype, "type", "tenex", 0); 22810294Ssam } 22910294Ssam 23010294Ssam /* 23110294Ssam * Set ebcdic transfer type. 23210294Ssam */ 23310294Ssam /*VARARGS*/ 23410294Ssam setebcdic() 23510294Ssam { 23610294Ssam 23710294Ssam call(settype, "type", "ebcdic", 0); 23810294Ssam } 23910294Ssam 24010294Ssam /* 24110294Ssam * Set file transfer mode. 24210294Ssam */ 24326497Sminshall /*ARGSUSED*/ 24410294Ssam setmode(argc, argv) 24510294Ssam char *argv[]; 24610294Ssam { 24710294Ssam 24810294Ssam printf("We only support %s mode, sorry.\n", modename); 24926049Sminshall code = -1; 25010294Ssam } 25110294Ssam 25210294Ssam /* 25310294Ssam * Set file transfer format. 25410294Ssam */ 25526497Sminshall /*ARGSUSED*/ 25610294Ssam setform(argc, argv) 25710294Ssam char *argv[]; 25810294Ssam { 25910294Ssam 26010294Ssam printf("We only support %s format, sorry.\n", formname); 26126049Sminshall code = -1; 26210294Ssam } 26310294Ssam 26410294Ssam /* 26510294Ssam * Set file transfer structure. 26610294Ssam */ 26726497Sminshall /*ARGSUSED*/ 26810294Ssam setstruct(argc, argv) 26910294Ssam char *argv[]; 27010294Ssam { 27110294Ssam 27210294Ssam printf("We only support %s structure, sorry.\n", structname); 27326049Sminshall code = -1; 27410294Ssam } 27510294Ssam 27618286Sralph /* 27718286Sralph * Send a single file. 27818286Sralph */ 27910294Ssam put(argc, argv) 28011756Ssam int argc; 28110294Ssam char *argv[]; 28210294Ssam { 28311650Ssam char *cmd; 28426049Sminshall int loc = 0; 28525908Smckusick char *oldargv1; 28611650Ssam 28726049Sminshall if (argc == 2) { 28826049Sminshall argc++; 28926049Sminshall argv[2] = argv[1]; 29026049Sminshall loc++; 29126049Sminshall } 29210294Ssam if (argc < 2) { 29326497Sminshall (void) strcat(line, " "); 29410294Ssam printf("(local-file) "); 29526497Sminshall (void) gets(&line[strlen(line)]); 29610294Ssam makeargv(); 29710294Ssam argc = margc; 29810294Ssam argv = margv; 29910294Ssam } 30010294Ssam if (argc < 2) { 30110294Ssam usage: 30226049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 30326049Sminshall code = -1; 30410294Ssam return; 30510294Ssam } 30610294Ssam if (argc < 3) { 30726497Sminshall (void) strcat(line, " "); 30810294Ssam printf("(remote-file) "); 30926497Sminshall (void) gets(&line[strlen(line)]); 31010294Ssam makeargv(); 31110294Ssam argc = margc; 31210294Ssam argv = margv; 31310294Ssam } 31410294Ssam if (argc < 3) 31510294Ssam goto usage; 31625908Smckusick oldargv1 = argv[1]; 31726049Sminshall if (!globulize(&argv[1])) { 31826049Sminshall code = -1; 31911353Ssam return; 32026049Sminshall } 32125908Smckusick /* 32225908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 32325908Smckusick * the old argv[1], make it a copy of the new argv[1]. 32425908Smckusick */ 32526049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 32625908Smckusick argv[2] = argv[1]; 32726049Sminshall } 32826049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 32926049Sminshall if (loc && ntflag) { 33026049Sminshall argv[2] = dotrans(argv[2]); 33126049Sminshall } 33226049Sminshall if (loc && mapflag) { 33326049Sminshall argv[2] = domap(argv[2]); 33426049Sminshall } 33511650Ssam sendrequest(cmd, argv[1], argv[2]); 33610294Ssam } 33710294Ssam 33810294Ssam /* 33911756Ssam * Send multiple files. 34010294Ssam */ 34111353Ssam mput(argc, argv) 34211353Ssam char *argv[]; 34311353Ssam { 34413212Ssam register int i; 34526049Sminshall int ointer, (*oldintr)(), mabort(); 34626049Sminshall extern jmp_buf jabort; 34726049Sminshall char *tp; 34811353Ssam 34911650Ssam if (argc < 2) { 35026497Sminshall (void) strcat(line, " "); 35111650Ssam printf("(local-files) "); 35226497Sminshall (void) gets(&line[strlen(line)]); 35311650Ssam makeargv(); 35411650Ssam argc = margc; 35511650Ssam argv = margv; 35611353Ssam } 35711353Ssam if (argc < 2) { 35826049Sminshall printf("usage:%s local-files\n", argv[0]); 35926049Sminshall code = -1; 36011353Ssam return; 36111353Ssam } 36226049Sminshall mname = argv[0]; 36326049Sminshall mflag = 1; 36426049Sminshall oldintr = signal(SIGINT, mabort); 36526049Sminshall (void) setjmp(jabort); 36626049Sminshall if (proxy) { 36726049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 36826049Sminshall 36926497Sminshall while ((cp = remglob(argv,0)) != NULL) { 37026049Sminshall if (*cp == 0) { 37126049Sminshall mflag = 0; 37226049Sminshall continue; 37326049Sminshall } 37426049Sminshall if (mflag && confirm(argv[0], cp)) { 37526049Sminshall tp = cp; 37626049Sminshall if (mcase) { 37726049Sminshall while (*tp && !islower(*tp)) { 37826049Sminshall tp++; 37926049Sminshall } 38026049Sminshall if (!*tp) { 38126049Sminshall tp = cp; 38226049Sminshall tp2 = tmpbuf; 38326049Sminshall while ((*tp2 = *tp) != NULL) { 38426049Sminshall if (isupper(*tp2)) { 38526049Sminshall *tp2 = 'a' + *tp2 - 'A'; 38626049Sminshall } 38726049Sminshall tp++; 38826049Sminshall tp2++; 38926049Sminshall } 39026049Sminshall } 39126049Sminshall tp = tmpbuf; 39226049Sminshall } 39326049Sminshall if (ntflag) { 39426049Sminshall tp = dotrans(tp); 39526049Sminshall } 39626049Sminshall if (mapflag) { 39726049Sminshall tp = domap(tp); 39826049Sminshall } 39926049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 40026049Sminshall if (!mflag && fromatty) { 40126049Sminshall ointer = interactive; 40226049Sminshall interactive = 1; 40326049Sminshall if (confirm("Continue with","mput")) { 40426049Sminshall mflag++; 40526049Sminshall } 40626049Sminshall interactive = ointer; 40726049Sminshall } 40826049Sminshall } 40926049Sminshall } 41026049Sminshall (void) signal(SIGINT, oldintr); 41126049Sminshall mflag = 0; 41226049Sminshall return; 41326049Sminshall } 41413212Ssam for (i = 1; i < argc; i++) { 41513212Ssam register char **cpp, **gargs; 41613212Ssam 41713212Ssam if (!doglob) { 41826049Sminshall if (mflag && confirm(argv[0], argv[i])) { 41926049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 42026049Sminshall tp = (mapflag) ? domap(tp) : tp; 42126049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 42226049Sminshall argv[i], tp); 42326049Sminshall if (!mflag && fromatty) { 42426049Sminshall ointer = interactive; 42526049Sminshall interactive = 1; 42626049Sminshall if (confirm("Continue with","mput")) { 42726049Sminshall mflag++; 42826049Sminshall } 42926049Sminshall interactive = ointer; 43026049Sminshall } 43126049Sminshall } 43213212Ssam continue; 43313212Ssam } 43413212Ssam gargs = glob(argv[i]); 43511650Ssam if (globerr != NULL) { 43611650Ssam printf("%s\n", globerr); 43736421Sbostic if (gargs) { 43811650Ssam blkfree(gargs); 43936421Sbostic free(gargs); 44036421Sbostic } 44113212Ssam continue; 44211353Ssam } 44326049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 44426049Sminshall if (mflag && confirm(argv[0], *cpp)) { 44526049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 44626049Sminshall tp = (mapflag) ? domap(tp) : tp; 44726049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 44826049Sminshall *cpp, tp); 44926049Sminshall if (!mflag && fromatty) { 45026049Sminshall ointer = interactive; 45126049Sminshall interactive = 1; 45226049Sminshall if (confirm("Continue with","mput")) { 45326049Sminshall mflag++; 45426049Sminshall } 45526049Sminshall interactive = ointer; 45626049Sminshall } 45726049Sminshall } 45826049Sminshall } 45936421Sbostic if (gargs != NULL) { 46013212Ssam blkfree(gargs); 46136421Sbostic free(gargs); 46236421Sbostic } 46311353Ssam } 46426049Sminshall (void) signal(SIGINT, oldintr); 46526049Sminshall mflag = 0; 46611353Ssam } 46711353Ssam 468*36935Skarels reget(argc, argv) 469*36935Skarels char *argv[]; 470*36935Skarels { 471*36935Skarels (void) getit(argc, argv, 1, "r+w"); 472*36935Skarels } 473*36935Skarels 474*36935Skarels get(argc, argv) 475*36935Skarels char *argv[]; 476*36935Skarels { 477*36935Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 478*36935Skarels } 479*36935Skarels 48011353Ssam /* 48111353Ssam * Receive one file. 48211353Ssam */ 483*36935Skarels getit(argc, argv, restartit, mode) 48410294Ssam char *argv[]; 485*36935Skarels char *mode; 48610294Ssam { 48726049Sminshall int loc = 0; 48810294Ssam 48926049Sminshall if (argc == 2) { 49026049Sminshall argc++; 49126049Sminshall argv[2] = argv[1]; 49226049Sminshall loc++; 49326049Sminshall } 49410294Ssam if (argc < 2) { 49526497Sminshall (void) strcat(line, " "); 49610294Ssam printf("(remote-file) "); 49726497Sminshall (void) gets(&line[strlen(line)]); 49810294Ssam makeargv(); 49910294Ssam argc = margc; 50010294Ssam argv = margv; 50110294Ssam } 50210294Ssam if (argc < 2) { 50310294Ssam usage: 50426049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 50526049Sminshall code = -1; 506*36935Skarels return 0; 50710294Ssam } 50810294Ssam if (argc < 3) { 50926497Sminshall (void) strcat(line, " "); 51010294Ssam printf("(local-file) "); 51126497Sminshall (void) gets(&line[strlen(line)]); 51210294Ssam makeargv(); 51310294Ssam argc = margc; 51410294Ssam argv = margv; 51510294Ssam } 51610294Ssam if (argc < 3) 51710294Ssam goto usage; 51826049Sminshall if (!globulize(&argv[2])) { 51926049Sminshall code = -1; 520*36935Skarels return 0; 52126049Sminshall } 52226049Sminshall if (loc && mcase) { 52326049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 52426049Sminshall 52526049Sminshall while (*tp && !islower(*tp)) { 52626049Sminshall tp++; 52726049Sminshall } 52826049Sminshall if (!*tp) { 52926049Sminshall tp = argv[2]; 53026049Sminshall tp2 = tmpbuf; 53126049Sminshall while ((*tp2 = *tp) != NULL) { 53226049Sminshall if (isupper(*tp2)) { 53326049Sminshall *tp2 = 'a' + *tp2 - 'A'; 53426049Sminshall } 53526049Sminshall tp++; 53626049Sminshall tp2++; 53726049Sminshall } 53826049Sminshall argv[2] = tmpbuf; 53926049Sminshall } 54026049Sminshall } 54126049Sminshall if (loc && ntflag) { 54226049Sminshall argv[2] = dotrans(argv[2]); 54326049Sminshall } 54426049Sminshall if (loc && mapflag) { 54526049Sminshall argv[2] = domap(argv[2]); 54626049Sminshall } 547*36935Skarels if (restartit) { 548*36935Skarels struct stat stbuf; 549*36935Skarels int ret; 550*36935Skarels ret = stat(argv[2], &stbuf); 551*36935Skarels if (restartit == 1) { 552*36935Skarels if (ret < 0) { 553*36935Skarels perror(argv[2]); 554*36935Skarels return 0; 555*36935Skarels } 556*36935Skarels restart_point = stbuf.st_size; 557*36935Skarels } else { 558*36935Skarels if (ret == 0) { 559*36935Skarels int overbose; 560*36935Skarels overbose = verbose; verbose = -1; 561*36935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 562*36935Skarels int yy, mo, day, hour, min, sec; 563*36935Skarels struct tm *tm; 564*36935Skarels verbose = overbose; 565*36935Skarels sscanf(reply_string, 566*36935Skarels "%*s %04d%02d%02d%02d%02d%02d", 567*36935Skarels &yy, &mo, &day, &hour, &min, &sec); 568*36935Skarels tm = gmtime(&stbuf.st_mtime); 569*36935Skarels tm->tm_mon++; 570*36935Skarels if (tm->tm_year > yy%100) 571*36935Skarels return 1; 572*36935Skarels else if (tm->tm_year == yy%100) { 573*36935Skarels if (tm->tm_mon > mo) 574*36935Skarels return 1; 575*36935Skarels } else if (tm->tm_mon == mo) { 576*36935Skarels if (tm->tm_mday > day) 577*36935Skarels return 1; 578*36935Skarels } else if (tm->tm_mday == day) { 579*36935Skarels if (tm->tm_hour > hour) 580*36935Skarels return 1; 581*36935Skarels } else if (tm->tm_hour == hour) { 582*36935Skarels if (tm->tm_min > min) 583*36935Skarels return 1; 584*36935Skarels } else if (tm->tm_min == min) { 585*36935Skarels if (tm->tm_sec > sec) 586*36935Skarels return 1; 587*36935Skarels } 588*36935Skarels } else { 589*36935Skarels fputs(reply_string, stdout); 590*36935Skarels verbose = overbose; 591*36935Skarels return 0; 592*36935Skarels } 593*36935Skarels } 594*36935Skarels } 595*36935Skarels } 596*36935Skarels 597*36935Skarels recvrequest("RETR", argv[2], argv[1], mode); 598*36935Skarels restart_point = 0; 599*36935Skarels return 0; 60010294Ssam } 60110294Ssam 60226049Sminshall mabort() 60326049Sminshall { 60426049Sminshall int ointer; 60526049Sminshall extern jmp_buf jabort; 60626049Sminshall 60726049Sminshall printf("\n"); 60826049Sminshall (void) fflush(stdout); 60926049Sminshall if (mflag && fromatty) { 61026049Sminshall ointer = interactive; 61126049Sminshall interactive = 1; 61226049Sminshall if (confirm("Continue with", mname)) { 61326049Sminshall interactive = ointer; 61426049Sminshall longjmp(jabort,0); 61526049Sminshall } 61626049Sminshall interactive = ointer; 61726049Sminshall } 61826049Sminshall mflag = 0; 61926049Sminshall longjmp(jabort,0); 62026049Sminshall } 62126049Sminshall 62211353Ssam /* 62311353Ssam * Get multiple files. 62411353Ssam */ 62511353Ssam mget(argc, argv) 62611353Ssam char *argv[]; 62711353Ssam { 62826049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 62926049Sminshall int ointer, (*oldintr)(), mabort(); 63026049Sminshall extern jmp_buf jabort; 63111353Ssam 63211353Ssam if (argc < 2) { 63326497Sminshall (void) strcat(line, " "); 63411756Ssam printf("(remote-files) "); 63526497Sminshall (void) gets(&line[strlen(line)]); 63611353Ssam makeargv(); 63711353Ssam argc = margc; 63811353Ssam argv = margv; 63911353Ssam } 64011353Ssam if (argc < 2) { 64126049Sminshall printf("usage:%s remote-files\n", argv[0]); 64226049Sminshall code = -1; 64311353Ssam return; 64411353Ssam } 64526049Sminshall mname = argv[0]; 64626049Sminshall mflag = 1; 64726049Sminshall oldintr = signal(SIGINT,mabort); 64826049Sminshall (void) setjmp(jabort); 64926497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 65026049Sminshall if (*cp == '\0') { 65126049Sminshall mflag = 0; 65226049Sminshall continue; 65326049Sminshall } 65426049Sminshall if (mflag && confirm(argv[0], cp)) { 65526049Sminshall tp = cp; 65626049Sminshall if (mcase) { 65726049Sminshall while (*tp && !islower(*tp)) { 65826049Sminshall tp++; 65926049Sminshall } 66026049Sminshall if (!*tp) { 66126049Sminshall tp = cp; 66226049Sminshall tp2 = tmpbuf; 66326049Sminshall while ((*tp2 = *tp) != NULL) { 66426049Sminshall if (isupper(*tp2)) { 66526049Sminshall *tp2 = 'a' + *tp2 - 'A'; 66626049Sminshall } 66726049Sminshall tp++; 66826049Sminshall tp2++; 66926049Sminshall } 67026049Sminshall } 67126049Sminshall tp = tmpbuf; 67226049Sminshall } 67326049Sminshall if (ntflag) { 67426049Sminshall tp = dotrans(tp); 67526049Sminshall } 67626049Sminshall if (mapflag) { 67726049Sminshall tp = domap(tp); 67826049Sminshall } 67926049Sminshall recvrequest("RETR", tp, cp, "w"); 68026049Sminshall if (!mflag && fromatty) { 68126049Sminshall ointer = interactive; 68226049Sminshall interactive = 1; 68326049Sminshall if (confirm("Continue with","mget")) { 68426049Sminshall mflag++; 68526049Sminshall } 68626049Sminshall interactive = ointer; 68726049Sminshall } 68826049Sminshall } 68926049Sminshall } 69026049Sminshall (void) signal(SIGINT,oldintr); 69126049Sminshall mflag = 0; 69211650Ssam } 69311650Ssam 69411650Ssam char * 69526497Sminshall remglob(argv,doswitch) 69611650Ssam char *argv[]; 69726497Sminshall int doswitch; 69811650Ssam { 69911756Ssam char temp[16]; 70011650Ssam static char buf[MAXPATHLEN]; 70111650Ssam static FILE *ftemp = NULL; 70211650Ssam static char **args; 70313212Ssam int oldverbose, oldhash; 70411756Ssam char *cp, *mode; 70511650Ssam 70626049Sminshall if (!mflag) { 70726049Sminshall if (!doglob) { 70826049Sminshall args = NULL; 70926049Sminshall } 71026049Sminshall else { 71126049Sminshall if (ftemp) { 71226497Sminshall (void) fclose(ftemp); 71326049Sminshall ftemp = NULL; 71426049Sminshall } 71526049Sminshall } 71626049Sminshall return(NULL); 71726049Sminshall } 71811650Ssam if (!doglob) { 71911756Ssam if (args == NULL) 72011650Ssam args = argv; 72111650Ssam if ((cp = *++args) == NULL) 72211650Ssam args = NULL; 72311650Ssam return (cp); 72411353Ssam } 72511650Ssam if (ftemp == NULL) { 72626497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 72726497Sminshall (void) mktemp(temp); 72811650Ssam oldverbose = verbose, verbose = 0; 72913212Ssam oldhash = hash, hash = 0; 73026049Sminshall if (doswitch) { 73126049Sminshall pswitch(!proxy); 73226049Sminshall } 73311756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 73411756Ssam recvrequest ("NLST", temp, *argv, mode); 73526049Sminshall if (doswitch) { 73626049Sminshall pswitch(!proxy); 73726049Sminshall } 73813212Ssam verbose = oldverbose; hash = oldhash; 73911650Ssam ftemp = fopen(temp, "r"); 74026497Sminshall (void) unlink(temp); 74111650Ssam if (ftemp == NULL) { 74211650Ssam printf("can't find list of remote files, oops\n"); 74311756Ssam return (NULL); 74411353Ssam } 74511353Ssam } 74611650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 74726497Sminshall (void) fclose(ftemp), ftemp = NULL; 74811650Ssam return (NULL); 74911353Ssam } 75011650Ssam if ((cp = index(buf, '\n')) != NULL) 75111650Ssam *cp = '\0'; 75211650Ssam return (buf); 75311353Ssam } 75411353Ssam 75510294Ssam char * 75610294Ssam onoff(bool) 75710294Ssam int bool; 75810294Ssam { 75910294Ssam 76010294Ssam return (bool ? "on" : "off"); 76110294Ssam } 76210294Ssam 76310294Ssam /* 76410294Ssam * Show status. 76510294Ssam */ 76626497Sminshall /*ARGSUSED*/ 76710294Ssam status(argc, argv) 76810294Ssam char *argv[]; 76910294Ssam { 77026049Sminshall int i; 77110294Ssam 77210294Ssam if (connected) 77310294Ssam printf("Connected to %s.\n", hostname); 77410294Ssam else 77510294Ssam printf("Not connected.\n"); 77626049Sminshall if (!proxy) { 77726049Sminshall pswitch(1); 77826049Sminshall if (connected) { 77926049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 78026049Sminshall } 78126049Sminshall else { 78226049Sminshall printf("No proxy connection.\n"); 78326049Sminshall } 78426049Sminshall pswitch(0); 78526049Sminshall } 78610294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 78710294Ssam modename, typename, formname, structname); 78811353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 78911353Ssam onoff(verbose), onoff(bell), onoff(interactive), 79011353Ssam onoff(doglob)); 79126049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 79226049Sminshall onoff(runique)); 79326049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 79426049Sminshall if (ntflag) { 79526049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 79626049Sminshall } 79726049Sminshall else { 79826049Sminshall printf("Ntrans: off\n"); 79926049Sminshall } 80026049Sminshall if (mapflag) { 80126049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 80226049Sminshall } 80326049Sminshall else { 80426049Sminshall printf("Nmap: off\n"); 80526049Sminshall } 80614143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 80714143Ssam onoff(hash), onoff(sendport)); 80826049Sminshall if (macnum > 0) { 80926049Sminshall printf("Macros:\n"); 81026049Sminshall for (i=0; i<macnum; i++) { 81126049Sminshall printf("\t%s\n",macros[i].mac_name); 81226049Sminshall } 81326049Sminshall } 81426049Sminshall code = 0; 81510294Ssam } 81610294Ssam 81710294Ssam /* 81810294Ssam * Set beep on cmd completed mode. 81910294Ssam */ 82010294Ssam /*VARARGS*/ 82110294Ssam setbell() 82210294Ssam { 82310294Ssam 82410294Ssam bell = !bell; 82510294Ssam printf("Bell mode %s.\n", onoff(bell)); 82626049Sminshall code = bell; 82710294Ssam } 82810294Ssam 82910294Ssam /* 83010294Ssam * Turn on packet tracing. 83110294Ssam */ 83210294Ssam /*VARARGS*/ 83310294Ssam settrace() 83410294Ssam { 83510294Ssam 83610294Ssam trace = !trace; 83710294Ssam printf("Packet tracing %s.\n", onoff(trace)); 83826049Sminshall code = trace; 83910294Ssam } 84010294Ssam 84110294Ssam /* 84211650Ssam * Toggle hash mark printing during transfers. 84311650Ssam */ 84411650Ssam /*VARARGS*/ 84511650Ssam sethash() 84611650Ssam { 84711650Ssam 84811650Ssam hash = !hash; 84911650Ssam printf("Hash mark printing %s", onoff(hash)); 85026049Sminshall code = hash; 85111650Ssam if (hash) 85211650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 85311650Ssam printf(".\n"); 85411650Ssam } 85511650Ssam 85611650Ssam /* 85710294Ssam * Turn on printing of server echo's. 85810294Ssam */ 85910294Ssam /*VARARGS*/ 86010294Ssam setverbose() 86110294Ssam { 86210294Ssam 86310294Ssam verbose = !verbose; 86410294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 86526049Sminshall code = verbose; 86610294Ssam } 86710294Ssam 86810294Ssam /* 86911650Ssam * Toggle PORT cmd use before each data connection. 87011650Ssam */ 87111650Ssam /*VARARGS*/ 87211650Ssam setport() 87311650Ssam { 87411650Ssam 87511650Ssam sendport = !sendport; 87611650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 87726049Sminshall code = sendport; 87811650Ssam } 87911650Ssam 88011650Ssam /* 88110294Ssam * Turn on interactive prompting 88210294Ssam * during mget, mput, and mdelete. 88310294Ssam */ 88410294Ssam /*VARARGS*/ 88510294Ssam setprompt() 88610294Ssam { 88710294Ssam 88810294Ssam interactive = !interactive; 88910294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 89026049Sminshall code = interactive; 89110294Ssam } 89210294Ssam 89310294Ssam /* 89411353Ssam * Toggle metacharacter interpretation 89511353Ssam * on local file names. 89611353Ssam */ 89711353Ssam /*VARARGS*/ 89811353Ssam setglob() 89911353Ssam { 90011353Ssam 90111353Ssam doglob = !doglob; 90211353Ssam printf("Globbing %s.\n", onoff(doglob)); 90326049Sminshall code = doglob; 90411353Ssam } 90511353Ssam 90611353Ssam /* 90710294Ssam * Set debugging mode on/off and/or 90810294Ssam * set level of debugging. 90910294Ssam */ 91011756Ssam /*VARARGS*/ 91110294Ssam setdebug(argc, argv) 91210294Ssam char *argv[]; 91310294Ssam { 91410294Ssam int val; 91510294Ssam 91610294Ssam if (argc > 1) { 91710294Ssam val = atoi(argv[1]); 91810294Ssam if (val < 0) { 91910294Ssam printf("%s: bad debugging value.\n", argv[1]); 92026049Sminshall code = -1; 92110294Ssam return; 92210294Ssam } 92310294Ssam } else 92410294Ssam val = !debug; 92510294Ssam debug = val; 92610294Ssam if (debug) 92710294Ssam options |= SO_DEBUG; 92810294Ssam else 92910294Ssam options &= ~SO_DEBUG; 93010294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 93126049Sminshall code = debug > 0; 93210294Ssam } 93310294Ssam 93410294Ssam /* 93510294Ssam * Set current working directory 93610294Ssam * on remote machine. 93710294Ssam */ 93810294Ssam cd(argc, argv) 93910294Ssam char *argv[]; 94010294Ssam { 94110294Ssam 94210294Ssam if (argc < 2) { 94326497Sminshall (void) strcat(line, " "); 94410294Ssam printf("(remote-directory) "); 94526497Sminshall (void) gets(&line[strlen(line)]); 94610294Ssam makeargv(); 94710294Ssam argc = margc; 94810294Ssam argv = margv; 94910294Ssam } 95010294Ssam if (argc < 2) { 95126049Sminshall printf("usage:%s remote-directory\n", argv[0]); 95226049Sminshall code = -1; 95310294Ssam return; 95410294Ssam } 95510294Ssam (void) command("CWD %s", argv[1]); 95610294Ssam } 95710294Ssam 95810294Ssam /* 95910294Ssam * Set current working directory 96010294Ssam * on local machine. 96110294Ssam */ 96210294Ssam lcd(argc, argv) 96310294Ssam char *argv[]; 96410294Ssam { 96511353Ssam char buf[MAXPATHLEN]; 96610294Ssam 96711353Ssam if (argc < 2) 96811353Ssam argc++, argv[1] = home; 96910294Ssam if (argc != 2) { 97026049Sminshall printf("usage:%s local-directory\n", argv[0]); 97126049Sminshall code = -1; 97210294Ssam return; 97310294Ssam } 97426049Sminshall if (!globulize(&argv[1])) { 97526049Sminshall code = -1; 97611353Ssam return; 97726049Sminshall } 97811353Ssam if (chdir(argv[1]) < 0) { 97910294Ssam perror(argv[1]); 98026049Sminshall code = -1; 98111353Ssam return; 98211353Ssam } 98311353Ssam printf("Local directory now %s\n", getwd(buf)); 98426049Sminshall code = 0; 98510294Ssam } 98610294Ssam 98710294Ssam /* 98810294Ssam * Delete a single file. 98910294Ssam */ 99010294Ssam delete(argc, argv) 99110294Ssam char *argv[]; 99210294Ssam { 99310294Ssam 99410294Ssam if (argc < 2) { 99526497Sminshall (void) strcat(line, " "); 99610294Ssam printf("(remote-file) "); 99726497Sminshall (void) gets(&line[strlen(line)]); 99810294Ssam makeargv(); 99910294Ssam argc = margc; 100010294Ssam argv = margv; 100110294Ssam } 100210294Ssam if (argc < 2) { 100326049Sminshall printf("usage:%s remote-file\n", argv[0]); 100426049Sminshall code = -1; 100510294Ssam return; 100610294Ssam } 100710294Ssam (void) command("DELE %s", argv[1]); 100810294Ssam } 100910294Ssam 101010294Ssam /* 101111650Ssam * Delete multiple files. 101211650Ssam */ 101311650Ssam mdelete(argc, argv) 101411650Ssam char *argv[]; 101511650Ssam { 101611650Ssam char *cp; 101726049Sminshall int ointer, (*oldintr)(), mabort(); 101826049Sminshall extern jmp_buf jabort; 101911650Ssam 102011650Ssam if (argc < 2) { 102126497Sminshall (void) strcat(line, " "); 102211650Ssam printf("(remote-files) "); 102326497Sminshall (void) gets(&line[strlen(line)]); 102411650Ssam makeargv(); 102511650Ssam argc = margc; 102611650Ssam argv = margv; 102711650Ssam } 102811650Ssam if (argc < 2) { 102926049Sminshall printf("usage:%s remote-files\n", argv[0]); 103026049Sminshall code = -1; 103111650Ssam return; 103211650Ssam } 103326049Sminshall mname = argv[0]; 103426049Sminshall mflag = 1; 103526049Sminshall oldintr = signal(SIGINT, mabort); 103626049Sminshall (void) setjmp(jabort); 103726497Sminshall while ((cp = remglob(argv,0)) != NULL) { 103826049Sminshall if (*cp == '\0') { 103926049Sminshall mflag = 0; 104026049Sminshall continue; 104126049Sminshall } 104226049Sminshall if (mflag && confirm(argv[0], cp)) { 104311650Ssam (void) command("DELE %s", cp); 104426049Sminshall if (!mflag && fromatty) { 104526049Sminshall ointer = interactive; 104626049Sminshall interactive = 1; 104726049Sminshall if (confirm("Continue with", "mdelete")) { 104826049Sminshall mflag++; 104926049Sminshall } 105026049Sminshall interactive = ointer; 105126049Sminshall } 105226049Sminshall } 105326049Sminshall } 105426049Sminshall (void) signal(SIGINT, oldintr); 105526049Sminshall mflag = 0; 105611650Ssam } 105711756Ssam 105811650Ssam /* 105910294Ssam * Rename a remote file. 106010294Ssam */ 106110294Ssam renamefile(argc, argv) 106210294Ssam char *argv[]; 106310294Ssam { 106410294Ssam 106510294Ssam if (argc < 2) { 106626497Sminshall (void) strcat(line, " "); 106710294Ssam printf("(from-name) "); 106826497Sminshall (void) gets(&line[strlen(line)]); 106910294Ssam makeargv(); 107010294Ssam argc = margc; 107110294Ssam argv = margv; 107210294Ssam } 107310294Ssam if (argc < 2) { 107410294Ssam usage: 107510294Ssam printf("%s from-name to-name\n", argv[0]); 107626049Sminshall code = -1; 107710294Ssam return; 107810294Ssam } 107910294Ssam if (argc < 3) { 108026497Sminshall (void) strcat(line, " "); 108110294Ssam printf("(to-name) "); 108226497Sminshall (void) gets(&line[strlen(line)]); 108310294Ssam makeargv(); 108410294Ssam argc = margc; 108510294Ssam argv = margv; 108610294Ssam } 108710294Ssam if (argc < 3) 108810294Ssam goto usage; 108910294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 109010294Ssam (void) command("RNTO %s", argv[2]); 109110294Ssam } 109210294Ssam 109310294Ssam /* 109410294Ssam * Get a directory listing 109510294Ssam * of remote files. 109610294Ssam */ 109710294Ssam ls(argc, argv) 109810294Ssam char *argv[]; 109910294Ssam { 110011756Ssam char *cmd; 110110294Ssam 110210294Ssam if (argc < 2) 110310294Ssam argc++, argv[1] = NULL; 110410294Ssam if (argc < 3) 110510294Ssam argc++, argv[2] = "-"; 110611756Ssam if (argc > 3) { 110711756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 110826049Sminshall code = -1; 110911756Ssam return; 111011756Ssam } 1111*36935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 111226049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 111326049Sminshall code = -1; 111411353Ssam return; 111526049Sminshall } 111632344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 111732344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 111832344Scsvsj code = -1; 111932344Scsvsj return; 112032344Scsvsj } 112111756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 112210294Ssam } 112310294Ssam 112410294Ssam /* 112511756Ssam * Get a directory listing 112611756Ssam * of multiple remote files. 112711756Ssam */ 112811756Ssam mls(argc, argv) 112911756Ssam char *argv[]; 113011756Ssam { 113126049Sminshall char *cmd, mode[1], *dest; 113226049Sminshall int ointer, i, (*oldintr)(), mabort(); 113326049Sminshall extern jmp_buf jabort; 113411756Ssam 113513212Ssam if (argc < 2) { 113626497Sminshall (void) strcat(line, " "); 113713212Ssam printf("(remote-files) "); 113826497Sminshall (void) gets(&line[strlen(line)]); 113913212Ssam makeargv(); 114013212Ssam argc = margc; 114113212Ssam argv = margv; 114213212Ssam } 114313212Ssam if (argc < 3) { 114426497Sminshall (void) strcat(line, " "); 114513212Ssam printf("(local-file) "); 114626497Sminshall (void) gets(&line[strlen(line)]); 114713212Ssam makeargv(); 114813212Ssam argc = margc; 114913212Ssam argv = margv; 115013212Ssam } 115113212Ssam if (argc < 3) { 115226049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 115326049Sminshall code = -1; 115413212Ssam return; 115513212Ssam } 115613212Ssam dest = argv[argc - 1]; 115713212Ssam argv[argc - 1] = NULL; 115826049Sminshall if (strcmp(dest, "-") && *dest != '|') 115926049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 116026049Sminshall code = -1; 116113212Ssam return; 116226049Sminshall } 1163*36935Skarels cmd = argv[0][1] == 'n' ? "NLST" : "LIST"; 116426049Sminshall mname = argv[0]; 116526049Sminshall mflag = 1; 116626049Sminshall oldintr = signal(SIGINT, mabort); 116726049Sminshall (void) setjmp(jabort); 116826049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 116926049Sminshall *mode = (i == 1) ? 'w' : 'a'; 117026049Sminshall recvrequest(cmd, dest, argv[i], mode); 117126049Sminshall if (!mflag && fromatty) { 117226049Sminshall ointer = interactive; 117326049Sminshall interactive = 1; 117426049Sminshall if (confirm("Continue with", argv[0])) { 117526049Sminshall mflag ++; 117626049Sminshall } 117726049Sminshall interactive = ointer; 117826049Sminshall } 117926049Sminshall } 118026049Sminshall (void) signal(SIGINT, oldintr); 118126049Sminshall mflag = 0; 118211756Ssam } 118311756Ssam 118411756Ssam /* 118510294Ssam * Do a shell escape 118610294Ssam */ 118726497Sminshall /*ARGSUSED*/ 118810294Ssam shell(argc, argv) 118910294Ssam char *argv[]; 119010294Ssam { 119126497Sminshall int pid, (*old1)(), (*old2)(); 119226049Sminshall char shellnam[40], *shell, *namep; 119326497Sminshall union wait status; 119410294Ssam 119511756Ssam old1 = signal (SIGINT, SIG_IGN); 119611756Ssam old2 = signal (SIGQUIT, SIG_IGN); 119711756Ssam if ((pid = fork()) == 0) { 119811756Ssam for (pid = 3; pid < 20; pid++) 119926497Sminshall (void) close(pid); 120026497Sminshall (void) signal(SIGINT, SIG_DFL); 120126497Sminshall (void) signal(SIGQUIT, SIG_DFL); 120225908Smckusick shell = getenv("SHELL"); 120325908Smckusick if (shell == NULL) 120425908Smckusick shell = "/bin/sh"; 120525908Smckusick namep = rindex(shell,'/'); 120625908Smckusick if (namep == NULL) 120725908Smckusick namep = shell; 120826497Sminshall (void) strcpy(shellnam,"-"); 120926497Sminshall (void) strcat(shellnam, ++namep); 121026049Sminshall if (strcmp(namep, "sh") != 0) 121126049Sminshall shellnam[0] = '+'; 121226049Sminshall if (debug) { 121326049Sminshall printf ("%s\n", shell); 121426497Sminshall (void) fflush (stdout); 121511756Ssam } 121626049Sminshall if (argc > 1) { 121726049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 121826049Sminshall } 121926049Sminshall else { 122026049Sminshall execl(shell,shellnam,(char *)0); 122126049Sminshall } 122225908Smckusick perror(shell); 122326049Sminshall code = -1; 122411756Ssam exit(1); 122526049Sminshall } 122611756Ssam if (pid > 0) 122711756Ssam while (wait(&status) != pid) 122811756Ssam ; 122926497Sminshall (void) signal(SIGINT, old1); 123026497Sminshall (void) signal(SIGQUIT, old2); 123126049Sminshall if (pid == -1) { 123211756Ssam perror("Try again later"); 123326049Sminshall code = -1; 123426049Sminshall } 123526049Sminshall else { 123626049Sminshall code = 0; 123726049Sminshall } 123811756Ssam return (0); 123910294Ssam } 124010294Ssam 124110294Ssam /* 124210294Ssam * Send new user information (re-login) 124310294Ssam */ 124410294Ssam user(argc, argv) 124510294Ssam int argc; 124610294Ssam char **argv; 124710294Ssam { 124835658Sbostic char acct[80], *getpass(); 124926049Sminshall int n, aflag = 0; 125010294Ssam 125110294Ssam if (argc < 2) { 125226497Sminshall (void) strcat(line, " "); 125310294Ssam printf("(username) "); 125426497Sminshall (void) gets(&line[strlen(line)]); 125510294Ssam makeargv(); 125610294Ssam argc = margc; 125710294Ssam argv = margv; 125810294Ssam } 125910294Ssam if (argc > 4) { 126010294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 126126049Sminshall code = -1; 126211756Ssam return (0); 126310294Ssam } 126410294Ssam n = command("USER %s", argv[1]); 126510294Ssam if (n == CONTINUE) { 126610294Ssam if (argc < 3 ) 126735658Sbostic argv[2] = getpass("Password: "), argc++; 126810294Ssam n = command("PASS %s", argv[2]); 126910294Ssam } 127010294Ssam if (n == CONTINUE) { 127110294Ssam if (argc < 4) { 127210294Ssam printf("Account: "); (void) fflush(stdout); 127310294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 127410294Ssam acct[strlen(acct) - 1] = '\0'; 127510294Ssam argv[3] = acct; argc++; 127610294Ssam } 127726049Sminshall n = command("ACCT %s", argv[3]); 127826049Sminshall aflag++; 127910294Ssam } 128010294Ssam if (n != COMPLETE) { 128126497Sminshall fprintf(stdout, "Login failed.\n"); 128210294Ssam return (0); 128310294Ssam } 128426049Sminshall if (!aflag && argc == 4) { 128526049Sminshall (void) command("ACCT %s", argv[3]); 128626049Sminshall } 128710294Ssam return (1); 128810294Ssam } 128910294Ssam 129010294Ssam /* 129110294Ssam * Print working directory. 129210294Ssam */ 129310294Ssam /*VARARGS*/ 129410294Ssam pwd() 129510294Ssam { 129611756Ssam 129726049Sminshall (void) command("PWD"); 129810294Ssam } 129910294Ssam 130010294Ssam /* 130110294Ssam * Make a directory. 130210294Ssam */ 130310294Ssam makedir(argc, argv) 130410294Ssam char *argv[]; 130510294Ssam { 130610294Ssam 130710294Ssam if (argc < 2) { 130826497Sminshall (void) strcat(line, " "); 130910294Ssam printf("(directory-name) "); 131026497Sminshall (void) gets(&line[strlen(line)]); 131110294Ssam makeargv(); 131210294Ssam argc = margc; 131310294Ssam argv = margv; 131410294Ssam } 131510294Ssam if (argc < 2) { 131626049Sminshall printf("usage: %s directory-name\n", argv[0]); 131726049Sminshall code = -1; 131810294Ssam return; 131910294Ssam } 132026049Sminshall (void) command("MKD %s", argv[1]); 132110294Ssam } 132210294Ssam 132310294Ssam /* 132410294Ssam * Remove a directory. 132510294Ssam */ 132610294Ssam removedir(argc, argv) 132710294Ssam char *argv[]; 132810294Ssam { 132910294Ssam 133010294Ssam if (argc < 2) { 133126497Sminshall (void) strcat(line, " "); 133210294Ssam printf("(directory-name) "); 133326497Sminshall (void) gets(&line[strlen(line)]); 133410294Ssam makeargv(); 133510294Ssam argc = margc; 133610294Ssam argv = margv; 133710294Ssam } 133810294Ssam if (argc < 2) { 133926049Sminshall printf("usage: %s directory-name\n", argv[0]); 134026049Sminshall code = -1; 134110294Ssam return; 134210294Ssam } 134326049Sminshall (void) command("RMD %s", argv[1]); 134410294Ssam } 134510294Ssam 134610294Ssam /* 134710294Ssam * Send a line, verbatim, to the remote machine. 134810294Ssam */ 134910294Ssam quote(argc, argv) 135010294Ssam char *argv[]; 135110294Ssam { 135210294Ssam int i; 135310294Ssam char buf[BUFSIZ]; 135410294Ssam 135510294Ssam if (argc < 2) { 135626497Sminshall (void) strcat(line, " "); 135710294Ssam printf("(command line to send) "); 135826497Sminshall (void) gets(&line[strlen(line)]); 135910294Ssam makeargv(); 136010294Ssam argc = margc; 136110294Ssam argv = margv; 136210294Ssam } 136310294Ssam if (argc < 2) { 136410294Ssam printf("usage: %s line-to-send\n", argv[0]); 136526049Sminshall code = -1; 136610294Ssam return; 136710294Ssam } 136826497Sminshall (void) strcpy(buf, argv[1]); 136910294Ssam for (i = 2; i < argc; i++) { 137026497Sminshall (void) strcat(buf, " "); 137126497Sminshall (void) strcat(buf, argv[i]); 137210294Ssam } 137326049Sminshall if (command(buf) == PRELIM) { 137426049Sminshall while (getreply(0) == PRELIM); 137526049Sminshall } 137610294Ssam } 137710294Ssam 137810294Ssam /* 137910294Ssam * Ask the other side for help. 138010294Ssam */ 138110294Ssam rmthelp(argc, argv) 138210294Ssam char *argv[]; 138310294Ssam { 138410294Ssam int oldverbose = verbose; 138510294Ssam 138610294Ssam verbose = 1; 138710294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 138810294Ssam verbose = oldverbose; 138910294Ssam } 139010294Ssam 139110294Ssam /* 139210294Ssam * Terminate session and exit. 139310294Ssam */ 139410294Ssam /*VARARGS*/ 139510294Ssam quit() 139610294Ssam { 139710294Ssam 139818286Sralph if (connected) 139918286Sralph disconnect(); 140026049Sminshall pswitch(1); 140126049Sminshall if (connected) { 140226049Sminshall disconnect(); 140326049Sminshall } 140410294Ssam exit(0); 140510294Ssam } 140610294Ssam 140710294Ssam /* 140810294Ssam * Terminate session, but don't exit. 140910294Ssam */ 141010294Ssam disconnect() 141110294Ssam { 141210294Ssam extern FILE *cout; 141310294Ssam extern int data; 141410294Ssam 141510294Ssam if (!connected) 141610294Ssam return; 141710294Ssam (void) command("QUIT"); 141826049Sminshall if (cout) { 141926049Sminshall (void) fclose(cout); 142026049Sminshall } 142110294Ssam cout = NULL; 142210294Ssam connected = 0; 142310294Ssam data = -1; 142426049Sminshall if (!proxy) { 142526049Sminshall macnum = 0; 142626049Sminshall } 142710294Ssam } 142811353Ssam 142911650Ssam confirm(cmd, file) 143011353Ssam char *cmd, *file; 143111353Ssam { 143211353Ssam char line[BUFSIZ]; 143311353Ssam 143411353Ssam if (!interactive) 143511650Ssam return (1); 143611353Ssam printf("%s %s? ", cmd, file); 143726497Sminshall (void) fflush(stdout); 143826497Sminshall (void) gets(line); 143911650Ssam return (*line != 'n' && *line != 'N'); 144011353Ssam } 144111353Ssam 144211353Ssam fatal(msg) 144311353Ssam char *msg; 144411353Ssam { 144511353Ssam 144626497Sminshall fprintf(stderr, "ftp: %s\n", msg); 144711353Ssam exit(1); 144811353Ssam } 144911353Ssam 145011353Ssam /* 145111353Ssam * Glob a local file name specification with 145211353Ssam * the expectation of a single return value. 145311353Ssam * Can't control multiple values being expanded 145411353Ssam * from the expression, we return only the first. 145511353Ssam */ 145611353Ssam globulize(cpp) 145711353Ssam char **cpp; 145811353Ssam { 145911353Ssam char **globbed; 146011353Ssam 146111353Ssam if (!doglob) 146211353Ssam return (1); 146311353Ssam globbed = glob(*cpp); 146411353Ssam if (globerr != NULL) { 146511353Ssam printf("%s: %s\n", *cpp, globerr); 146636421Sbostic if (globbed) { 146711353Ssam blkfree(globbed); 146836421Sbostic free(globbed); 146936421Sbostic } 147011353Ssam return (0); 147111353Ssam } 147211353Ssam if (globbed) { 147311353Ssam *cpp = *globbed++; 147411353Ssam /* don't waste too much memory */ 147536421Sbostic if (*globbed) { 147611353Ssam blkfree(globbed); 147736421Sbostic free(globbed); 147836421Sbostic } 147911353Ssam } 148011353Ssam return (1); 148111353Ssam } 148226049Sminshall 148326049Sminshall account(argc,argv) 148426049Sminshall int argc; 148526049Sminshall char **argv; 148626049Sminshall { 148735658Sbostic char acct[50], *getpass(), *ap; 148826049Sminshall 148926049Sminshall if (argc > 1) { 149026049Sminshall ++argv; 149126049Sminshall --argc; 149226049Sminshall (void) strncpy(acct,*argv,49); 149336268Sbostic acct[49] = '\0'; 149426049Sminshall while (argc > 1) { 149526049Sminshall --argc; 149626049Sminshall ++argv; 149726049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 149826049Sminshall } 149926049Sminshall ap = acct; 150026049Sminshall } 150126049Sminshall else { 150235658Sbostic ap = getpass("Account:"); 150326049Sminshall } 150426049Sminshall (void) command("ACCT %s", ap); 150526049Sminshall } 150626049Sminshall 150726049Sminshall jmp_buf abortprox; 150826049Sminshall 150926049Sminshall proxabort() 151026049Sminshall { 151126049Sminshall extern int proxy; 151226049Sminshall 151326049Sminshall if (!proxy) { 151426049Sminshall pswitch(1); 151526049Sminshall } 151626049Sminshall if (connected) { 151726049Sminshall proxflag = 1; 151826049Sminshall } 151926049Sminshall else { 152026049Sminshall proxflag = 0; 152126049Sminshall } 152226049Sminshall pswitch(0); 152326049Sminshall longjmp(abortprox,1); 152426049Sminshall } 152526049Sminshall 152626049Sminshall doproxy(argc,argv) 152726049Sminshall int argc; 152826049Sminshall char *argv[]; 152926049Sminshall { 153026049Sminshall int (*oldintr)(), proxabort(); 153126049Sminshall register struct cmd *c; 153226049Sminshall struct cmd *getcmd(); 153326049Sminshall extern struct cmd cmdtab[]; 153426049Sminshall extern jmp_buf abortprox; 153526049Sminshall 153626049Sminshall if (argc < 2) { 153726497Sminshall (void) strcat(line, " "); 153826049Sminshall printf("(command) "); 153926497Sminshall (void) gets(&line[strlen(line)]); 154026049Sminshall makeargv(); 154126049Sminshall argc = margc; 154226049Sminshall argv = margv; 154326049Sminshall } 154426049Sminshall if (argc < 2) { 154526049Sminshall printf("usage:%s command\n", argv[0]); 154626049Sminshall code = -1; 154726049Sminshall return; 154826049Sminshall } 154926049Sminshall c = getcmd(argv[1]); 155026049Sminshall if (c == (struct cmd *) -1) { 155126049Sminshall printf("?Ambiguous command\n"); 155226497Sminshall (void) fflush(stdout); 155326049Sminshall code = -1; 155426049Sminshall return; 155526049Sminshall } 155626049Sminshall if (c == 0) { 155726049Sminshall printf("?Invalid command\n"); 155826497Sminshall (void) fflush(stdout); 155926049Sminshall code = -1; 156026049Sminshall return; 156126049Sminshall } 156226049Sminshall if (!c->c_proxy) { 156326049Sminshall printf("?Invalid proxy command\n"); 156426497Sminshall (void) fflush(stdout); 156526049Sminshall code = -1; 156626049Sminshall return; 156726049Sminshall } 156826049Sminshall if (setjmp(abortprox)) { 156926049Sminshall code = -1; 157026049Sminshall return; 157126049Sminshall } 157226049Sminshall oldintr = signal(SIGINT, proxabort); 157326049Sminshall pswitch(1); 157426049Sminshall if (c->c_conn && !connected) { 157526049Sminshall printf("Not connected\n"); 157626497Sminshall (void) fflush(stdout); 157726049Sminshall pswitch(0); 157826049Sminshall (void) signal(SIGINT, oldintr); 157926049Sminshall code = -1; 158026049Sminshall return; 158126049Sminshall } 158226049Sminshall (*c->c_handler)(argc-1, argv+1); 158326049Sminshall if (connected) { 158426049Sminshall proxflag = 1; 158526049Sminshall } 158626049Sminshall else { 158726049Sminshall proxflag = 0; 158826049Sminshall } 158926049Sminshall pswitch(0); 159026049Sminshall (void) signal(SIGINT, oldintr); 159126049Sminshall } 159226049Sminshall 159326049Sminshall setcase() 159426049Sminshall { 159526049Sminshall mcase = !mcase; 159626049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 159726049Sminshall code = mcase; 159826049Sminshall } 159926049Sminshall 160026049Sminshall setcr() 160126049Sminshall { 160226049Sminshall crflag = !crflag; 160326049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 160426049Sminshall code = crflag; 160526049Sminshall } 160626049Sminshall 160726049Sminshall setntrans(argc,argv) 160826049Sminshall int argc; 160926049Sminshall char *argv[]; 161026049Sminshall { 161126049Sminshall if (argc == 1) { 161226049Sminshall ntflag = 0; 161326049Sminshall printf("Ntrans off.\n"); 161426049Sminshall code = ntflag; 161526049Sminshall return; 161626049Sminshall } 161726049Sminshall ntflag++; 161826049Sminshall code = ntflag; 161926049Sminshall (void) strncpy(ntin, argv[1], 16); 162026049Sminshall ntin[16] = '\0'; 162126049Sminshall if (argc == 2) { 162226049Sminshall ntout[0] = '\0'; 162326049Sminshall return; 162426049Sminshall } 162526049Sminshall (void) strncpy(ntout, argv[2], 16); 162626049Sminshall ntout[16] = '\0'; 162726049Sminshall } 162826049Sminshall 162926049Sminshall char * 163026049Sminshall dotrans(name) 163126049Sminshall char *name; 163226049Sminshall { 163326049Sminshall static char new[MAXPATHLEN]; 163426049Sminshall char *cp1, *cp2 = new; 163526049Sminshall register int i, ostop, found; 163626049Sminshall 163726049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 163826049Sminshall for (cp1 = name; *cp1; cp1++) { 163926049Sminshall found = 0; 164026049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 164126049Sminshall if (*cp1 == *(ntin + i)) { 164226049Sminshall found++; 164326049Sminshall if (i < ostop) { 164426049Sminshall *cp2++ = *(ntout + i); 164526049Sminshall } 164626049Sminshall break; 164726049Sminshall } 164826049Sminshall } 164926049Sminshall if (!found) { 165026049Sminshall *cp2++ = *cp1; 165126049Sminshall } 165226049Sminshall } 165326049Sminshall *cp2 = '\0'; 165426049Sminshall return(new); 165526049Sminshall } 165626049Sminshall 165726049Sminshall setnmap(argc, argv) 165826049Sminshall int argc; 165926049Sminshall char *argv[]; 166026049Sminshall { 166126049Sminshall char *cp; 166226049Sminshall 166326049Sminshall if (argc == 1) { 166426049Sminshall mapflag = 0; 166526049Sminshall printf("Nmap off.\n"); 166626049Sminshall code = mapflag; 166726049Sminshall return; 166826049Sminshall } 166926049Sminshall if (argc < 3) { 167026497Sminshall (void) strcat(line, " "); 167126049Sminshall printf("(mapout) "); 167226497Sminshall (void) gets(&line[strlen(line)]); 167326049Sminshall makeargv(); 167426049Sminshall argc = margc; 167526049Sminshall argv = margv; 167626049Sminshall } 167726049Sminshall if (argc < 3) { 167826049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 167926049Sminshall code = -1; 168026049Sminshall return; 168126049Sminshall } 168226049Sminshall mapflag = 1; 168326049Sminshall code = 1; 168426049Sminshall cp = index(altarg, ' '); 168526049Sminshall if (proxy) { 168626049Sminshall while(*++cp == ' '); 168726049Sminshall altarg = cp; 168826049Sminshall cp = index(altarg, ' '); 168926049Sminshall } 169026049Sminshall *cp = '\0'; 169126049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 169226049Sminshall while (*++cp == ' '); 169326049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 169426049Sminshall } 169526049Sminshall 169626049Sminshall char * 169726049Sminshall domap(name) 169826049Sminshall char *name; 169926049Sminshall { 170026049Sminshall static char new[MAXPATHLEN]; 170126049Sminshall register char *cp1 = name, *cp2 = mapin; 170226049Sminshall char *tp[9], *te[9]; 170336689Scsvsj int i, toks[9], toknum = 0, match = 1; 170426049Sminshall 170526049Sminshall for (i=0; i < 9; ++i) { 170626049Sminshall toks[i] = 0; 170726049Sminshall } 170826049Sminshall while (match && *cp1 && *cp2) { 170926049Sminshall switch (*cp2) { 171026049Sminshall case '\\': 171126049Sminshall if (*++cp2 != *cp1) { 171226049Sminshall match = 0; 171326049Sminshall } 171426049Sminshall break; 171526049Sminshall case '$': 171626049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 171726049Sminshall if (*cp1 != *(++cp2+1)) { 171826049Sminshall toks[toknum = *cp2 - '1']++; 171926049Sminshall tp[toknum] = cp1; 172026049Sminshall while (*++cp1 && *(cp2+1) 172126049Sminshall != *cp1); 172226049Sminshall te[toknum] = cp1; 172326049Sminshall } 172426049Sminshall cp2++; 172526049Sminshall break; 172626049Sminshall } 1727*36935Skarels /* FALLTHROUGH */ 172826049Sminshall default: 172926049Sminshall if (*cp2 != *cp1) { 173026049Sminshall match = 0; 173126049Sminshall } 173226049Sminshall break; 173326049Sminshall } 173436689Scsvsj if (match && *cp1) { 173526049Sminshall cp1++; 173626049Sminshall } 173736689Scsvsj if (match && *cp2) { 173826049Sminshall cp2++; 173926049Sminshall } 174026049Sminshall } 174136689Scsvsj if (!match && *cp1) /* last token mismatch */ 174236689Scsvsj { 174336689Scsvsj toks[toknum] = 0; 174436689Scsvsj } 174526049Sminshall cp1 = new; 174626049Sminshall *cp1 = '\0'; 174726049Sminshall cp2 = mapout; 174826049Sminshall while (*cp2) { 174926049Sminshall match = 0; 175026049Sminshall switch (*cp2) { 175126049Sminshall case '\\': 175226049Sminshall if (*(cp2 + 1)) { 175326049Sminshall *cp1++ = *++cp2; 175426049Sminshall } 175526049Sminshall break; 175626049Sminshall case '[': 175726049Sminshall LOOP: 175826049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 175926049Sminshall if (*++cp2 == '0') { 176026049Sminshall char *cp3 = name; 176126049Sminshall 176226049Sminshall while (*cp3) { 176326049Sminshall *cp1++ = *cp3++; 176426049Sminshall } 176526049Sminshall match = 1; 176626049Sminshall } 176726049Sminshall else if (toks[toknum = *cp2 - '1']) { 176826049Sminshall char *cp3 = tp[toknum]; 176926049Sminshall 177026049Sminshall while (cp3 != te[toknum]) { 177126049Sminshall *cp1++ = *cp3++; 177226049Sminshall } 177326049Sminshall match = 1; 177426049Sminshall } 177526049Sminshall } 177626049Sminshall else { 177726049Sminshall while (*cp2 && *cp2 != ',' && 177826049Sminshall *cp2 != ']') { 177926049Sminshall if (*cp2 == '\\') { 178026049Sminshall cp2++; 178126049Sminshall } 178226049Sminshall else if (*cp2 == '$' && 178326049Sminshall isdigit(*(cp2+1))) { 178426049Sminshall if (*++cp2 == '0') { 178526049Sminshall char *cp3 = name; 178626049Sminshall 178726049Sminshall while (*cp3) { 178826049Sminshall *cp1++ = *cp3++; 178926049Sminshall } 179026049Sminshall } 179126049Sminshall else if (toks[toknum = 179226049Sminshall *cp2 - '1']) { 179326049Sminshall char *cp3=tp[toknum]; 179426049Sminshall 179526049Sminshall while (cp3 != 179626049Sminshall te[toknum]) { 179726049Sminshall *cp1++ = *cp3++; 179826049Sminshall } 179926049Sminshall } 180026049Sminshall } 180126049Sminshall else if (*cp2) { 180226049Sminshall *cp1++ = *cp2++; 180326049Sminshall } 180426049Sminshall } 180526049Sminshall if (!*cp2) { 180626049Sminshall printf("nmap: unbalanced brackets\n"); 180726049Sminshall return(name); 180826049Sminshall } 180926049Sminshall match = 1; 181026049Sminshall cp2--; 181126049Sminshall } 181226049Sminshall if (match) { 181326049Sminshall while (*++cp2 && *cp2 != ']') { 181426049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 181526049Sminshall cp2++; 181626049Sminshall } 181726049Sminshall } 181826049Sminshall if (!*cp2) { 181926049Sminshall printf("nmap: unbalanced brackets\n"); 182026049Sminshall return(name); 182126049Sminshall } 182226049Sminshall break; 182326049Sminshall } 182426049Sminshall switch (*++cp2) { 182526049Sminshall case ',': 182626049Sminshall goto LOOP; 182726049Sminshall case ']': 182826049Sminshall break; 182926049Sminshall default: 183026049Sminshall cp2--; 183126049Sminshall goto LOOP; 183226049Sminshall } 183326049Sminshall break; 183426049Sminshall case '$': 183526049Sminshall if (isdigit(*(cp2 + 1))) { 183626049Sminshall if (*++cp2 == '0') { 183726049Sminshall char *cp3 = name; 183826049Sminshall 183926049Sminshall while (*cp3) { 184026049Sminshall *cp1++ = *cp3++; 184126049Sminshall } 184226049Sminshall } 184326049Sminshall else if (toks[toknum = *cp2 - '1']) { 184426049Sminshall char *cp3 = tp[toknum]; 184526049Sminshall 184626049Sminshall while (cp3 != te[toknum]) { 184726049Sminshall *cp1++ = *cp3++; 184826049Sminshall } 184926049Sminshall } 185026049Sminshall break; 185126049Sminshall } 185226049Sminshall /* intentional drop through */ 185326049Sminshall default: 185426049Sminshall *cp1++ = *cp2; 185526049Sminshall break; 185626049Sminshall } 185726049Sminshall cp2++; 185826049Sminshall } 185926049Sminshall *cp1 = '\0'; 186026049Sminshall if (!*new) { 186126049Sminshall return(name); 186226049Sminshall } 186326049Sminshall return(new); 186426049Sminshall } 186526049Sminshall 186626049Sminshall setsunique() 186726049Sminshall { 186826049Sminshall sunique = !sunique; 186926049Sminshall printf("Store unique %s.\n", onoff(sunique)); 187026049Sminshall code = sunique; 187126049Sminshall } 187226049Sminshall 187326049Sminshall setrunique() 187426049Sminshall { 187526049Sminshall runique = !runique; 187626049Sminshall printf("Receive unique %s.\n", onoff(runique)); 187726049Sminshall code = runique; 187826049Sminshall } 187926049Sminshall 188026049Sminshall /* change directory to perent directory */ 188126049Sminshall cdup() 188226049Sminshall { 188326049Sminshall (void) command("CDUP"); 188426049Sminshall } 188526049Sminshall 1886*36935Skarels /* restart transfer at specific point */ 1887*36935Skarels restart(argc, argv) 1888*36935Skarels int argc; 1889*36935Skarels char *argv[]; 1890*36935Skarels { 1891*36935Skarels extern long atol(); 1892*36935Skarels if (argc != 2) 1893*36935Skarels printf("restart: offset not specified\n"); 1894*36935Skarels else { 1895*36935Skarels restart_point = atol(argv[1]); 1896*36935Skarels printf("restarting at %ld. execute get, put or append to initiate transfer\n", 1897*36935Skarels restart_point); 1898*36935Skarels } 1899*36935Skarels } 1900*36935Skarels 1901*36935Skarels /* show remote system type */ 1902*36935Skarels syst() 1903*36935Skarels { 1904*36935Skarels (void) command("SYST"); 1905*36935Skarels } 1906*36935Skarels 190726049Sminshall macdef(argc, argv) 190826049Sminshall int argc; 190926049Sminshall char *argv[]; 191026049Sminshall { 191126049Sminshall char *tmp; 191226049Sminshall int c; 191326049Sminshall 191426049Sminshall if (macnum == 16) { 191526049Sminshall printf("Limit of 16 macros have already been defined\n"); 191626049Sminshall code = -1; 191726049Sminshall return; 191826049Sminshall } 191926049Sminshall if (argc < 2) { 192026497Sminshall (void) strcat(line, " "); 192126049Sminshall printf("(macro name) "); 192226497Sminshall (void) gets(&line[strlen(line)]); 192326049Sminshall makeargv(); 192426049Sminshall argc = margc; 192526049Sminshall argv = margv; 192626049Sminshall } 192726049Sminshall if (argc != 2) { 192826049Sminshall printf("Usage: %s macro_name\n",argv[0]); 192926049Sminshall code = -1; 193026049Sminshall return; 193126049Sminshall } 193226049Sminshall if (interactive) { 193326049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 193426049Sminshall } 193526497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 193626049Sminshall if (macnum == 0) { 193726049Sminshall macros[macnum].mac_start = macbuf; 193826049Sminshall } 193926049Sminshall else { 194026049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 194126049Sminshall } 194226049Sminshall tmp = macros[macnum].mac_start; 194326049Sminshall while (tmp != macbuf+4096) { 194426049Sminshall if ((c = getchar()) == EOF) { 194526049Sminshall printf("macdef:end of file encountered\n"); 194626049Sminshall code = -1; 194726049Sminshall return; 194826049Sminshall } 194926049Sminshall if ((*tmp = c) == '\n') { 195026049Sminshall if (tmp == macros[macnum].mac_start) { 195126049Sminshall macros[macnum++].mac_end = tmp; 195226049Sminshall code = 0; 195326049Sminshall return; 195426049Sminshall } 195526049Sminshall if (*(tmp-1) == '\0') { 195626049Sminshall macros[macnum++].mac_end = tmp - 1; 195726049Sminshall code = 0; 195826049Sminshall return; 195926049Sminshall } 196026049Sminshall *tmp = '\0'; 196126049Sminshall } 196226049Sminshall tmp++; 196326049Sminshall } 196426049Sminshall while (1) { 1965*36935Skarels while ((c = getchar()) != '\n' && c != EOF) 1966*36935Skarels /* LOOP */; 196726049Sminshall if (c == EOF || getchar() == '\n') { 196826049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 196926049Sminshall code = -1; 197026049Sminshall return; 197126049Sminshall } 197226049Sminshall } 197326049Sminshall } 1974*36935Skarels 1975*36935Skarels /* 1976*36935Skarels * get size of file on remote machine 1977*36935Skarels */ 1978*36935Skarels sizecmd(argc, argv) 1979*36935Skarels char *argv[]; 1980*36935Skarels { 1981*36935Skarels 1982*36935Skarels if (argc < 2) { 1983*36935Skarels (void) strcat(line, " "); 1984*36935Skarels printf("(filename) "); 1985*36935Skarels (void) gets(&line[strlen(line)]); 1986*36935Skarels makeargv(); 1987*36935Skarels argc = margc; 1988*36935Skarels argv = margv; 1989*36935Skarels } 1990*36935Skarels if (argc < 2) { 1991*36935Skarels printf("usage:%s filename\n", argv[0]); 1992*36935Skarels code = -1; 1993*36935Skarels return; 1994*36935Skarels } 1995*36935Skarels (void) command("SIZE %s", argv[1]); 1996*36935Skarels } 1997*36935Skarels 1998*36935Skarels /* 1999*36935Skarels * get last modification time of file on remote machine 2000*36935Skarels */ 2001*36935Skarels modtime(argc, argv) 2002*36935Skarels char *argv[]; 2003*36935Skarels { 2004*36935Skarels int overbose; 2005*36935Skarels 2006*36935Skarels if (argc < 2) { 2007*36935Skarels (void) strcat(line, " "); 2008*36935Skarels printf("(filename) "); 2009*36935Skarels (void) gets(&line[strlen(line)]); 2010*36935Skarels makeargv(); 2011*36935Skarels argc = margc; 2012*36935Skarels argv = margv; 2013*36935Skarels } 2014*36935Skarels if (argc < 2) { 2015*36935Skarels printf("usage:%s filename\n", argv[0]); 2016*36935Skarels code = -1; 2017*36935Skarels return; 2018*36935Skarels } 2019*36935Skarels overbose = verbose; verbose = -1; 2020*36935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 2021*36935Skarels int yy, mo, day, hour, min, sec; 2022*36935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 2023*36935Skarels &day, &hour, &min, &sec); 2024*36935Skarels /* might want to print this in local time */ 2025*36935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 2026*36935Skarels mo, day, yy, hour, min, sec); 2027*36935Skarels } else 2028*36935Skarels fputs(reply_string, stdout); 2029*36935Skarels verbose = overbose; 2030*36935Skarels } 2031*36935Skarels 2032*36935Skarels /* 2033*36935Skarels * show status on reomte machine 2034*36935Skarels */ 2035*36935Skarels rmtstatus(argc, argv) 2036*36935Skarels char *argv[]; 2037*36935Skarels { 2038*36935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 2039*36935Skarels } 2040*36935Skarels 2041*36935Skarels /* 2042*36935Skarels * get file if modtime is more recent than current file 2043*36935Skarels */ 2044*36935Skarels newer(argc, argv) 2045*36935Skarels char *argv[]; 2046*36935Skarels { 2047*36935Skarels if (getit(argc, argv, -1, "w")) 2048*36935Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 2049*36935Skarels argv[1], argv[2]); 2050*36935Skarels } 2051