121737Sdist /* 226049Sminshall * Copyright (c) 1985 Regents of the University of California. 321737Sdist * All rights reserved. The Berkeley software License Agreement 421737Sdist * specifies the terms and conditions for redistribution. 521737Sdist */ 621737Sdist 710294Ssam #ifndef lint 8*32344Scsvsj static char sccsid[] = "@(#)cmds.c 5.6 (Berkeley) 10/06/87"; 921737Sdist #endif not lint 1010294Ssam 1110294Ssam /* 1210294Ssam * FTP User Program -- Command Routines. 1310294Ssam */ 1426049Sminshall #include "ftp_var.h" 1510294Ssam #include <sys/socket.h> 1610294Ssam 1712396Ssam #include <arpa/ftp.h> 1812396Ssam 1910294Ssam #include <signal.h> 2010294Ssam #include <stdio.h> 2110294Ssam #include <errno.h> 2210294Ssam #include <netdb.h> 2326049Sminshall #include <ctype.h> 2426497Sminshall #include <sys/wait.h> 2510294Ssam 2610294Ssam 2711353Ssam extern char *globerr; 2811353Ssam extern char **glob(); 2911756Ssam extern char *home; 3011353Ssam extern short gflag; 3111756Ssam extern char *remglob(); 3211756Ssam extern char *getenv(); 3311756Ssam extern char *index(); 3411756Ssam extern char *rindex(); 3526049Sminshall char *mname; 3626049Sminshall jmp_buf jabort; 3726049Sminshall char *dotrans(), *domap(); 3810294Ssam 3910294Ssam /* 4010294Ssam * Connect to peer server and 4110294Ssam * auto-login, if possible. 4210294Ssam */ 4310294Ssam setpeer(argc, argv) 4410294Ssam int argc; 4510294Ssam char *argv[]; 4610294Ssam { 4725903Skarels char *host, *hookup(); 4810294Ssam int port; 4910294Ssam 5010294Ssam if (connected) { 5126049Sminshall printf("Already connected to %s, use close first.\n", 5210294Ssam hostname); 5326049Sminshall code = -1; 5410294Ssam return; 5510294Ssam } 5610294Ssam if (argc < 2) { 5726497Sminshall (void) strcat(line, " "); 5810294Ssam printf("(to) "); 5926497Sminshall (void) gets(&line[strlen(line)]); 6010294Ssam makeargv(); 6110294Ssam argc = margc; 6210294Ssam argv = margv; 6310294Ssam } 6410294Ssam if (argc > 3) { 6510294Ssam printf("usage: %s host-name [port]\n", argv[0]); 6626049Sminshall code = -1; 6710294Ssam return; 6810294Ssam } 6910294Ssam port = sp->s_port; 7010294Ssam if (argc > 2) { 7111218Ssam port = atoi(argv[2]); 7210294Ssam if (port <= 0) { 7311218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 7411218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 7526049Sminshall code = -1; 7610294Ssam return; 7710294Ssam } 7810294Ssam port = htons(port); 7910294Ssam } 8010294Ssam host = hookup(argv[1], port); 8110294Ssam if (host) { 8210294Ssam connected = 1; 8310294Ssam if (autologin) 8426497Sminshall (void) login(argv[1]); 8510294Ssam } 8610294Ssam } 8710294Ssam 8810294Ssam struct types { 8910294Ssam char *t_name; 9010294Ssam char *t_mode; 9110294Ssam int t_type; 9211218Ssam char *t_arg; 9310294Ssam } types[] = { 9411218Ssam { "ascii", "A", TYPE_A, 0 }, 9511218Ssam { "binary", "I", TYPE_I, 0 }, 9611218Ssam { "image", "I", TYPE_I, 0 }, 9711218Ssam { "ebcdic", "E", TYPE_E, 0 }, 9811218Ssam { "tenex", "L", TYPE_L, bytename }, 9910294Ssam 0 10010294Ssam }; 10110294Ssam 10210294Ssam /* 10310294Ssam * Set transfer type. 10410294Ssam */ 10510294Ssam settype(argc, argv) 10610294Ssam char *argv[]; 10710294Ssam { 10810294Ssam register struct types *p; 10911218Ssam int comret; 11010294Ssam 11110294Ssam if (argc > 2) { 11210294Ssam char *sep; 11310294Ssam 11410294Ssam printf("usage: %s [", argv[0]); 11510294Ssam sep = " "; 11610294Ssam for (p = types; p->t_name; p++) { 11710294Ssam printf("%s%s", sep, p->t_name); 11810294Ssam if (*sep == ' ') 11910294Ssam sep = " | "; 12010294Ssam } 12110294Ssam printf(" ]\n"); 12226049Sminshall code = -1; 12310294Ssam return; 12410294Ssam } 12510294Ssam if (argc < 2) { 12610294Ssam printf("Using %s mode to transfer files.\n", typename); 12726049Sminshall code = 0; 12810294Ssam return; 12910294Ssam } 13010294Ssam for (p = types; p->t_name; p++) 13110294Ssam if (strcmp(argv[1], p->t_name) == 0) 13210294Ssam break; 13310294Ssam if (p->t_name == 0) { 13410294Ssam printf("%s: unknown mode\n", argv[1]); 13526049Sminshall code = -1; 13610294Ssam return; 13710294Ssam } 13811218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 13911218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 14011218Ssam else 14111218Ssam comret = command("TYPE %s", p->t_mode); 14211218Ssam if (comret == COMPLETE) { 14326497Sminshall (void) strcpy(typename, p->t_name); 14410294Ssam type = p->t_type; 14510294Ssam } 14610294Ssam } 14710294Ssam 14810294Ssam /* 14910294Ssam * Set binary transfer type. 15010294Ssam */ 15110294Ssam /*VARARGS*/ 15210294Ssam setbinary() 15310294Ssam { 15410294Ssam 15510294Ssam call(settype, "type", "binary", 0); 15610294Ssam } 15710294Ssam 15810294Ssam /* 15910294Ssam * Set ascii transfer type. 16010294Ssam */ 16110294Ssam /*VARARGS*/ 16210294Ssam setascii() 16310294Ssam { 16410294Ssam 16510294Ssam call(settype, "type", "ascii", 0); 16610294Ssam } 16710294Ssam 16810294Ssam /* 16910294Ssam * Set tenex transfer type. 17010294Ssam */ 17110294Ssam /*VARARGS*/ 17210294Ssam settenex() 17310294Ssam { 17410294Ssam 17510294Ssam call(settype, "type", "tenex", 0); 17610294Ssam } 17710294Ssam 17810294Ssam /* 17910294Ssam * Set ebcdic transfer type. 18010294Ssam */ 18110294Ssam /*VARARGS*/ 18210294Ssam setebcdic() 18310294Ssam { 18410294Ssam 18510294Ssam call(settype, "type", "ebcdic", 0); 18610294Ssam } 18710294Ssam 18810294Ssam /* 18910294Ssam * Set file transfer mode. 19010294Ssam */ 19126497Sminshall /*ARGSUSED*/ 19210294Ssam setmode(argc, argv) 19310294Ssam char *argv[]; 19410294Ssam { 19510294Ssam 19610294Ssam printf("We only support %s mode, sorry.\n", modename); 19726049Sminshall code = -1; 19810294Ssam } 19910294Ssam 20010294Ssam /* 20110294Ssam * Set file transfer format. 20210294Ssam */ 20326497Sminshall /*ARGSUSED*/ 20410294Ssam setform(argc, argv) 20510294Ssam char *argv[]; 20610294Ssam { 20710294Ssam 20810294Ssam printf("We only support %s format, sorry.\n", formname); 20926049Sminshall code = -1; 21010294Ssam } 21110294Ssam 21210294Ssam /* 21310294Ssam * Set file transfer structure. 21410294Ssam */ 21526497Sminshall /*ARGSUSED*/ 21610294Ssam setstruct(argc, argv) 21710294Ssam char *argv[]; 21810294Ssam { 21910294Ssam 22010294Ssam printf("We only support %s structure, sorry.\n", structname); 22126049Sminshall code = -1; 22210294Ssam } 22310294Ssam 22418286Sralph /* 22518286Sralph * Send a single file. 22618286Sralph */ 22710294Ssam put(argc, argv) 22811756Ssam int argc; 22910294Ssam char *argv[]; 23010294Ssam { 23111650Ssam char *cmd; 23226049Sminshall int loc = 0; 23325908Smckusick char *oldargv1; 23411650Ssam 23526049Sminshall if (argc == 2) { 23626049Sminshall argc++; 23726049Sminshall argv[2] = argv[1]; 23826049Sminshall loc++; 23926049Sminshall } 24010294Ssam if (argc < 2) { 24126497Sminshall (void) strcat(line, " "); 24210294Ssam printf("(local-file) "); 24326497Sminshall (void) gets(&line[strlen(line)]); 24410294Ssam makeargv(); 24510294Ssam argc = margc; 24610294Ssam argv = margv; 24710294Ssam } 24810294Ssam if (argc < 2) { 24910294Ssam usage: 25026049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 25126049Sminshall code = -1; 25210294Ssam return; 25310294Ssam } 25410294Ssam if (argc < 3) { 25526497Sminshall (void) strcat(line, " "); 25610294Ssam printf("(remote-file) "); 25726497Sminshall (void) gets(&line[strlen(line)]); 25810294Ssam makeargv(); 25910294Ssam argc = margc; 26010294Ssam argv = margv; 26110294Ssam } 26210294Ssam if (argc < 3) 26310294Ssam goto usage; 26425908Smckusick oldargv1 = argv[1]; 26526049Sminshall if (!globulize(&argv[1])) { 26626049Sminshall code = -1; 26711353Ssam return; 26826049Sminshall } 26925908Smckusick /* 27025908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 27125908Smckusick * the old argv[1], make it a copy of the new argv[1]. 27225908Smckusick */ 27326049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 27425908Smckusick argv[2] = argv[1]; 27526049Sminshall } 27626049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 27726049Sminshall if (loc && ntflag) { 27826049Sminshall argv[2] = dotrans(argv[2]); 27926049Sminshall } 28026049Sminshall if (loc && mapflag) { 28126049Sminshall argv[2] = domap(argv[2]); 28226049Sminshall } 28311650Ssam sendrequest(cmd, argv[1], argv[2]); 28410294Ssam } 28510294Ssam 28610294Ssam /* 28711756Ssam * Send multiple files. 28810294Ssam */ 28911353Ssam mput(argc, argv) 29011353Ssam char *argv[]; 29111353Ssam { 29213212Ssam register int i; 29326049Sminshall int ointer, (*oldintr)(), mabort(); 29426049Sminshall extern jmp_buf jabort; 29526049Sminshall char *tp; 29611353Ssam 29711650Ssam if (argc < 2) { 29826497Sminshall (void) strcat(line, " "); 29911650Ssam printf("(local-files) "); 30026497Sminshall (void) gets(&line[strlen(line)]); 30111650Ssam makeargv(); 30211650Ssam argc = margc; 30311650Ssam argv = margv; 30411353Ssam } 30511353Ssam if (argc < 2) { 30626049Sminshall printf("usage:%s local-files\n", argv[0]); 30726049Sminshall code = -1; 30811353Ssam return; 30911353Ssam } 31026049Sminshall mname = argv[0]; 31126049Sminshall mflag = 1; 31226049Sminshall oldintr = signal(SIGINT, mabort); 31326049Sminshall (void) setjmp(jabort); 31426049Sminshall if (proxy) { 31526049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 31626049Sminshall 31726497Sminshall while ((cp = remglob(argv,0)) != NULL) { 31826049Sminshall if (*cp == 0) { 31926049Sminshall mflag = 0; 32026049Sminshall continue; 32126049Sminshall } 32226049Sminshall if (mflag && confirm(argv[0], cp)) { 32326049Sminshall tp = cp; 32426049Sminshall if (mcase) { 32526049Sminshall while (*tp && !islower(*tp)) { 32626049Sminshall tp++; 32726049Sminshall } 32826049Sminshall if (!*tp) { 32926049Sminshall tp = cp; 33026049Sminshall tp2 = tmpbuf; 33126049Sminshall while ((*tp2 = *tp) != NULL) { 33226049Sminshall if (isupper(*tp2)) { 33326049Sminshall *tp2 = 'a' + *tp2 - 'A'; 33426049Sminshall } 33526049Sminshall tp++; 33626049Sminshall tp2++; 33726049Sminshall } 33826049Sminshall } 33926049Sminshall tp = tmpbuf; 34026049Sminshall } 34126049Sminshall if (ntflag) { 34226049Sminshall tp = dotrans(tp); 34326049Sminshall } 34426049Sminshall if (mapflag) { 34526049Sminshall tp = domap(tp); 34626049Sminshall } 34726049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 34826049Sminshall if (!mflag && fromatty) { 34926049Sminshall ointer = interactive; 35026049Sminshall interactive = 1; 35126049Sminshall if (confirm("Continue with","mput")) { 35226049Sminshall mflag++; 35326049Sminshall } 35426049Sminshall interactive = ointer; 35526049Sminshall } 35626049Sminshall } 35726049Sminshall } 35826049Sminshall (void) signal(SIGINT, oldintr); 35926049Sminshall mflag = 0; 36026049Sminshall return; 36126049Sminshall } 36213212Ssam for (i = 1; i < argc; i++) { 36313212Ssam register char **cpp, **gargs; 36413212Ssam 36513212Ssam if (!doglob) { 36626049Sminshall if (mflag && confirm(argv[0], argv[i])) { 36726049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 36826049Sminshall tp = (mapflag) ? domap(tp) : tp; 36926049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 37026049Sminshall argv[i], tp); 37126049Sminshall if (!mflag && fromatty) { 37226049Sminshall ointer = interactive; 37326049Sminshall interactive = 1; 37426049Sminshall if (confirm("Continue with","mput")) { 37526049Sminshall mflag++; 37626049Sminshall } 37726049Sminshall interactive = ointer; 37826049Sminshall } 37926049Sminshall } 38013212Ssam continue; 38113212Ssam } 38213212Ssam gargs = glob(argv[i]); 38311650Ssam if (globerr != NULL) { 38411650Ssam printf("%s\n", globerr); 38511650Ssam if (gargs) 38611650Ssam blkfree(gargs); 38713212Ssam continue; 38811353Ssam } 38926049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 39026049Sminshall if (mflag && confirm(argv[0], *cpp)) { 39126049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 39226049Sminshall tp = (mapflag) ? domap(tp) : tp; 39326049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 39426049Sminshall *cpp, tp); 39526049Sminshall if (!mflag && fromatty) { 39626049Sminshall ointer = interactive; 39726049Sminshall interactive = 1; 39826049Sminshall if (confirm("Continue with","mput")) { 39926049Sminshall mflag++; 40026049Sminshall } 40126049Sminshall interactive = ointer; 40226049Sminshall } 40326049Sminshall } 40426049Sminshall } 40513212Ssam if (gargs != NULL) 40613212Ssam blkfree(gargs); 40711353Ssam } 40826049Sminshall (void) signal(SIGINT, oldintr); 40926049Sminshall mflag = 0; 41011353Ssam } 41111353Ssam 41211353Ssam /* 41311353Ssam * Receive one file. 41411353Ssam */ 41510294Ssam get(argc, argv) 41610294Ssam char *argv[]; 41710294Ssam { 41826049Sminshall int loc = 0; 41910294Ssam 42026049Sminshall if (argc == 2) { 42126049Sminshall argc++; 42226049Sminshall argv[2] = argv[1]; 42326049Sminshall loc++; 42426049Sminshall } 42510294Ssam if (argc < 2) { 42626497Sminshall (void) strcat(line, " "); 42710294Ssam printf("(remote-file) "); 42826497Sminshall (void) gets(&line[strlen(line)]); 42910294Ssam makeargv(); 43010294Ssam argc = margc; 43110294Ssam argv = margv; 43210294Ssam } 43310294Ssam if (argc < 2) { 43410294Ssam usage: 43526049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 43626049Sminshall code = -1; 43710294Ssam return; 43810294Ssam } 43910294Ssam if (argc < 3) { 44026497Sminshall (void) strcat(line, " "); 44110294Ssam printf("(local-file) "); 44226497Sminshall (void) gets(&line[strlen(line)]); 44310294Ssam makeargv(); 44410294Ssam argc = margc; 44510294Ssam argv = margv; 44610294Ssam } 44710294Ssam if (argc < 3) 44810294Ssam goto usage; 44926049Sminshall if (!globulize(&argv[2])) { 45026049Sminshall code = -1; 45111353Ssam return; 45226049Sminshall } 45326049Sminshall if (loc && mcase) { 45426049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 45526049Sminshall 45626049Sminshall while (*tp && !islower(*tp)) { 45726049Sminshall tp++; 45826049Sminshall } 45926049Sminshall if (!*tp) { 46026049Sminshall tp = argv[2]; 46126049Sminshall tp2 = tmpbuf; 46226049Sminshall while ((*tp2 = *tp) != NULL) { 46326049Sminshall if (isupper(*tp2)) { 46426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 46526049Sminshall } 46626049Sminshall tp++; 46726049Sminshall tp2++; 46826049Sminshall } 46926049Sminshall argv[2] = tmpbuf; 47026049Sminshall } 47126049Sminshall } 47226049Sminshall if (loc && ntflag) { 47326049Sminshall argv[2] = dotrans(argv[2]); 47426049Sminshall } 47526049Sminshall if (loc && mapflag) { 47626049Sminshall argv[2] = domap(argv[2]); 47726049Sminshall } 47811650Ssam recvrequest("RETR", argv[2], argv[1], "w"); 47910294Ssam } 48010294Ssam 48126049Sminshall mabort() 48226049Sminshall { 48326049Sminshall int ointer; 48426049Sminshall extern jmp_buf jabort; 48526049Sminshall 48626049Sminshall printf("\n"); 48726049Sminshall (void) fflush(stdout); 48826049Sminshall if (mflag && fromatty) { 48926049Sminshall ointer = interactive; 49026049Sminshall interactive = 1; 49126049Sminshall if (confirm("Continue with", mname)) { 49226049Sminshall interactive = ointer; 49326049Sminshall longjmp(jabort,0); 49426049Sminshall } 49526049Sminshall interactive = ointer; 49626049Sminshall } 49726049Sminshall mflag = 0; 49826049Sminshall longjmp(jabort,0); 49926049Sminshall } 50026049Sminshall 50111353Ssam /* 50211353Ssam * Get multiple files. 50311353Ssam */ 50411353Ssam mget(argc, argv) 50511353Ssam char *argv[]; 50611353Ssam { 50726049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 50826049Sminshall int ointer, (*oldintr)(), mabort(); 50926049Sminshall extern jmp_buf jabort; 51011353Ssam 51111353Ssam if (argc < 2) { 51226497Sminshall (void) strcat(line, " "); 51311756Ssam printf("(remote-files) "); 51426497Sminshall (void) gets(&line[strlen(line)]); 51511353Ssam makeargv(); 51611353Ssam argc = margc; 51711353Ssam argv = margv; 51811353Ssam } 51911353Ssam if (argc < 2) { 52026049Sminshall printf("usage:%s remote-files\n", argv[0]); 52126049Sminshall code = -1; 52211353Ssam return; 52311353Ssam } 52426049Sminshall mname = argv[0]; 52526049Sminshall mflag = 1; 52626049Sminshall oldintr = signal(SIGINT,mabort); 52726049Sminshall (void) setjmp(jabort); 52826497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 52926049Sminshall if (*cp == '\0') { 53026049Sminshall mflag = 0; 53126049Sminshall continue; 53226049Sminshall } 53326049Sminshall if (mflag && confirm(argv[0], cp)) { 53426049Sminshall tp = cp; 53526049Sminshall if (mcase) { 53626049Sminshall while (*tp && !islower(*tp)) { 53726049Sminshall tp++; 53826049Sminshall } 53926049Sminshall if (!*tp) { 54026049Sminshall tp = cp; 54126049Sminshall tp2 = tmpbuf; 54226049Sminshall while ((*tp2 = *tp) != NULL) { 54326049Sminshall if (isupper(*tp2)) { 54426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 54526049Sminshall } 54626049Sminshall tp++; 54726049Sminshall tp2++; 54826049Sminshall } 54926049Sminshall } 55026049Sminshall tp = tmpbuf; 55126049Sminshall } 55226049Sminshall if (ntflag) { 55326049Sminshall tp = dotrans(tp); 55426049Sminshall } 55526049Sminshall if (mapflag) { 55626049Sminshall tp = domap(tp); 55726049Sminshall } 55826049Sminshall recvrequest("RETR", tp, cp, "w"); 55926049Sminshall if (!mflag && fromatty) { 56026049Sminshall ointer = interactive; 56126049Sminshall interactive = 1; 56226049Sminshall if (confirm("Continue with","mget")) { 56326049Sminshall mflag++; 56426049Sminshall } 56526049Sminshall interactive = ointer; 56626049Sminshall } 56726049Sminshall } 56826049Sminshall } 56926049Sminshall (void) signal(SIGINT,oldintr); 57026049Sminshall mflag = 0; 57111650Ssam } 57211650Ssam 57311650Ssam char * 57426497Sminshall remglob(argv,doswitch) 57511650Ssam char *argv[]; 57626497Sminshall int doswitch; 57711650Ssam { 57811756Ssam char temp[16]; 57911650Ssam static char buf[MAXPATHLEN]; 58011650Ssam static FILE *ftemp = NULL; 58111650Ssam static char **args; 58213212Ssam int oldverbose, oldhash; 58311756Ssam char *cp, *mode; 58411650Ssam 58526049Sminshall if (!mflag) { 58626049Sminshall if (!doglob) { 58726049Sminshall args = NULL; 58826049Sminshall } 58926049Sminshall else { 59026049Sminshall if (ftemp) { 59126497Sminshall (void) fclose(ftemp); 59226049Sminshall ftemp = NULL; 59326049Sminshall } 59426049Sminshall } 59526049Sminshall return(NULL); 59626049Sminshall } 59711650Ssam if (!doglob) { 59811756Ssam if (args == NULL) 59911650Ssam args = argv; 60011650Ssam if ((cp = *++args) == NULL) 60111650Ssam args = NULL; 60211650Ssam return (cp); 60311353Ssam } 60411650Ssam if (ftemp == NULL) { 60526497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 60626497Sminshall (void) mktemp(temp); 60711650Ssam oldverbose = verbose, verbose = 0; 60813212Ssam oldhash = hash, hash = 0; 60926049Sminshall if (doswitch) { 61026049Sminshall pswitch(!proxy); 61126049Sminshall } 61211756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 61311756Ssam recvrequest ("NLST", temp, *argv, mode); 61426049Sminshall if (doswitch) { 61526049Sminshall pswitch(!proxy); 61626049Sminshall } 61713212Ssam verbose = oldverbose; hash = oldhash; 61811650Ssam ftemp = fopen(temp, "r"); 61926497Sminshall (void) unlink(temp); 62011650Ssam if (ftemp == NULL) { 62111650Ssam printf("can't find list of remote files, oops\n"); 62211756Ssam return (NULL); 62311353Ssam } 62411353Ssam } 62511650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 62626497Sminshall (void) fclose(ftemp), ftemp = NULL; 62711650Ssam return (NULL); 62811353Ssam } 62911650Ssam if ((cp = index(buf, '\n')) != NULL) 63011650Ssam *cp = '\0'; 63111650Ssam return (buf); 63211353Ssam } 63311353Ssam 63410294Ssam char * 63510294Ssam onoff(bool) 63610294Ssam int bool; 63710294Ssam { 63810294Ssam 63910294Ssam return (bool ? "on" : "off"); 64010294Ssam } 64110294Ssam 64210294Ssam /* 64310294Ssam * Show status. 64410294Ssam */ 64526497Sminshall /*ARGSUSED*/ 64610294Ssam status(argc, argv) 64710294Ssam char *argv[]; 64810294Ssam { 64926049Sminshall int i; 65010294Ssam 65110294Ssam if (connected) 65210294Ssam printf("Connected to %s.\n", hostname); 65310294Ssam else 65410294Ssam printf("Not connected.\n"); 65526049Sminshall if (!proxy) { 65626049Sminshall pswitch(1); 65726049Sminshall if (connected) { 65826049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 65926049Sminshall } 66026049Sminshall else { 66126049Sminshall printf("No proxy connection.\n"); 66226049Sminshall } 66326049Sminshall pswitch(0); 66426049Sminshall } 66510294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 66610294Ssam modename, typename, formname, structname); 66711353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 66811353Ssam onoff(verbose), onoff(bell), onoff(interactive), 66911353Ssam onoff(doglob)); 67026049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 67126049Sminshall onoff(runique)); 67226049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 67326049Sminshall if (ntflag) { 67426049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 67526049Sminshall } 67626049Sminshall else { 67726049Sminshall printf("Ntrans: off\n"); 67826049Sminshall } 67926049Sminshall if (mapflag) { 68026049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 68126049Sminshall } 68226049Sminshall else { 68326049Sminshall printf("Nmap: off\n"); 68426049Sminshall } 68514143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 68614143Ssam onoff(hash), onoff(sendport)); 68726049Sminshall if (macnum > 0) { 68826049Sminshall printf("Macros:\n"); 68926049Sminshall for (i=0; i<macnum; i++) { 69026049Sminshall printf("\t%s\n",macros[i].mac_name); 69126049Sminshall } 69226049Sminshall } 69326049Sminshall code = 0; 69410294Ssam } 69510294Ssam 69610294Ssam /* 69710294Ssam * Set beep on cmd completed mode. 69810294Ssam */ 69910294Ssam /*VARARGS*/ 70010294Ssam setbell() 70110294Ssam { 70210294Ssam 70310294Ssam bell = !bell; 70410294Ssam printf("Bell mode %s.\n", onoff(bell)); 70526049Sminshall code = bell; 70610294Ssam } 70710294Ssam 70810294Ssam /* 70910294Ssam * Turn on packet tracing. 71010294Ssam */ 71110294Ssam /*VARARGS*/ 71210294Ssam settrace() 71310294Ssam { 71410294Ssam 71510294Ssam trace = !trace; 71610294Ssam printf("Packet tracing %s.\n", onoff(trace)); 71726049Sminshall code = trace; 71810294Ssam } 71910294Ssam 72010294Ssam /* 72111650Ssam * Toggle hash mark printing during transfers. 72211650Ssam */ 72311650Ssam /*VARARGS*/ 72411650Ssam sethash() 72511650Ssam { 72611650Ssam 72711650Ssam hash = !hash; 72811650Ssam printf("Hash mark printing %s", onoff(hash)); 72926049Sminshall code = hash; 73011650Ssam if (hash) 73111650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 73211650Ssam printf(".\n"); 73311650Ssam } 73411650Ssam 73511650Ssam /* 73610294Ssam * Turn on printing of server echo's. 73710294Ssam */ 73810294Ssam /*VARARGS*/ 73910294Ssam setverbose() 74010294Ssam { 74110294Ssam 74210294Ssam verbose = !verbose; 74310294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 74426049Sminshall code = verbose; 74510294Ssam } 74610294Ssam 74710294Ssam /* 74811650Ssam * Toggle PORT cmd use before each data connection. 74911650Ssam */ 75011650Ssam /*VARARGS*/ 75111650Ssam setport() 75211650Ssam { 75311650Ssam 75411650Ssam sendport = !sendport; 75511650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 75626049Sminshall code = sendport; 75711650Ssam } 75811650Ssam 75911650Ssam /* 76010294Ssam * Turn on interactive prompting 76110294Ssam * during mget, mput, and mdelete. 76210294Ssam */ 76310294Ssam /*VARARGS*/ 76410294Ssam setprompt() 76510294Ssam { 76610294Ssam 76710294Ssam interactive = !interactive; 76810294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 76926049Sminshall code = interactive; 77010294Ssam } 77110294Ssam 77210294Ssam /* 77311353Ssam * Toggle metacharacter interpretation 77411353Ssam * on local file names. 77511353Ssam */ 77611353Ssam /*VARARGS*/ 77711353Ssam setglob() 77811353Ssam { 77911353Ssam 78011353Ssam doglob = !doglob; 78111353Ssam printf("Globbing %s.\n", onoff(doglob)); 78226049Sminshall code = doglob; 78311353Ssam } 78411353Ssam 78511353Ssam /* 78610294Ssam * Set debugging mode on/off and/or 78710294Ssam * set level of debugging. 78810294Ssam */ 78911756Ssam /*VARARGS*/ 79010294Ssam setdebug(argc, argv) 79110294Ssam char *argv[]; 79210294Ssam { 79310294Ssam int val; 79410294Ssam 79510294Ssam if (argc > 1) { 79610294Ssam val = atoi(argv[1]); 79710294Ssam if (val < 0) { 79810294Ssam printf("%s: bad debugging value.\n", argv[1]); 79926049Sminshall code = -1; 80010294Ssam return; 80110294Ssam } 80210294Ssam } else 80310294Ssam val = !debug; 80410294Ssam debug = val; 80510294Ssam if (debug) 80610294Ssam options |= SO_DEBUG; 80710294Ssam else 80810294Ssam options &= ~SO_DEBUG; 80910294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 81026049Sminshall code = debug > 0; 81110294Ssam } 81210294Ssam 81310294Ssam /* 81410294Ssam * Set current working directory 81510294Ssam * on remote machine. 81610294Ssam */ 81710294Ssam cd(argc, argv) 81810294Ssam char *argv[]; 81910294Ssam { 82010294Ssam 82110294Ssam if (argc < 2) { 82226497Sminshall (void) strcat(line, " "); 82310294Ssam printf("(remote-directory) "); 82426497Sminshall (void) gets(&line[strlen(line)]); 82510294Ssam makeargv(); 82610294Ssam argc = margc; 82710294Ssam argv = margv; 82810294Ssam } 82910294Ssam if (argc < 2) { 83026049Sminshall printf("usage:%s remote-directory\n", argv[0]); 83126049Sminshall code = -1; 83210294Ssam return; 83310294Ssam } 83410294Ssam (void) command("CWD %s", argv[1]); 83510294Ssam } 83610294Ssam 83710294Ssam /* 83810294Ssam * Set current working directory 83910294Ssam * on local machine. 84010294Ssam */ 84110294Ssam lcd(argc, argv) 84210294Ssam char *argv[]; 84310294Ssam { 84411353Ssam char buf[MAXPATHLEN]; 84510294Ssam 84611353Ssam if (argc < 2) 84711353Ssam argc++, argv[1] = home; 84810294Ssam if (argc != 2) { 84926049Sminshall printf("usage:%s local-directory\n", argv[0]); 85026049Sminshall code = -1; 85110294Ssam return; 85210294Ssam } 85326049Sminshall if (!globulize(&argv[1])) { 85426049Sminshall code = -1; 85511353Ssam return; 85626049Sminshall } 85711353Ssam if (chdir(argv[1]) < 0) { 85810294Ssam perror(argv[1]); 85926049Sminshall code = -1; 86011353Ssam return; 86111353Ssam } 86211353Ssam printf("Local directory now %s\n", getwd(buf)); 86326049Sminshall code = 0; 86410294Ssam } 86510294Ssam 86610294Ssam /* 86710294Ssam * Delete a single file. 86810294Ssam */ 86910294Ssam delete(argc, argv) 87010294Ssam char *argv[]; 87110294Ssam { 87210294Ssam 87310294Ssam if (argc < 2) { 87426497Sminshall (void) strcat(line, " "); 87510294Ssam printf("(remote-file) "); 87626497Sminshall (void) gets(&line[strlen(line)]); 87710294Ssam makeargv(); 87810294Ssam argc = margc; 87910294Ssam argv = margv; 88010294Ssam } 88110294Ssam if (argc < 2) { 88226049Sminshall printf("usage:%s remote-file\n", argv[0]); 88326049Sminshall code = -1; 88410294Ssam return; 88510294Ssam } 88610294Ssam (void) command("DELE %s", argv[1]); 88710294Ssam } 88810294Ssam 88910294Ssam /* 89011650Ssam * Delete multiple files. 89111650Ssam */ 89211650Ssam mdelete(argc, argv) 89311650Ssam char *argv[]; 89411650Ssam { 89511650Ssam char *cp; 89626049Sminshall int ointer, (*oldintr)(), mabort(); 89726049Sminshall extern jmp_buf jabort; 89811650Ssam 89911650Ssam if (argc < 2) { 90026497Sminshall (void) strcat(line, " "); 90111650Ssam printf("(remote-files) "); 90226497Sminshall (void) gets(&line[strlen(line)]); 90311650Ssam makeargv(); 90411650Ssam argc = margc; 90511650Ssam argv = margv; 90611650Ssam } 90711650Ssam if (argc < 2) { 90826049Sminshall printf("usage:%s remote-files\n", argv[0]); 90926049Sminshall code = -1; 91011650Ssam return; 91111650Ssam } 91226049Sminshall mname = argv[0]; 91326049Sminshall mflag = 1; 91426049Sminshall oldintr = signal(SIGINT, mabort); 91526049Sminshall (void) setjmp(jabort); 91626497Sminshall while ((cp = remglob(argv,0)) != NULL) { 91726049Sminshall if (*cp == '\0') { 91826049Sminshall mflag = 0; 91926049Sminshall continue; 92026049Sminshall } 92126049Sminshall if (mflag && confirm(argv[0], cp)) { 92211650Ssam (void) command("DELE %s", cp); 92326049Sminshall if (!mflag && fromatty) { 92426049Sminshall ointer = interactive; 92526049Sminshall interactive = 1; 92626049Sminshall if (confirm("Continue with", "mdelete")) { 92726049Sminshall mflag++; 92826049Sminshall } 92926049Sminshall interactive = ointer; 93026049Sminshall } 93126049Sminshall } 93226049Sminshall } 93326049Sminshall (void) signal(SIGINT, oldintr); 93426049Sminshall mflag = 0; 93511650Ssam } 93611756Ssam 93711650Ssam /* 93810294Ssam * Rename a remote file. 93910294Ssam */ 94010294Ssam renamefile(argc, argv) 94110294Ssam char *argv[]; 94210294Ssam { 94310294Ssam 94410294Ssam if (argc < 2) { 94526497Sminshall (void) strcat(line, " "); 94610294Ssam printf("(from-name) "); 94726497Sminshall (void) gets(&line[strlen(line)]); 94810294Ssam makeargv(); 94910294Ssam argc = margc; 95010294Ssam argv = margv; 95110294Ssam } 95210294Ssam if (argc < 2) { 95310294Ssam usage: 95410294Ssam printf("%s from-name to-name\n", argv[0]); 95526049Sminshall code = -1; 95610294Ssam return; 95710294Ssam } 95810294Ssam if (argc < 3) { 95926497Sminshall (void) strcat(line, " "); 96010294Ssam printf("(to-name) "); 96126497Sminshall (void) gets(&line[strlen(line)]); 96210294Ssam makeargv(); 96310294Ssam argc = margc; 96410294Ssam argv = margv; 96510294Ssam } 96610294Ssam if (argc < 3) 96710294Ssam goto usage; 96810294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 96910294Ssam (void) command("RNTO %s", argv[2]); 97010294Ssam } 97110294Ssam 97210294Ssam /* 97310294Ssam * Get a directory listing 97410294Ssam * of remote files. 97510294Ssam */ 97610294Ssam ls(argc, argv) 97710294Ssam char *argv[]; 97810294Ssam { 97911756Ssam char *cmd; 98010294Ssam 98110294Ssam if (argc < 2) 98210294Ssam argc++, argv[1] = NULL; 98310294Ssam if (argc < 3) 98410294Ssam argc++, argv[2] = "-"; 98511756Ssam if (argc > 3) { 98611756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 98726049Sminshall code = -1; 98811756Ssam return; 98911756Ssam } 99010294Ssam cmd = argv[0][0] == 'l' ? "NLST" : "LIST"; 99126049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 99226049Sminshall code = -1; 99311353Ssam return; 99426049Sminshall } 995*32344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 996*32344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 997*32344Scsvsj code = -1; 998*32344Scsvsj return; 999*32344Scsvsj } 100011756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 100110294Ssam } 100210294Ssam 100310294Ssam /* 100411756Ssam * Get a directory listing 100511756Ssam * of multiple remote files. 100611756Ssam */ 100711756Ssam mls(argc, argv) 100811756Ssam char *argv[]; 100911756Ssam { 101026049Sminshall char *cmd, mode[1], *dest; 101126049Sminshall int ointer, i, (*oldintr)(), mabort(); 101226049Sminshall extern jmp_buf jabort; 101311756Ssam 101413212Ssam if (argc < 2) { 101526497Sminshall (void) strcat(line, " "); 101613212Ssam printf("(remote-files) "); 101726497Sminshall (void) gets(&line[strlen(line)]); 101813212Ssam makeargv(); 101913212Ssam argc = margc; 102013212Ssam argv = margv; 102113212Ssam } 102213212Ssam if (argc < 3) { 102326497Sminshall (void) strcat(line, " "); 102413212Ssam printf("(local-file) "); 102526497Sminshall (void) gets(&line[strlen(line)]); 102613212Ssam makeargv(); 102713212Ssam argc = margc; 102813212Ssam argv = margv; 102913212Ssam } 103013212Ssam if (argc < 3) { 103126049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 103226049Sminshall code = -1; 103313212Ssam return; 103413212Ssam } 103513212Ssam dest = argv[argc - 1]; 103613212Ssam argv[argc - 1] = NULL; 103726049Sminshall if (strcmp(dest, "-") && *dest != '|') 103826049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 103926049Sminshall code = -1; 104013212Ssam return; 104126049Sminshall } 104211756Ssam cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 104326049Sminshall mname = argv[0]; 104426049Sminshall mflag = 1; 104526049Sminshall oldintr = signal(SIGINT, mabort); 104626049Sminshall (void) setjmp(jabort); 104726049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 104826049Sminshall *mode = (i == 1) ? 'w' : 'a'; 104926049Sminshall recvrequest(cmd, dest, argv[i], mode); 105026049Sminshall if (!mflag && fromatty) { 105126049Sminshall ointer = interactive; 105226049Sminshall interactive = 1; 105326049Sminshall if (confirm("Continue with", argv[0])) { 105426049Sminshall mflag ++; 105526049Sminshall } 105626049Sminshall interactive = ointer; 105726049Sminshall } 105826049Sminshall } 105926049Sminshall (void) signal(SIGINT, oldintr); 106026049Sminshall mflag = 0; 106111756Ssam } 106211756Ssam 106311756Ssam /* 106410294Ssam * Do a shell escape 106510294Ssam */ 106626497Sminshall /*ARGSUSED*/ 106710294Ssam shell(argc, argv) 106810294Ssam char *argv[]; 106910294Ssam { 107026497Sminshall int pid, (*old1)(), (*old2)(); 107126049Sminshall char shellnam[40], *shell, *namep; 107226497Sminshall union wait status; 107310294Ssam 107411756Ssam old1 = signal (SIGINT, SIG_IGN); 107511756Ssam old2 = signal (SIGQUIT, SIG_IGN); 107611756Ssam if ((pid = fork()) == 0) { 107711756Ssam for (pid = 3; pid < 20; pid++) 107826497Sminshall (void) close(pid); 107926497Sminshall (void) signal(SIGINT, SIG_DFL); 108026497Sminshall (void) signal(SIGQUIT, SIG_DFL); 108125908Smckusick shell = getenv("SHELL"); 108225908Smckusick if (shell == NULL) 108325908Smckusick shell = "/bin/sh"; 108425908Smckusick namep = rindex(shell,'/'); 108525908Smckusick if (namep == NULL) 108625908Smckusick namep = shell; 108726497Sminshall (void) strcpy(shellnam,"-"); 108826497Sminshall (void) strcat(shellnam, ++namep); 108926049Sminshall if (strcmp(namep, "sh") != 0) 109026049Sminshall shellnam[0] = '+'; 109126049Sminshall if (debug) { 109226049Sminshall printf ("%s\n", shell); 109326497Sminshall (void) fflush (stdout); 109411756Ssam } 109526049Sminshall if (argc > 1) { 109626049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 109726049Sminshall } 109826049Sminshall else { 109926049Sminshall execl(shell,shellnam,(char *)0); 110026049Sminshall } 110125908Smckusick perror(shell); 110226049Sminshall code = -1; 110311756Ssam exit(1); 110426049Sminshall } 110511756Ssam if (pid > 0) 110611756Ssam while (wait(&status) != pid) 110711756Ssam ; 110826497Sminshall (void) signal(SIGINT, old1); 110926497Sminshall (void) signal(SIGQUIT, old2); 111026049Sminshall if (pid == -1) { 111111756Ssam perror("Try again later"); 111226049Sminshall code = -1; 111326049Sminshall } 111426049Sminshall else { 111526049Sminshall code = 0; 111626049Sminshall } 111711756Ssam return (0); 111810294Ssam } 111910294Ssam 112010294Ssam /* 112110294Ssam * Send new user information (re-login) 112210294Ssam */ 112310294Ssam user(argc, argv) 112410294Ssam int argc; 112510294Ssam char **argv; 112610294Ssam { 112726497Sminshall char acct[80], *mygetpass(); 112826049Sminshall int n, aflag = 0; 112910294Ssam 113010294Ssam if (argc < 2) { 113126497Sminshall (void) strcat(line, " "); 113210294Ssam printf("(username) "); 113326497Sminshall (void) gets(&line[strlen(line)]); 113410294Ssam makeargv(); 113510294Ssam argc = margc; 113610294Ssam argv = margv; 113710294Ssam } 113810294Ssam if (argc > 4) { 113910294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 114026049Sminshall code = -1; 114111756Ssam return (0); 114210294Ssam } 114310294Ssam n = command("USER %s", argv[1]); 114410294Ssam if (n == CONTINUE) { 114510294Ssam if (argc < 3 ) 114626497Sminshall argv[2] = mygetpass("Password: "), argc++; 114710294Ssam n = command("PASS %s", argv[2]); 114810294Ssam } 114910294Ssam if (n == CONTINUE) { 115010294Ssam if (argc < 4) { 115110294Ssam printf("Account: "); (void) fflush(stdout); 115210294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 115310294Ssam acct[strlen(acct) - 1] = '\0'; 115410294Ssam argv[3] = acct; argc++; 115510294Ssam } 115626049Sminshall n = command("ACCT %s", argv[3]); 115726049Sminshall aflag++; 115810294Ssam } 115910294Ssam if (n != COMPLETE) { 116026497Sminshall fprintf(stdout, "Login failed.\n"); 116110294Ssam return (0); 116210294Ssam } 116326049Sminshall if (!aflag && argc == 4) { 116426049Sminshall (void) command("ACCT %s", argv[3]); 116526049Sminshall } 116610294Ssam return (1); 116710294Ssam } 116810294Ssam 116910294Ssam /* 117010294Ssam * Print working directory. 117110294Ssam */ 117210294Ssam /*VARARGS*/ 117310294Ssam pwd() 117410294Ssam { 117511756Ssam 117626049Sminshall (void) command("PWD"); 117710294Ssam } 117810294Ssam 117910294Ssam /* 118010294Ssam * Make a directory. 118110294Ssam */ 118210294Ssam makedir(argc, argv) 118310294Ssam char *argv[]; 118410294Ssam { 118510294Ssam 118610294Ssam if (argc < 2) { 118726497Sminshall (void) strcat(line, " "); 118810294Ssam printf("(directory-name) "); 118926497Sminshall (void) gets(&line[strlen(line)]); 119010294Ssam makeargv(); 119110294Ssam argc = margc; 119210294Ssam argv = margv; 119310294Ssam } 119410294Ssam if (argc < 2) { 119526049Sminshall printf("usage: %s directory-name\n", argv[0]); 119626049Sminshall code = -1; 119710294Ssam return; 119810294Ssam } 119926049Sminshall (void) command("MKD %s", argv[1]); 120010294Ssam } 120110294Ssam 120210294Ssam /* 120310294Ssam * Remove a directory. 120410294Ssam */ 120510294Ssam removedir(argc, argv) 120610294Ssam char *argv[]; 120710294Ssam { 120810294Ssam 120910294Ssam if (argc < 2) { 121026497Sminshall (void) strcat(line, " "); 121110294Ssam printf("(directory-name) "); 121226497Sminshall (void) gets(&line[strlen(line)]); 121310294Ssam makeargv(); 121410294Ssam argc = margc; 121510294Ssam argv = margv; 121610294Ssam } 121710294Ssam if (argc < 2) { 121826049Sminshall printf("usage: %s directory-name\n", argv[0]); 121926049Sminshall code = -1; 122010294Ssam return; 122110294Ssam } 122226049Sminshall (void) command("RMD %s", argv[1]); 122310294Ssam } 122410294Ssam 122510294Ssam /* 122610294Ssam * Send a line, verbatim, to the remote machine. 122710294Ssam */ 122810294Ssam quote(argc, argv) 122910294Ssam char *argv[]; 123010294Ssam { 123110294Ssam int i; 123210294Ssam char buf[BUFSIZ]; 123310294Ssam 123410294Ssam if (argc < 2) { 123526497Sminshall (void) strcat(line, " "); 123610294Ssam printf("(command line to send) "); 123726497Sminshall (void) gets(&line[strlen(line)]); 123810294Ssam makeargv(); 123910294Ssam argc = margc; 124010294Ssam argv = margv; 124110294Ssam } 124210294Ssam if (argc < 2) { 124310294Ssam printf("usage: %s line-to-send\n", argv[0]); 124426049Sminshall code = -1; 124510294Ssam return; 124610294Ssam } 124726497Sminshall (void) strcpy(buf, argv[1]); 124810294Ssam for (i = 2; i < argc; i++) { 124926497Sminshall (void) strcat(buf, " "); 125026497Sminshall (void) strcat(buf, argv[i]); 125110294Ssam } 125226049Sminshall if (command(buf) == PRELIM) { 125326049Sminshall while (getreply(0) == PRELIM); 125426049Sminshall } 125510294Ssam } 125610294Ssam 125710294Ssam /* 125810294Ssam * Ask the other side for help. 125910294Ssam */ 126010294Ssam rmthelp(argc, argv) 126110294Ssam char *argv[]; 126210294Ssam { 126310294Ssam int oldverbose = verbose; 126410294Ssam 126510294Ssam verbose = 1; 126610294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 126710294Ssam verbose = oldverbose; 126810294Ssam } 126910294Ssam 127010294Ssam /* 127110294Ssam * Terminate session and exit. 127210294Ssam */ 127310294Ssam /*VARARGS*/ 127410294Ssam quit() 127510294Ssam { 127610294Ssam 127718286Sralph if (connected) 127818286Sralph disconnect(); 127926049Sminshall pswitch(1); 128026049Sminshall if (connected) { 128126049Sminshall disconnect(); 128226049Sminshall } 128310294Ssam exit(0); 128410294Ssam } 128510294Ssam 128610294Ssam /* 128710294Ssam * Terminate session, but don't exit. 128810294Ssam */ 128910294Ssam disconnect() 129010294Ssam { 129110294Ssam extern FILE *cout; 129210294Ssam extern int data; 129310294Ssam 129410294Ssam if (!connected) 129510294Ssam return; 129610294Ssam (void) command("QUIT"); 129726049Sminshall if (cout) { 129826049Sminshall (void) fclose(cout); 129926049Sminshall } 130010294Ssam cout = NULL; 130110294Ssam connected = 0; 130210294Ssam data = -1; 130326049Sminshall if (!proxy) { 130426049Sminshall macnum = 0; 130526049Sminshall } 130610294Ssam } 130711353Ssam 130811650Ssam confirm(cmd, file) 130911353Ssam char *cmd, *file; 131011353Ssam { 131111353Ssam char line[BUFSIZ]; 131211353Ssam 131311353Ssam if (!interactive) 131411650Ssam return (1); 131511353Ssam printf("%s %s? ", cmd, file); 131626497Sminshall (void) fflush(stdout); 131726497Sminshall (void) gets(line); 131811650Ssam return (*line != 'n' && *line != 'N'); 131911353Ssam } 132011353Ssam 132111353Ssam fatal(msg) 132211353Ssam char *msg; 132311353Ssam { 132411353Ssam 132526497Sminshall fprintf(stderr, "ftp: %s\n", msg); 132611353Ssam exit(1); 132711353Ssam } 132811353Ssam 132911353Ssam /* 133011353Ssam * Glob a local file name specification with 133111353Ssam * the expectation of a single return value. 133211353Ssam * Can't control multiple values being expanded 133311353Ssam * from the expression, we return only the first. 133411353Ssam */ 133511353Ssam globulize(cpp) 133611353Ssam char **cpp; 133711353Ssam { 133811353Ssam char **globbed; 133911353Ssam 134011353Ssam if (!doglob) 134111353Ssam return (1); 134211353Ssam globbed = glob(*cpp); 134311353Ssam if (globerr != NULL) { 134411353Ssam printf("%s: %s\n", *cpp, globerr); 134511353Ssam if (globbed) 134611353Ssam blkfree(globbed); 134711353Ssam return (0); 134811353Ssam } 134911353Ssam if (globbed) { 135011353Ssam *cpp = *globbed++; 135111353Ssam /* don't waste too much memory */ 135211353Ssam if (*globbed) 135311353Ssam blkfree(globbed); 135411353Ssam } 135511353Ssam return (1); 135611353Ssam } 135726049Sminshall 135826049Sminshall account(argc,argv) 135926049Sminshall 136026049Sminshall int argc; 136126049Sminshall char **argv; 136226049Sminshall { 136326497Sminshall char acct[50], *mygetpass(), *ap; 136426049Sminshall 136526049Sminshall if (argc > 1) { 136626049Sminshall ++argv; 136726049Sminshall --argc; 136826049Sminshall (void) strncpy(acct,*argv,49); 136926049Sminshall acct[50] = '\0'; 137026049Sminshall while (argc > 1) { 137126049Sminshall --argc; 137226049Sminshall ++argv; 137326049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 137426049Sminshall } 137526049Sminshall ap = acct; 137626049Sminshall } 137726049Sminshall else { 137826497Sminshall ap = mygetpass("Account:"); 137926049Sminshall } 138026049Sminshall (void) command("ACCT %s", ap); 138126049Sminshall } 138226049Sminshall 138326049Sminshall jmp_buf abortprox; 138426049Sminshall 138526049Sminshall proxabort() 138626049Sminshall { 138726049Sminshall extern int proxy; 138826049Sminshall 138926049Sminshall if (!proxy) { 139026049Sminshall pswitch(1); 139126049Sminshall } 139226049Sminshall if (connected) { 139326049Sminshall proxflag = 1; 139426049Sminshall } 139526049Sminshall else { 139626049Sminshall proxflag = 0; 139726049Sminshall } 139826049Sminshall pswitch(0); 139926049Sminshall longjmp(abortprox,1); 140026049Sminshall } 140126049Sminshall 140226049Sminshall doproxy(argc,argv) 140326049Sminshall int argc; 140426049Sminshall char *argv[]; 140526049Sminshall { 140626049Sminshall int (*oldintr)(), proxabort(); 140726049Sminshall register struct cmd *c; 140826049Sminshall struct cmd *getcmd(); 140926049Sminshall extern struct cmd cmdtab[]; 141026049Sminshall extern jmp_buf abortprox; 141126049Sminshall 141226049Sminshall if (argc < 2) { 141326497Sminshall (void) strcat(line, " "); 141426049Sminshall printf("(command) "); 141526497Sminshall (void) gets(&line[strlen(line)]); 141626049Sminshall makeargv(); 141726049Sminshall argc = margc; 141826049Sminshall argv = margv; 141926049Sminshall } 142026049Sminshall if (argc < 2) { 142126049Sminshall printf("usage:%s command\n", argv[0]); 142226049Sminshall code = -1; 142326049Sminshall return; 142426049Sminshall } 142526049Sminshall c = getcmd(argv[1]); 142626049Sminshall if (c == (struct cmd *) -1) { 142726049Sminshall printf("?Ambiguous command\n"); 142826497Sminshall (void) fflush(stdout); 142926049Sminshall code = -1; 143026049Sminshall return; 143126049Sminshall } 143226049Sminshall if (c == 0) { 143326049Sminshall printf("?Invalid command\n"); 143426497Sminshall (void) fflush(stdout); 143526049Sminshall code = -1; 143626049Sminshall return; 143726049Sminshall } 143826049Sminshall if (!c->c_proxy) { 143926049Sminshall printf("?Invalid proxy command\n"); 144026497Sminshall (void) fflush(stdout); 144126049Sminshall code = -1; 144226049Sminshall return; 144326049Sminshall } 144426049Sminshall if (setjmp(abortprox)) { 144526049Sminshall code = -1; 144626049Sminshall return; 144726049Sminshall } 144826049Sminshall oldintr = signal(SIGINT, proxabort); 144926049Sminshall pswitch(1); 145026049Sminshall if (c->c_conn && !connected) { 145126049Sminshall printf("Not connected\n"); 145226497Sminshall (void) fflush(stdout); 145326049Sminshall pswitch(0); 145426049Sminshall (void) signal(SIGINT, oldintr); 145526049Sminshall code = -1; 145626049Sminshall return; 145726049Sminshall } 145826049Sminshall (*c->c_handler)(argc-1, argv+1); 145926049Sminshall if (connected) { 146026049Sminshall proxflag = 1; 146126049Sminshall } 146226049Sminshall else { 146326049Sminshall proxflag = 0; 146426049Sminshall } 146526049Sminshall pswitch(0); 146626049Sminshall (void) signal(SIGINT, oldintr); 146726049Sminshall } 146826049Sminshall 146926049Sminshall setcase() 147026049Sminshall { 147126049Sminshall mcase = !mcase; 147226049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 147326049Sminshall code = mcase; 147426049Sminshall } 147526049Sminshall 147626049Sminshall setcr() 147726049Sminshall { 147826049Sminshall crflag = !crflag; 147926049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 148026049Sminshall code = crflag; 148126049Sminshall } 148226049Sminshall 148326049Sminshall setntrans(argc,argv) 148426049Sminshall int argc; 148526049Sminshall char *argv[]; 148626049Sminshall { 148726049Sminshall if (argc == 1) { 148826049Sminshall ntflag = 0; 148926049Sminshall printf("Ntrans off.\n"); 149026049Sminshall code = ntflag; 149126049Sminshall return; 149226049Sminshall } 149326049Sminshall ntflag++; 149426049Sminshall code = ntflag; 149526049Sminshall (void) strncpy(ntin, argv[1], 16); 149626049Sminshall ntin[16] = '\0'; 149726049Sminshall if (argc == 2) { 149826049Sminshall ntout[0] = '\0'; 149926049Sminshall return; 150026049Sminshall } 150126049Sminshall (void) strncpy(ntout, argv[2], 16); 150226049Sminshall ntout[16] = '\0'; 150326049Sminshall } 150426049Sminshall 150526049Sminshall char * 150626049Sminshall dotrans(name) 150726049Sminshall char *name; 150826049Sminshall { 150926049Sminshall static char new[MAXPATHLEN]; 151026049Sminshall char *cp1, *cp2 = new; 151126049Sminshall register int i, ostop, found; 151226049Sminshall 151326049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 151426049Sminshall for (cp1 = name; *cp1; cp1++) { 151526049Sminshall found = 0; 151626049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 151726049Sminshall if (*cp1 == *(ntin + i)) { 151826049Sminshall found++; 151926049Sminshall if (i < ostop) { 152026049Sminshall *cp2++ = *(ntout + i); 152126049Sminshall } 152226049Sminshall break; 152326049Sminshall } 152426049Sminshall } 152526049Sminshall if (!found) { 152626049Sminshall *cp2++ = *cp1; 152726049Sminshall } 152826049Sminshall } 152926049Sminshall *cp2 = '\0'; 153026049Sminshall return(new); 153126049Sminshall } 153226049Sminshall 153326049Sminshall setnmap(argc, argv) 153426049Sminshall int argc; 153526049Sminshall char *argv[]; 153626049Sminshall { 153726049Sminshall char *cp; 153826049Sminshall 153926049Sminshall if (argc == 1) { 154026049Sminshall mapflag = 0; 154126049Sminshall printf("Nmap off.\n"); 154226049Sminshall code = mapflag; 154326049Sminshall return; 154426049Sminshall } 154526049Sminshall if (argc < 3) { 154626497Sminshall (void) strcat(line, " "); 154726049Sminshall printf("(mapout) "); 154826497Sminshall (void) gets(&line[strlen(line)]); 154926049Sminshall makeargv(); 155026049Sminshall argc = margc; 155126049Sminshall argv = margv; 155226049Sminshall } 155326049Sminshall if (argc < 3) { 155426049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 155526049Sminshall code = -1; 155626049Sminshall return; 155726049Sminshall } 155826049Sminshall mapflag = 1; 155926049Sminshall code = 1; 156026049Sminshall cp = index(altarg, ' '); 156126049Sminshall if (proxy) { 156226049Sminshall while(*++cp == ' '); 156326049Sminshall altarg = cp; 156426049Sminshall cp = index(altarg, ' '); 156526049Sminshall } 156626049Sminshall *cp = '\0'; 156726049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 156826049Sminshall while (*++cp == ' '); 156926049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 157026049Sminshall } 157126049Sminshall 157226049Sminshall char * 157326049Sminshall domap(name) 157426049Sminshall char *name; 157526049Sminshall { 157626049Sminshall static char new[MAXPATHLEN]; 157726049Sminshall register char *cp1 = name, *cp2 = mapin; 157826049Sminshall char *tp[9], *te[9]; 157926049Sminshall int i, toks[9], toknum, match = 1; 158026049Sminshall 158126049Sminshall for (i=0; i < 9; ++i) { 158226049Sminshall toks[i] = 0; 158326049Sminshall } 158426049Sminshall while (match && *cp1 && *cp2) { 158526049Sminshall switch (*cp2) { 158626049Sminshall case '\\': 158726049Sminshall if (*++cp2 != *cp1) { 158826049Sminshall match = 0; 158926049Sminshall } 159026049Sminshall break; 159126049Sminshall case '$': 159226049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 159326049Sminshall if (*cp1 != *(++cp2+1)) { 159426049Sminshall toks[toknum = *cp2 - '1']++; 159526049Sminshall tp[toknum] = cp1; 159626049Sminshall while (*++cp1 && *(cp2+1) 159726049Sminshall != *cp1); 159826049Sminshall te[toknum] = cp1; 159926049Sminshall } 160026049Sminshall cp2++; 160126049Sminshall break; 160226049Sminshall } 160326049Sminshall /* intentional drop through */ 160426049Sminshall default: 160526049Sminshall if (*cp2 != *cp1) { 160626049Sminshall match = 0; 160726049Sminshall } 160826049Sminshall break; 160926049Sminshall } 161026049Sminshall if (*cp1) { 161126049Sminshall cp1++; 161226049Sminshall } 161326049Sminshall if (*cp2) { 161426049Sminshall cp2++; 161526049Sminshall } 161626049Sminshall } 161726049Sminshall cp1 = new; 161826049Sminshall *cp1 = '\0'; 161926049Sminshall cp2 = mapout; 162026049Sminshall while (*cp2) { 162126049Sminshall match = 0; 162226049Sminshall switch (*cp2) { 162326049Sminshall case '\\': 162426049Sminshall if (*(cp2 + 1)) { 162526049Sminshall *cp1++ = *++cp2; 162626049Sminshall } 162726049Sminshall break; 162826049Sminshall case '[': 162926049Sminshall LOOP: 163026049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 163126049Sminshall if (*++cp2 == '0') { 163226049Sminshall char *cp3 = name; 163326049Sminshall 163426049Sminshall while (*cp3) { 163526049Sminshall *cp1++ = *cp3++; 163626049Sminshall } 163726049Sminshall match = 1; 163826049Sminshall } 163926049Sminshall else if (toks[toknum = *cp2 - '1']) { 164026049Sminshall char *cp3 = tp[toknum]; 164126049Sminshall 164226049Sminshall while (cp3 != te[toknum]) { 164326049Sminshall *cp1++ = *cp3++; 164426049Sminshall } 164526049Sminshall match = 1; 164626049Sminshall } 164726049Sminshall } 164826049Sminshall else { 164926049Sminshall while (*cp2 && *cp2 != ',' && 165026049Sminshall *cp2 != ']') { 165126049Sminshall if (*cp2 == '\\') { 165226049Sminshall cp2++; 165326049Sminshall } 165426049Sminshall else if (*cp2 == '$' && 165526049Sminshall isdigit(*(cp2+1))) { 165626049Sminshall if (*++cp2 == '0') { 165726049Sminshall char *cp3 = name; 165826049Sminshall 165926049Sminshall while (*cp3) { 166026049Sminshall *cp1++ = *cp3++; 166126049Sminshall } 166226049Sminshall } 166326049Sminshall else if (toks[toknum = 166426049Sminshall *cp2 - '1']) { 166526049Sminshall char *cp3=tp[toknum]; 166626049Sminshall 166726049Sminshall while (cp3 != 166826049Sminshall te[toknum]) { 166926049Sminshall *cp1++ = *cp3++; 167026049Sminshall } 167126049Sminshall } 167226049Sminshall } 167326049Sminshall else if (*cp2) { 167426049Sminshall *cp1++ = *cp2++; 167526049Sminshall } 167626049Sminshall } 167726049Sminshall if (!*cp2) { 167826049Sminshall printf("nmap: unbalanced brackets\n"); 167926049Sminshall return(name); 168026049Sminshall } 168126049Sminshall match = 1; 168226049Sminshall cp2--; 168326049Sminshall } 168426049Sminshall if (match) { 168526049Sminshall while (*++cp2 && *cp2 != ']') { 168626049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 168726049Sminshall cp2++; 168826049Sminshall } 168926049Sminshall } 169026049Sminshall if (!*cp2) { 169126049Sminshall printf("nmap: unbalanced brackets\n"); 169226049Sminshall return(name); 169326049Sminshall } 169426049Sminshall break; 169526049Sminshall } 169626049Sminshall switch (*++cp2) { 169726049Sminshall case ',': 169826049Sminshall goto LOOP; 169926049Sminshall case ']': 170026049Sminshall break; 170126049Sminshall default: 170226049Sminshall cp2--; 170326049Sminshall goto LOOP; 170426049Sminshall } 170526049Sminshall break; 170626049Sminshall case '$': 170726049Sminshall if (isdigit(*(cp2 + 1))) { 170826049Sminshall if (*++cp2 == '0') { 170926049Sminshall char *cp3 = name; 171026049Sminshall 171126049Sminshall while (*cp3) { 171226049Sminshall *cp1++ = *cp3++; 171326049Sminshall } 171426049Sminshall } 171526049Sminshall else if (toks[toknum = *cp2 - '1']) { 171626049Sminshall char *cp3 = tp[toknum]; 171726049Sminshall 171826049Sminshall while (cp3 != te[toknum]) { 171926049Sminshall *cp1++ = *cp3++; 172026049Sminshall } 172126049Sminshall } 172226049Sminshall break; 172326049Sminshall } 172426049Sminshall /* intentional drop through */ 172526049Sminshall default: 172626049Sminshall *cp1++ = *cp2; 172726049Sminshall break; 172826049Sminshall } 172926049Sminshall cp2++; 173026049Sminshall } 173126049Sminshall *cp1 = '\0'; 173226049Sminshall if (!*new) { 173326049Sminshall return(name); 173426049Sminshall } 173526049Sminshall return(new); 173626049Sminshall } 173726049Sminshall 173826049Sminshall setsunique() 173926049Sminshall { 174026049Sminshall sunique = !sunique; 174126049Sminshall printf("Store unique %s.\n", onoff(sunique)); 174226049Sminshall code = sunique; 174326049Sminshall } 174426049Sminshall 174526049Sminshall setrunique() 174626049Sminshall { 174726049Sminshall runique = !runique; 174826049Sminshall printf("Receive unique %s.\n", onoff(runique)); 174926049Sminshall code = runique; 175026049Sminshall } 175126049Sminshall 175226049Sminshall /* change directory to perent directory */ 175326049Sminshall cdup() 175426049Sminshall { 175526049Sminshall (void) command("CDUP"); 175626049Sminshall } 175726049Sminshall 175826049Sminshall macdef(argc, argv) 175926049Sminshall int argc; 176026049Sminshall char *argv[]; 176126049Sminshall { 176226049Sminshall char *tmp; 176326049Sminshall int c; 176426049Sminshall 176526049Sminshall if (macnum == 16) { 176626049Sminshall printf("Limit of 16 macros have already been defined\n"); 176726049Sminshall code = -1; 176826049Sminshall return; 176926049Sminshall } 177026049Sminshall if (argc < 2) { 177126497Sminshall (void) strcat(line, " "); 177226049Sminshall printf("(macro name) "); 177326497Sminshall (void) gets(&line[strlen(line)]); 177426049Sminshall makeargv(); 177526049Sminshall argc = margc; 177626049Sminshall argv = margv; 177726049Sminshall } 177826049Sminshall if (argc != 2) { 177926049Sminshall printf("Usage: %s macro_name\n",argv[0]); 178026049Sminshall code = -1; 178126049Sminshall return; 178226049Sminshall } 178326049Sminshall if (interactive) { 178426049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 178526049Sminshall } 178626497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 178726049Sminshall if (macnum == 0) { 178826049Sminshall macros[macnum].mac_start = macbuf; 178926049Sminshall } 179026049Sminshall else { 179126049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 179226049Sminshall } 179326049Sminshall tmp = macros[macnum].mac_start; 179426049Sminshall while (tmp != macbuf+4096) { 179526049Sminshall if ((c = getchar()) == EOF) { 179626049Sminshall printf("macdef:end of file encountered\n"); 179726049Sminshall code = -1; 179826049Sminshall return; 179926049Sminshall } 180026049Sminshall if ((*tmp = c) == '\n') { 180126049Sminshall if (tmp == macros[macnum].mac_start) { 180226049Sminshall macros[macnum++].mac_end = tmp; 180326049Sminshall code = 0; 180426049Sminshall return; 180526049Sminshall } 180626049Sminshall if (*(tmp-1) == '\0') { 180726049Sminshall macros[macnum++].mac_end = tmp - 1; 180826049Sminshall code = 0; 180926049Sminshall return; 181026049Sminshall } 181126049Sminshall *tmp = '\0'; 181226049Sminshall } 181326049Sminshall tmp++; 181426049Sminshall } 181526049Sminshall while (1) { 181626049Sminshall while ((c = getchar()) != '\n' && c != EOF); 181726049Sminshall if (c == EOF || getchar() == '\n') { 181826049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 181926049Sminshall code = -1; 182026049Sminshall return; 182126049Sminshall } 182226049Sminshall } 182326049Sminshall } 1824