121737Sdist /* 226049Sminshall * Copyright (c) 1985 Regents of the University of California. 3*33737Sbostic * All rights reserved. 4*33737Sbostic * 5*33737Sbostic * Redistribution and use in source and binary forms are permitted 6*33737Sbostic * provided that this notice is preserved and that due credit is given 7*33737Sbostic * to the University of California at Berkeley. The name of the University 8*33737Sbostic * may not be used to endorse or promote products derived from this 9*33737Sbostic * software without specific prior written permission. This software 10*33737Sbostic * is provided ``as is'' without express or implied warranty. 1121737Sdist */ 1221737Sdist 1310294Ssam #ifndef lint 14*33737Sbostic static char sccsid[] = "@(#)cmds.c 5.7 (Berkeley) 03/14/88"; 15*33737Sbostic #endif /* not lint */ 1610294Ssam 1710294Ssam /* 1810294Ssam * FTP User Program -- Command Routines. 1910294Ssam */ 2026049Sminshall #include "ftp_var.h" 2110294Ssam #include <sys/socket.h> 2210294Ssam 2312396Ssam #include <arpa/ftp.h> 2412396Ssam 2510294Ssam #include <signal.h> 2610294Ssam #include <stdio.h> 2710294Ssam #include <errno.h> 2810294Ssam #include <netdb.h> 2926049Sminshall #include <ctype.h> 3026497Sminshall #include <sys/wait.h> 3110294Ssam 3210294Ssam 3311353Ssam extern char *globerr; 3411353Ssam extern char **glob(); 3511756Ssam extern char *home; 3611353Ssam extern short gflag; 3711756Ssam extern char *remglob(); 3811756Ssam extern char *getenv(); 3911756Ssam extern char *index(); 4011756Ssam extern char *rindex(); 4126049Sminshall char *mname; 4226049Sminshall jmp_buf jabort; 4326049Sminshall char *dotrans(), *domap(); 4410294Ssam 4510294Ssam /* 4610294Ssam * Connect to peer server and 4710294Ssam * auto-login, if possible. 4810294Ssam */ 4910294Ssam setpeer(argc, argv) 5010294Ssam int argc; 5110294Ssam char *argv[]; 5210294Ssam { 5325903Skarels char *host, *hookup(); 5410294Ssam int port; 5510294Ssam 5610294Ssam if (connected) { 5726049Sminshall printf("Already connected to %s, use close first.\n", 5810294Ssam hostname); 5926049Sminshall code = -1; 6010294Ssam return; 6110294Ssam } 6210294Ssam if (argc < 2) { 6326497Sminshall (void) strcat(line, " "); 6410294Ssam printf("(to) "); 6526497Sminshall (void) gets(&line[strlen(line)]); 6610294Ssam makeargv(); 6710294Ssam argc = margc; 6810294Ssam argv = margv; 6910294Ssam } 7010294Ssam if (argc > 3) { 7110294Ssam printf("usage: %s host-name [port]\n", argv[0]); 7226049Sminshall code = -1; 7310294Ssam return; 7410294Ssam } 7510294Ssam port = sp->s_port; 7610294Ssam if (argc > 2) { 7711218Ssam port = atoi(argv[2]); 7810294Ssam if (port <= 0) { 7911218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 8011218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 8126049Sminshall code = -1; 8210294Ssam return; 8310294Ssam } 8410294Ssam port = htons(port); 8510294Ssam } 8610294Ssam host = hookup(argv[1], port); 8710294Ssam if (host) { 8810294Ssam connected = 1; 8910294Ssam if (autologin) 9026497Sminshall (void) login(argv[1]); 9110294Ssam } 9210294Ssam } 9310294Ssam 9410294Ssam struct types { 9510294Ssam char *t_name; 9610294Ssam char *t_mode; 9710294Ssam int t_type; 9811218Ssam char *t_arg; 9910294Ssam } types[] = { 10011218Ssam { "ascii", "A", TYPE_A, 0 }, 10111218Ssam { "binary", "I", TYPE_I, 0 }, 10211218Ssam { "image", "I", TYPE_I, 0 }, 10311218Ssam { "ebcdic", "E", TYPE_E, 0 }, 10411218Ssam { "tenex", "L", TYPE_L, bytename }, 10510294Ssam 0 10610294Ssam }; 10710294Ssam 10810294Ssam /* 10910294Ssam * Set transfer type. 11010294Ssam */ 11110294Ssam settype(argc, argv) 11210294Ssam char *argv[]; 11310294Ssam { 11410294Ssam register struct types *p; 11511218Ssam int comret; 11610294Ssam 11710294Ssam if (argc > 2) { 11810294Ssam char *sep; 11910294Ssam 12010294Ssam printf("usage: %s [", argv[0]); 12110294Ssam sep = " "; 12210294Ssam for (p = types; p->t_name; p++) { 12310294Ssam printf("%s%s", sep, p->t_name); 12410294Ssam if (*sep == ' ') 12510294Ssam sep = " | "; 12610294Ssam } 12710294Ssam printf(" ]\n"); 12826049Sminshall code = -1; 12910294Ssam return; 13010294Ssam } 13110294Ssam if (argc < 2) { 13210294Ssam printf("Using %s mode to transfer files.\n", typename); 13326049Sminshall code = 0; 13410294Ssam return; 13510294Ssam } 13610294Ssam for (p = types; p->t_name; p++) 13710294Ssam if (strcmp(argv[1], p->t_name) == 0) 13810294Ssam break; 13910294Ssam if (p->t_name == 0) { 14010294Ssam printf("%s: unknown mode\n", argv[1]); 14126049Sminshall code = -1; 14210294Ssam return; 14310294Ssam } 14411218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 14511218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 14611218Ssam else 14711218Ssam comret = command("TYPE %s", p->t_mode); 14811218Ssam if (comret == COMPLETE) { 14926497Sminshall (void) strcpy(typename, p->t_name); 15010294Ssam type = p->t_type; 15110294Ssam } 15210294Ssam } 15310294Ssam 15410294Ssam /* 15510294Ssam * Set binary transfer type. 15610294Ssam */ 15710294Ssam /*VARARGS*/ 15810294Ssam setbinary() 15910294Ssam { 16010294Ssam 16110294Ssam call(settype, "type", "binary", 0); 16210294Ssam } 16310294Ssam 16410294Ssam /* 16510294Ssam * Set ascii transfer type. 16610294Ssam */ 16710294Ssam /*VARARGS*/ 16810294Ssam setascii() 16910294Ssam { 17010294Ssam 17110294Ssam call(settype, "type", "ascii", 0); 17210294Ssam } 17310294Ssam 17410294Ssam /* 17510294Ssam * Set tenex transfer type. 17610294Ssam */ 17710294Ssam /*VARARGS*/ 17810294Ssam settenex() 17910294Ssam { 18010294Ssam 18110294Ssam call(settype, "type", "tenex", 0); 18210294Ssam } 18310294Ssam 18410294Ssam /* 18510294Ssam * Set ebcdic transfer type. 18610294Ssam */ 18710294Ssam /*VARARGS*/ 18810294Ssam setebcdic() 18910294Ssam { 19010294Ssam 19110294Ssam call(settype, "type", "ebcdic", 0); 19210294Ssam } 19310294Ssam 19410294Ssam /* 19510294Ssam * Set file transfer mode. 19610294Ssam */ 19726497Sminshall /*ARGSUSED*/ 19810294Ssam setmode(argc, argv) 19910294Ssam char *argv[]; 20010294Ssam { 20110294Ssam 20210294Ssam printf("We only support %s mode, sorry.\n", modename); 20326049Sminshall code = -1; 20410294Ssam } 20510294Ssam 20610294Ssam /* 20710294Ssam * Set file transfer format. 20810294Ssam */ 20926497Sminshall /*ARGSUSED*/ 21010294Ssam setform(argc, argv) 21110294Ssam char *argv[]; 21210294Ssam { 21310294Ssam 21410294Ssam printf("We only support %s format, sorry.\n", formname); 21526049Sminshall code = -1; 21610294Ssam } 21710294Ssam 21810294Ssam /* 21910294Ssam * Set file transfer structure. 22010294Ssam */ 22126497Sminshall /*ARGSUSED*/ 22210294Ssam setstruct(argc, argv) 22310294Ssam char *argv[]; 22410294Ssam { 22510294Ssam 22610294Ssam printf("We only support %s structure, sorry.\n", structname); 22726049Sminshall code = -1; 22810294Ssam } 22910294Ssam 23018286Sralph /* 23118286Sralph * Send a single file. 23218286Sralph */ 23310294Ssam put(argc, argv) 23411756Ssam int argc; 23510294Ssam char *argv[]; 23610294Ssam { 23711650Ssam char *cmd; 23826049Sminshall int loc = 0; 23925908Smckusick char *oldargv1; 24011650Ssam 24126049Sminshall if (argc == 2) { 24226049Sminshall argc++; 24326049Sminshall argv[2] = argv[1]; 24426049Sminshall loc++; 24526049Sminshall } 24610294Ssam if (argc < 2) { 24726497Sminshall (void) strcat(line, " "); 24810294Ssam printf("(local-file) "); 24926497Sminshall (void) gets(&line[strlen(line)]); 25010294Ssam makeargv(); 25110294Ssam argc = margc; 25210294Ssam argv = margv; 25310294Ssam } 25410294Ssam if (argc < 2) { 25510294Ssam usage: 25626049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 25726049Sminshall code = -1; 25810294Ssam return; 25910294Ssam } 26010294Ssam if (argc < 3) { 26126497Sminshall (void) strcat(line, " "); 26210294Ssam printf("(remote-file) "); 26326497Sminshall (void) gets(&line[strlen(line)]); 26410294Ssam makeargv(); 26510294Ssam argc = margc; 26610294Ssam argv = margv; 26710294Ssam } 26810294Ssam if (argc < 3) 26910294Ssam goto usage; 27025908Smckusick oldargv1 = argv[1]; 27126049Sminshall if (!globulize(&argv[1])) { 27226049Sminshall code = -1; 27311353Ssam return; 27426049Sminshall } 27525908Smckusick /* 27625908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 27725908Smckusick * the old argv[1], make it a copy of the new argv[1]. 27825908Smckusick */ 27926049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 28025908Smckusick argv[2] = argv[1]; 28126049Sminshall } 28226049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 28326049Sminshall if (loc && ntflag) { 28426049Sminshall argv[2] = dotrans(argv[2]); 28526049Sminshall } 28626049Sminshall if (loc && mapflag) { 28726049Sminshall argv[2] = domap(argv[2]); 28826049Sminshall } 28911650Ssam sendrequest(cmd, argv[1], argv[2]); 29010294Ssam } 29110294Ssam 29210294Ssam /* 29311756Ssam * Send multiple files. 29410294Ssam */ 29511353Ssam mput(argc, argv) 29611353Ssam char *argv[]; 29711353Ssam { 29813212Ssam register int i; 29926049Sminshall int ointer, (*oldintr)(), mabort(); 30026049Sminshall extern jmp_buf jabort; 30126049Sminshall char *tp; 30211353Ssam 30311650Ssam if (argc < 2) { 30426497Sminshall (void) strcat(line, " "); 30511650Ssam printf("(local-files) "); 30626497Sminshall (void) gets(&line[strlen(line)]); 30711650Ssam makeargv(); 30811650Ssam argc = margc; 30911650Ssam argv = margv; 31011353Ssam } 31111353Ssam if (argc < 2) { 31226049Sminshall printf("usage:%s local-files\n", argv[0]); 31326049Sminshall code = -1; 31411353Ssam return; 31511353Ssam } 31626049Sminshall mname = argv[0]; 31726049Sminshall mflag = 1; 31826049Sminshall oldintr = signal(SIGINT, mabort); 31926049Sminshall (void) setjmp(jabort); 32026049Sminshall if (proxy) { 32126049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 32226049Sminshall 32326497Sminshall while ((cp = remglob(argv,0)) != NULL) { 32426049Sminshall if (*cp == 0) { 32526049Sminshall mflag = 0; 32626049Sminshall continue; 32726049Sminshall } 32826049Sminshall if (mflag && confirm(argv[0], cp)) { 32926049Sminshall tp = cp; 33026049Sminshall if (mcase) { 33126049Sminshall while (*tp && !islower(*tp)) { 33226049Sminshall tp++; 33326049Sminshall } 33426049Sminshall if (!*tp) { 33526049Sminshall tp = cp; 33626049Sminshall tp2 = tmpbuf; 33726049Sminshall while ((*tp2 = *tp) != NULL) { 33826049Sminshall if (isupper(*tp2)) { 33926049Sminshall *tp2 = 'a' + *tp2 - 'A'; 34026049Sminshall } 34126049Sminshall tp++; 34226049Sminshall tp2++; 34326049Sminshall } 34426049Sminshall } 34526049Sminshall tp = tmpbuf; 34626049Sminshall } 34726049Sminshall if (ntflag) { 34826049Sminshall tp = dotrans(tp); 34926049Sminshall } 35026049Sminshall if (mapflag) { 35126049Sminshall tp = domap(tp); 35226049Sminshall } 35326049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 35426049Sminshall if (!mflag && fromatty) { 35526049Sminshall ointer = interactive; 35626049Sminshall interactive = 1; 35726049Sminshall if (confirm("Continue with","mput")) { 35826049Sminshall mflag++; 35926049Sminshall } 36026049Sminshall interactive = ointer; 36126049Sminshall } 36226049Sminshall } 36326049Sminshall } 36426049Sminshall (void) signal(SIGINT, oldintr); 36526049Sminshall mflag = 0; 36626049Sminshall return; 36726049Sminshall } 36813212Ssam for (i = 1; i < argc; i++) { 36913212Ssam register char **cpp, **gargs; 37013212Ssam 37113212Ssam if (!doglob) { 37226049Sminshall if (mflag && confirm(argv[0], argv[i])) { 37326049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 37426049Sminshall tp = (mapflag) ? domap(tp) : tp; 37526049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 37626049Sminshall argv[i], tp); 37726049Sminshall if (!mflag && fromatty) { 37826049Sminshall ointer = interactive; 37926049Sminshall interactive = 1; 38026049Sminshall if (confirm("Continue with","mput")) { 38126049Sminshall mflag++; 38226049Sminshall } 38326049Sminshall interactive = ointer; 38426049Sminshall } 38526049Sminshall } 38613212Ssam continue; 38713212Ssam } 38813212Ssam gargs = glob(argv[i]); 38911650Ssam if (globerr != NULL) { 39011650Ssam printf("%s\n", globerr); 39111650Ssam if (gargs) 39211650Ssam blkfree(gargs); 39313212Ssam continue; 39411353Ssam } 39526049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 39626049Sminshall if (mflag && confirm(argv[0], *cpp)) { 39726049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 39826049Sminshall tp = (mapflag) ? domap(tp) : tp; 39926049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 40026049Sminshall *cpp, tp); 40126049Sminshall if (!mflag && fromatty) { 40226049Sminshall ointer = interactive; 40326049Sminshall interactive = 1; 40426049Sminshall if (confirm("Continue with","mput")) { 40526049Sminshall mflag++; 40626049Sminshall } 40726049Sminshall interactive = ointer; 40826049Sminshall } 40926049Sminshall } 41026049Sminshall } 41113212Ssam if (gargs != NULL) 41213212Ssam blkfree(gargs); 41311353Ssam } 41426049Sminshall (void) signal(SIGINT, oldintr); 41526049Sminshall mflag = 0; 41611353Ssam } 41711353Ssam 41811353Ssam /* 41911353Ssam * Receive one file. 42011353Ssam */ 42110294Ssam get(argc, argv) 42210294Ssam char *argv[]; 42310294Ssam { 42426049Sminshall int loc = 0; 42510294Ssam 42626049Sminshall if (argc == 2) { 42726049Sminshall argc++; 42826049Sminshall argv[2] = argv[1]; 42926049Sminshall loc++; 43026049Sminshall } 43110294Ssam if (argc < 2) { 43226497Sminshall (void) strcat(line, " "); 43310294Ssam printf("(remote-file) "); 43426497Sminshall (void) gets(&line[strlen(line)]); 43510294Ssam makeargv(); 43610294Ssam argc = margc; 43710294Ssam argv = margv; 43810294Ssam } 43910294Ssam if (argc < 2) { 44010294Ssam usage: 44126049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 44226049Sminshall code = -1; 44310294Ssam return; 44410294Ssam } 44510294Ssam if (argc < 3) { 44626497Sminshall (void) strcat(line, " "); 44710294Ssam printf("(local-file) "); 44826497Sminshall (void) gets(&line[strlen(line)]); 44910294Ssam makeargv(); 45010294Ssam argc = margc; 45110294Ssam argv = margv; 45210294Ssam } 45310294Ssam if (argc < 3) 45410294Ssam goto usage; 45526049Sminshall if (!globulize(&argv[2])) { 45626049Sminshall code = -1; 45711353Ssam return; 45826049Sminshall } 45926049Sminshall if (loc && mcase) { 46026049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 46126049Sminshall 46226049Sminshall while (*tp && !islower(*tp)) { 46326049Sminshall tp++; 46426049Sminshall } 46526049Sminshall if (!*tp) { 46626049Sminshall tp = argv[2]; 46726049Sminshall tp2 = tmpbuf; 46826049Sminshall while ((*tp2 = *tp) != NULL) { 46926049Sminshall if (isupper(*tp2)) { 47026049Sminshall *tp2 = 'a' + *tp2 - 'A'; 47126049Sminshall } 47226049Sminshall tp++; 47326049Sminshall tp2++; 47426049Sminshall } 47526049Sminshall argv[2] = tmpbuf; 47626049Sminshall } 47726049Sminshall } 47826049Sminshall if (loc && ntflag) { 47926049Sminshall argv[2] = dotrans(argv[2]); 48026049Sminshall } 48126049Sminshall if (loc && mapflag) { 48226049Sminshall argv[2] = domap(argv[2]); 48326049Sminshall } 48411650Ssam recvrequest("RETR", argv[2], argv[1], "w"); 48510294Ssam } 48610294Ssam 48726049Sminshall mabort() 48826049Sminshall { 48926049Sminshall int ointer; 49026049Sminshall extern jmp_buf jabort; 49126049Sminshall 49226049Sminshall printf("\n"); 49326049Sminshall (void) fflush(stdout); 49426049Sminshall if (mflag && fromatty) { 49526049Sminshall ointer = interactive; 49626049Sminshall interactive = 1; 49726049Sminshall if (confirm("Continue with", mname)) { 49826049Sminshall interactive = ointer; 49926049Sminshall longjmp(jabort,0); 50026049Sminshall } 50126049Sminshall interactive = ointer; 50226049Sminshall } 50326049Sminshall mflag = 0; 50426049Sminshall longjmp(jabort,0); 50526049Sminshall } 50626049Sminshall 50711353Ssam /* 50811353Ssam * Get multiple files. 50911353Ssam */ 51011353Ssam mget(argc, argv) 51111353Ssam char *argv[]; 51211353Ssam { 51326049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 51426049Sminshall int ointer, (*oldintr)(), mabort(); 51526049Sminshall extern jmp_buf jabort; 51611353Ssam 51711353Ssam if (argc < 2) { 51826497Sminshall (void) strcat(line, " "); 51911756Ssam printf("(remote-files) "); 52026497Sminshall (void) gets(&line[strlen(line)]); 52111353Ssam makeargv(); 52211353Ssam argc = margc; 52311353Ssam argv = margv; 52411353Ssam } 52511353Ssam if (argc < 2) { 52626049Sminshall printf("usage:%s remote-files\n", argv[0]); 52726049Sminshall code = -1; 52811353Ssam return; 52911353Ssam } 53026049Sminshall mname = argv[0]; 53126049Sminshall mflag = 1; 53226049Sminshall oldintr = signal(SIGINT,mabort); 53326049Sminshall (void) setjmp(jabort); 53426497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 53526049Sminshall if (*cp == '\0') { 53626049Sminshall mflag = 0; 53726049Sminshall continue; 53826049Sminshall } 53926049Sminshall if (mflag && confirm(argv[0], cp)) { 54026049Sminshall tp = cp; 54126049Sminshall if (mcase) { 54226049Sminshall while (*tp && !islower(*tp)) { 54326049Sminshall tp++; 54426049Sminshall } 54526049Sminshall if (!*tp) { 54626049Sminshall tp = cp; 54726049Sminshall tp2 = tmpbuf; 54826049Sminshall while ((*tp2 = *tp) != NULL) { 54926049Sminshall if (isupper(*tp2)) { 55026049Sminshall *tp2 = 'a' + *tp2 - 'A'; 55126049Sminshall } 55226049Sminshall tp++; 55326049Sminshall tp2++; 55426049Sminshall } 55526049Sminshall } 55626049Sminshall tp = tmpbuf; 55726049Sminshall } 55826049Sminshall if (ntflag) { 55926049Sminshall tp = dotrans(tp); 56026049Sminshall } 56126049Sminshall if (mapflag) { 56226049Sminshall tp = domap(tp); 56326049Sminshall } 56426049Sminshall recvrequest("RETR", tp, cp, "w"); 56526049Sminshall if (!mflag && fromatty) { 56626049Sminshall ointer = interactive; 56726049Sminshall interactive = 1; 56826049Sminshall if (confirm("Continue with","mget")) { 56926049Sminshall mflag++; 57026049Sminshall } 57126049Sminshall interactive = ointer; 57226049Sminshall } 57326049Sminshall } 57426049Sminshall } 57526049Sminshall (void) signal(SIGINT,oldintr); 57626049Sminshall mflag = 0; 57711650Ssam } 57811650Ssam 57911650Ssam char * 58026497Sminshall remglob(argv,doswitch) 58111650Ssam char *argv[]; 58226497Sminshall int doswitch; 58311650Ssam { 58411756Ssam char temp[16]; 58511650Ssam static char buf[MAXPATHLEN]; 58611650Ssam static FILE *ftemp = NULL; 58711650Ssam static char **args; 58813212Ssam int oldverbose, oldhash; 58911756Ssam char *cp, *mode; 59011650Ssam 59126049Sminshall if (!mflag) { 59226049Sminshall if (!doglob) { 59326049Sminshall args = NULL; 59426049Sminshall } 59526049Sminshall else { 59626049Sminshall if (ftemp) { 59726497Sminshall (void) fclose(ftemp); 59826049Sminshall ftemp = NULL; 59926049Sminshall } 60026049Sminshall } 60126049Sminshall return(NULL); 60226049Sminshall } 60311650Ssam if (!doglob) { 60411756Ssam if (args == NULL) 60511650Ssam args = argv; 60611650Ssam if ((cp = *++args) == NULL) 60711650Ssam args = NULL; 60811650Ssam return (cp); 60911353Ssam } 61011650Ssam if (ftemp == NULL) { 61126497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 61226497Sminshall (void) mktemp(temp); 61311650Ssam oldverbose = verbose, verbose = 0; 61413212Ssam oldhash = hash, hash = 0; 61526049Sminshall if (doswitch) { 61626049Sminshall pswitch(!proxy); 61726049Sminshall } 61811756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 61911756Ssam recvrequest ("NLST", temp, *argv, mode); 62026049Sminshall if (doswitch) { 62126049Sminshall pswitch(!proxy); 62226049Sminshall } 62313212Ssam verbose = oldverbose; hash = oldhash; 62411650Ssam ftemp = fopen(temp, "r"); 62526497Sminshall (void) unlink(temp); 62611650Ssam if (ftemp == NULL) { 62711650Ssam printf("can't find list of remote files, oops\n"); 62811756Ssam return (NULL); 62911353Ssam } 63011353Ssam } 63111650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 63226497Sminshall (void) fclose(ftemp), ftemp = NULL; 63311650Ssam return (NULL); 63411353Ssam } 63511650Ssam if ((cp = index(buf, '\n')) != NULL) 63611650Ssam *cp = '\0'; 63711650Ssam return (buf); 63811353Ssam } 63911353Ssam 64010294Ssam char * 64110294Ssam onoff(bool) 64210294Ssam int bool; 64310294Ssam { 64410294Ssam 64510294Ssam return (bool ? "on" : "off"); 64610294Ssam } 64710294Ssam 64810294Ssam /* 64910294Ssam * Show status. 65010294Ssam */ 65126497Sminshall /*ARGSUSED*/ 65210294Ssam status(argc, argv) 65310294Ssam char *argv[]; 65410294Ssam { 65526049Sminshall int i; 65610294Ssam 65710294Ssam if (connected) 65810294Ssam printf("Connected to %s.\n", hostname); 65910294Ssam else 66010294Ssam printf("Not connected.\n"); 66126049Sminshall if (!proxy) { 66226049Sminshall pswitch(1); 66326049Sminshall if (connected) { 66426049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 66526049Sminshall } 66626049Sminshall else { 66726049Sminshall printf("No proxy connection.\n"); 66826049Sminshall } 66926049Sminshall pswitch(0); 67026049Sminshall } 67110294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 67210294Ssam modename, typename, formname, structname); 67311353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 67411353Ssam onoff(verbose), onoff(bell), onoff(interactive), 67511353Ssam onoff(doglob)); 67626049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 67726049Sminshall onoff(runique)); 67826049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 67926049Sminshall if (ntflag) { 68026049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 68126049Sminshall } 68226049Sminshall else { 68326049Sminshall printf("Ntrans: off\n"); 68426049Sminshall } 68526049Sminshall if (mapflag) { 68626049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 68726049Sminshall } 68826049Sminshall else { 68926049Sminshall printf("Nmap: off\n"); 69026049Sminshall } 69114143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 69214143Ssam onoff(hash), onoff(sendport)); 69326049Sminshall if (macnum > 0) { 69426049Sminshall printf("Macros:\n"); 69526049Sminshall for (i=0; i<macnum; i++) { 69626049Sminshall printf("\t%s\n",macros[i].mac_name); 69726049Sminshall } 69826049Sminshall } 69926049Sminshall code = 0; 70010294Ssam } 70110294Ssam 70210294Ssam /* 70310294Ssam * Set beep on cmd completed mode. 70410294Ssam */ 70510294Ssam /*VARARGS*/ 70610294Ssam setbell() 70710294Ssam { 70810294Ssam 70910294Ssam bell = !bell; 71010294Ssam printf("Bell mode %s.\n", onoff(bell)); 71126049Sminshall code = bell; 71210294Ssam } 71310294Ssam 71410294Ssam /* 71510294Ssam * Turn on packet tracing. 71610294Ssam */ 71710294Ssam /*VARARGS*/ 71810294Ssam settrace() 71910294Ssam { 72010294Ssam 72110294Ssam trace = !trace; 72210294Ssam printf("Packet tracing %s.\n", onoff(trace)); 72326049Sminshall code = trace; 72410294Ssam } 72510294Ssam 72610294Ssam /* 72711650Ssam * Toggle hash mark printing during transfers. 72811650Ssam */ 72911650Ssam /*VARARGS*/ 73011650Ssam sethash() 73111650Ssam { 73211650Ssam 73311650Ssam hash = !hash; 73411650Ssam printf("Hash mark printing %s", onoff(hash)); 73526049Sminshall code = hash; 73611650Ssam if (hash) 73711650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 73811650Ssam printf(".\n"); 73911650Ssam } 74011650Ssam 74111650Ssam /* 74210294Ssam * Turn on printing of server echo's. 74310294Ssam */ 74410294Ssam /*VARARGS*/ 74510294Ssam setverbose() 74610294Ssam { 74710294Ssam 74810294Ssam verbose = !verbose; 74910294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 75026049Sminshall code = verbose; 75110294Ssam } 75210294Ssam 75310294Ssam /* 75411650Ssam * Toggle PORT cmd use before each data connection. 75511650Ssam */ 75611650Ssam /*VARARGS*/ 75711650Ssam setport() 75811650Ssam { 75911650Ssam 76011650Ssam sendport = !sendport; 76111650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 76226049Sminshall code = sendport; 76311650Ssam } 76411650Ssam 76511650Ssam /* 76610294Ssam * Turn on interactive prompting 76710294Ssam * during mget, mput, and mdelete. 76810294Ssam */ 76910294Ssam /*VARARGS*/ 77010294Ssam setprompt() 77110294Ssam { 77210294Ssam 77310294Ssam interactive = !interactive; 77410294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 77526049Sminshall code = interactive; 77610294Ssam } 77710294Ssam 77810294Ssam /* 77911353Ssam * Toggle metacharacter interpretation 78011353Ssam * on local file names. 78111353Ssam */ 78211353Ssam /*VARARGS*/ 78311353Ssam setglob() 78411353Ssam { 78511353Ssam 78611353Ssam doglob = !doglob; 78711353Ssam printf("Globbing %s.\n", onoff(doglob)); 78826049Sminshall code = doglob; 78911353Ssam } 79011353Ssam 79111353Ssam /* 79210294Ssam * Set debugging mode on/off and/or 79310294Ssam * set level of debugging. 79410294Ssam */ 79511756Ssam /*VARARGS*/ 79610294Ssam setdebug(argc, argv) 79710294Ssam char *argv[]; 79810294Ssam { 79910294Ssam int val; 80010294Ssam 80110294Ssam if (argc > 1) { 80210294Ssam val = atoi(argv[1]); 80310294Ssam if (val < 0) { 80410294Ssam printf("%s: bad debugging value.\n", argv[1]); 80526049Sminshall code = -1; 80610294Ssam return; 80710294Ssam } 80810294Ssam } else 80910294Ssam val = !debug; 81010294Ssam debug = val; 81110294Ssam if (debug) 81210294Ssam options |= SO_DEBUG; 81310294Ssam else 81410294Ssam options &= ~SO_DEBUG; 81510294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 81626049Sminshall code = debug > 0; 81710294Ssam } 81810294Ssam 81910294Ssam /* 82010294Ssam * Set current working directory 82110294Ssam * on remote machine. 82210294Ssam */ 82310294Ssam cd(argc, argv) 82410294Ssam char *argv[]; 82510294Ssam { 82610294Ssam 82710294Ssam if (argc < 2) { 82826497Sminshall (void) strcat(line, " "); 82910294Ssam printf("(remote-directory) "); 83026497Sminshall (void) gets(&line[strlen(line)]); 83110294Ssam makeargv(); 83210294Ssam argc = margc; 83310294Ssam argv = margv; 83410294Ssam } 83510294Ssam if (argc < 2) { 83626049Sminshall printf("usage:%s remote-directory\n", argv[0]); 83726049Sminshall code = -1; 83810294Ssam return; 83910294Ssam } 84010294Ssam (void) command("CWD %s", argv[1]); 84110294Ssam } 84210294Ssam 84310294Ssam /* 84410294Ssam * Set current working directory 84510294Ssam * on local machine. 84610294Ssam */ 84710294Ssam lcd(argc, argv) 84810294Ssam char *argv[]; 84910294Ssam { 85011353Ssam char buf[MAXPATHLEN]; 85110294Ssam 85211353Ssam if (argc < 2) 85311353Ssam argc++, argv[1] = home; 85410294Ssam if (argc != 2) { 85526049Sminshall printf("usage:%s local-directory\n", argv[0]); 85626049Sminshall code = -1; 85710294Ssam return; 85810294Ssam } 85926049Sminshall if (!globulize(&argv[1])) { 86026049Sminshall code = -1; 86111353Ssam return; 86226049Sminshall } 86311353Ssam if (chdir(argv[1]) < 0) { 86410294Ssam perror(argv[1]); 86526049Sminshall code = -1; 86611353Ssam return; 86711353Ssam } 86811353Ssam printf("Local directory now %s\n", getwd(buf)); 86926049Sminshall code = 0; 87010294Ssam } 87110294Ssam 87210294Ssam /* 87310294Ssam * Delete a single file. 87410294Ssam */ 87510294Ssam delete(argc, argv) 87610294Ssam char *argv[]; 87710294Ssam { 87810294Ssam 87910294Ssam if (argc < 2) { 88026497Sminshall (void) strcat(line, " "); 88110294Ssam printf("(remote-file) "); 88226497Sminshall (void) gets(&line[strlen(line)]); 88310294Ssam makeargv(); 88410294Ssam argc = margc; 88510294Ssam argv = margv; 88610294Ssam } 88710294Ssam if (argc < 2) { 88826049Sminshall printf("usage:%s remote-file\n", argv[0]); 88926049Sminshall code = -1; 89010294Ssam return; 89110294Ssam } 89210294Ssam (void) command("DELE %s", argv[1]); 89310294Ssam } 89410294Ssam 89510294Ssam /* 89611650Ssam * Delete multiple files. 89711650Ssam */ 89811650Ssam mdelete(argc, argv) 89911650Ssam char *argv[]; 90011650Ssam { 90111650Ssam char *cp; 90226049Sminshall int ointer, (*oldintr)(), mabort(); 90326049Sminshall extern jmp_buf jabort; 90411650Ssam 90511650Ssam if (argc < 2) { 90626497Sminshall (void) strcat(line, " "); 90711650Ssam printf("(remote-files) "); 90826497Sminshall (void) gets(&line[strlen(line)]); 90911650Ssam makeargv(); 91011650Ssam argc = margc; 91111650Ssam argv = margv; 91211650Ssam } 91311650Ssam if (argc < 2) { 91426049Sminshall printf("usage:%s remote-files\n", argv[0]); 91526049Sminshall code = -1; 91611650Ssam return; 91711650Ssam } 91826049Sminshall mname = argv[0]; 91926049Sminshall mflag = 1; 92026049Sminshall oldintr = signal(SIGINT, mabort); 92126049Sminshall (void) setjmp(jabort); 92226497Sminshall while ((cp = remglob(argv,0)) != NULL) { 92326049Sminshall if (*cp == '\0') { 92426049Sminshall mflag = 0; 92526049Sminshall continue; 92626049Sminshall } 92726049Sminshall if (mflag && confirm(argv[0], cp)) { 92811650Ssam (void) command("DELE %s", cp); 92926049Sminshall if (!mflag && fromatty) { 93026049Sminshall ointer = interactive; 93126049Sminshall interactive = 1; 93226049Sminshall if (confirm("Continue with", "mdelete")) { 93326049Sminshall mflag++; 93426049Sminshall } 93526049Sminshall interactive = ointer; 93626049Sminshall } 93726049Sminshall } 93826049Sminshall } 93926049Sminshall (void) signal(SIGINT, oldintr); 94026049Sminshall mflag = 0; 94111650Ssam } 94211756Ssam 94311650Ssam /* 94410294Ssam * Rename a remote file. 94510294Ssam */ 94610294Ssam renamefile(argc, argv) 94710294Ssam char *argv[]; 94810294Ssam { 94910294Ssam 95010294Ssam if (argc < 2) { 95126497Sminshall (void) strcat(line, " "); 95210294Ssam printf("(from-name) "); 95326497Sminshall (void) gets(&line[strlen(line)]); 95410294Ssam makeargv(); 95510294Ssam argc = margc; 95610294Ssam argv = margv; 95710294Ssam } 95810294Ssam if (argc < 2) { 95910294Ssam usage: 96010294Ssam printf("%s from-name to-name\n", argv[0]); 96126049Sminshall code = -1; 96210294Ssam return; 96310294Ssam } 96410294Ssam if (argc < 3) { 96526497Sminshall (void) strcat(line, " "); 96610294Ssam printf("(to-name) "); 96726497Sminshall (void) gets(&line[strlen(line)]); 96810294Ssam makeargv(); 96910294Ssam argc = margc; 97010294Ssam argv = margv; 97110294Ssam } 97210294Ssam if (argc < 3) 97310294Ssam goto usage; 97410294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 97510294Ssam (void) command("RNTO %s", argv[2]); 97610294Ssam } 97710294Ssam 97810294Ssam /* 97910294Ssam * Get a directory listing 98010294Ssam * of remote files. 98110294Ssam */ 98210294Ssam ls(argc, argv) 98310294Ssam char *argv[]; 98410294Ssam { 98511756Ssam char *cmd; 98610294Ssam 98710294Ssam if (argc < 2) 98810294Ssam argc++, argv[1] = NULL; 98910294Ssam if (argc < 3) 99010294Ssam argc++, argv[2] = "-"; 99111756Ssam if (argc > 3) { 99211756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 99326049Sminshall code = -1; 99411756Ssam return; 99511756Ssam } 99610294Ssam cmd = argv[0][0] == 'l' ? "NLST" : "LIST"; 99726049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 99826049Sminshall code = -1; 99911353Ssam return; 100026049Sminshall } 100132344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 100232344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 100332344Scsvsj code = -1; 100432344Scsvsj return; 100532344Scsvsj } 100611756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 100710294Ssam } 100810294Ssam 100910294Ssam /* 101011756Ssam * Get a directory listing 101111756Ssam * of multiple remote files. 101211756Ssam */ 101311756Ssam mls(argc, argv) 101411756Ssam char *argv[]; 101511756Ssam { 101626049Sminshall char *cmd, mode[1], *dest; 101726049Sminshall int ointer, i, (*oldintr)(), mabort(); 101826049Sminshall extern jmp_buf jabort; 101911756Ssam 102013212Ssam if (argc < 2) { 102126497Sminshall (void) strcat(line, " "); 102213212Ssam printf("(remote-files) "); 102326497Sminshall (void) gets(&line[strlen(line)]); 102413212Ssam makeargv(); 102513212Ssam argc = margc; 102613212Ssam argv = margv; 102713212Ssam } 102813212Ssam if (argc < 3) { 102926497Sminshall (void) strcat(line, " "); 103013212Ssam printf("(local-file) "); 103126497Sminshall (void) gets(&line[strlen(line)]); 103213212Ssam makeargv(); 103313212Ssam argc = margc; 103413212Ssam argv = margv; 103513212Ssam } 103613212Ssam if (argc < 3) { 103726049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 103826049Sminshall code = -1; 103913212Ssam return; 104013212Ssam } 104113212Ssam dest = argv[argc - 1]; 104213212Ssam argv[argc - 1] = NULL; 104326049Sminshall if (strcmp(dest, "-") && *dest != '|') 104426049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 104526049Sminshall code = -1; 104613212Ssam return; 104726049Sminshall } 104811756Ssam cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 104926049Sminshall mname = argv[0]; 105026049Sminshall mflag = 1; 105126049Sminshall oldintr = signal(SIGINT, mabort); 105226049Sminshall (void) setjmp(jabort); 105326049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 105426049Sminshall *mode = (i == 1) ? 'w' : 'a'; 105526049Sminshall recvrequest(cmd, dest, argv[i], mode); 105626049Sminshall if (!mflag && fromatty) { 105726049Sminshall ointer = interactive; 105826049Sminshall interactive = 1; 105926049Sminshall if (confirm("Continue with", argv[0])) { 106026049Sminshall mflag ++; 106126049Sminshall } 106226049Sminshall interactive = ointer; 106326049Sminshall } 106426049Sminshall } 106526049Sminshall (void) signal(SIGINT, oldintr); 106626049Sminshall mflag = 0; 106711756Ssam } 106811756Ssam 106911756Ssam /* 107010294Ssam * Do a shell escape 107110294Ssam */ 107226497Sminshall /*ARGSUSED*/ 107310294Ssam shell(argc, argv) 107410294Ssam char *argv[]; 107510294Ssam { 107626497Sminshall int pid, (*old1)(), (*old2)(); 107726049Sminshall char shellnam[40], *shell, *namep; 107826497Sminshall union wait status; 107910294Ssam 108011756Ssam old1 = signal (SIGINT, SIG_IGN); 108111756Ssam old2 = signal (SIGQUIT, SIG_IGN); 108211756Ssam if ((pid = fork()) == 0) { 108311756Ssam for (pid = 3; pid < 20; pid++) 108426497Sminshall (void) close(pid); 108526497Sminshall (void) signal(SIGINT, SIG_DFL); 108626497Sminshall (void) signal(SIGQUIT, SIG_DFL); 108725908Smckusick shell = getenv("SHELL"); 108825908Smckusick if (shell == NULL) 108925908Smckusick shell = "/bin/sh"; 109025908Smckusick namep = rindex(shell,'/'); 109125908Smckusick if (namep == NULL) 109225908Smckusick namep = shell; 109326497Sminshall (void) strcpy(shellnam,"-"); 109426497Sminshall (void) strcat(shellnam, ++namep); 109526049Sminshall if (strcmp(namep, "sh") != 0) 109626049Sminshall shellnam[0] = '+'; 109726049Sminshall if (debug) { 109826049Sminshall printf ("%s\n", shell); 109926497Sminshall (void) fflush (stdout); 110011756Ssam } 110126049Sminshall if (argc > 1) { 110226049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 110326049Sminshall } 110426049Sminshall else { 110526049Sminshall execl(shell,shellnam,(char *)0); 110626049Sminshall } 110725908Smckusick perror(shell); 110826049Sminshall code = -1; 110911756Ssam exit(1); 111026049Sminshall } 111111756Ssam if (pid > 0) 111211756Ssam while (wait(&status) != pid) 111311756Ssam ; 111426497Sminshall (void) signal(SIGINT, old1); 111526497Sminshall (void) signal(SIGQUIT, old2); 111626049Sminshall if (pid == -1) { 111711756Ssam perror("Try again later"); 111826049Sminshall code = -1; 111926049Sminshall } 112026049Sminshall else { 112126049Sminshall code = 0; 112226049Sminshall } 112311756Ssam return (0); 112410294Ssam } 112510294Ssam 112610294Ssam /* 112710294Ssam * Send new user information (re-login) 112810294Ssam */ 112910294Ssam user(argc, argv) 113010294Ssam int argc; 113110294Ssam char **argv; 113210294Ssam { 113326497Sminshall char acct[80], *mygetpass(); 113426049Sminshall int n, aflag = 0; 113510294Ssam 113610294Ssam if (argc < 2) { 113726497Sminshall (void) strcat(line, " "); 113810294Ssam printf("(username) "); 113926497Sminshall (void) gets(&line[strlen(line)]); 114010294Ssam makeargv(); 114110294Ssam argc = margc; 114210294Ssam argv = margv; 114310294Ssam } 114410294Ssam if (argc > 4) { 114510294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 114626049Sminshall code = -1; 114711756Ssam return (0); 114810294Ssam } 114910294Ssam n = command("USER %s", argv[1]); 115010294Ssam if (n == CONTINUE) { 115110294Ssam if (argc < 3 ) 115226497Sminshall argv[2] = mygetpass("Password: "), argc++; 115310294Ssam n = command("PASS %s", argv[2]); 115410294Ssam } 115510294Ssam if (n == CONTINUE) { 115610294Ssam if (argc < 4) { 115710294Ssam printf("Account: "); (void) fflush(stdout); 115810294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 115910294Ssam acct[strlen(acct) - 1] = '\0'; 116010294Ssam argv[3] = acct; argc++; 116110294Ssam } 116226049Sminshall n = command("ACCT %s", argv[3]); 116326049Sminshall aflag++; 116410294Ssam } 116510294Ssam if (n != COMPLETE) { 116626497Sminshall fprintf(stdout, "Login failed.\n"); 116710294Ssam return (0); 116810294Ssam } 116926049Sminshall if (!aflag && argc == 4) { 117026049Sminshall (void) command("ACCT %s", argv[3]); 117126049Sminshall } 117210294Ssam return (1); 117310294Ssam } 117410294Ssam 117510294Ssam /* 117610294Ssam * Print working directory. 117710294Ssam */ 117810294Ssam /*VARARGS*/ 117910294Ssam pwd() 118010294Ssam { 118111756Ssam 118226049Sminshall (void) command("PWD"); 118310294Ssam } 118410294Ssam 118510294Ssam /* 118610294Ssam * Make a directory. 118710294Ssam */ 118810294Ssam makedir(argc, argv) 118910294Ssam char *argv[]; 119010294Ssam { 119110294Ssam 119210294Ssam if (argc < 2) { 119326497Sminshall (void) strcat(line, " "); 119410294Ssam printf("(directory-name) "); 119526497Sminshall (void) gets(&line[strlen(line)]); 119610294Ssam makeargv(); 119710294Ssam argc = margc; 119810294Ssam argv = margv; 119910294Ssam } 120010294Ssam if (argc < 2) { 120126049Sminshall printf("usage: %s directory-name\n", argv[0]); 120226049Sminshall code = -1; 120310294Ssam return; 120410294Ssam } 120526049Sminshall (void) command("MKD %s", argv[1]); 120610294Ssam } 120710294Ssam 120810294Ssam /* 120910294Ssam * Remove a directory. 121010294Ssam */ 121110294Ssam removedir(argc, argv) 121210294Ssam char *argv[]; 121310294Ssam { 121410294Ssam 121510294Ssam if (argc < 2) { 121626497Sminshall (void) strcat(line, " "); 121710294Ssam printf("(directory-name) "); 121826497Sminshall (void) gets(&line[strlen(line)]); 121910294Ssam makeargv(); 122010294Ssam argc = margc; 122110294Ssam argv = margv; 122210294Ssam } 122310294Ssam if (argc < 2) { 122426049Sminshall printf("usage: %s directory-name\n", argv[0]); 122526049Sminshall code = -1; 122610294Ssam return; 122710294Ssam } 122826049Sminshall (void) command("RMD %s", argv[1]); 122910294Ssam } 123010294Ssam 123110294Ssam /* 123210294Ssam * Send a line, verbatim, to the remote machine. 123310294Ssam */ 123410294Ssam quote(argc, argv) 123510294Ssam char *argv[]; 123610294Ssam { 123710294Ssam int i; 123810294Ssam char buf[BUFSIZ]; 123910294Ssam 124010294Ssam if (argc < 2) { 124126497Sminshall (void) strcat(line, " "); 124210294Ssam printf("(command line to send) "); 124326497Sminshall (void) gets(&line[strlen(line)]); 124410294Ssam makeargv(); 124510294Ssam argc = margc; 124610294Ssam argv = margv; 124710294Ssam } 124810294Ssam if (argc < 2) { 124910294Ssam printf("usage: %s line-to-send\n", argv[0]); 125026049Sminshall code = -1; 125110294Ssam return; 125210294Ssam } 125326497Sminshall (void) strcpy(buf, argv[1]); 125410294Ssam for (i = 2; i < argc; i++) { 125526497Sminshall (void) strcat(buf, " "); 125626497Sminshall (void) strcat(buf, argv[i]); 125710294Ssam } 125826049Sminshall if (command(buf) == PRELIM) { 125926049Sminshall while (getreply(0) == PRELIM); 126026049Sminshall } 126110294Ssam } 126210294Ssam 126310294Ssam /* 126410294Ssam * Ask the other side for help. 126510294Ssam */ 126610294Ssam rmthelp(argc, argv) 126710294Ssam char *argv[]; 126810294Ssam { 126910294Ssam int oldverbose = verbose; 127010294Ssam 127110294Ssam verbose = 1; 127210294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 127310294Ssam verbose = oldverbose; 127410294Ssam } 127510294Ssam 127610294Ssam /* 127710294Ssam * Terminate session and exit. 127810294Ssam */ 127910294Ssam /*VARARGS*/ 128010294Ssam quit() 128110294Ssam { 128210294Ssam 128318286Sralph if (connected) 128418286Sralph disconnect(); 128526049Sminshall pswitch(1); 128626049Sminshall if (connected) { 128726049Sminshall disconnect(); 128826049Sminshall } 128910294Ssam exit(0); 129010294Ssam } 129110294Ssam 129210294Ssam /* 129310294Ssam * Terminate session, but don't exit. 129410294Ssam */ 129510294Ssam disconnect() 129610294Ssam { 129710294Ssam extern FILE *cout; 129810294Ssam extern int data; 129910294Ssam 130010294Ssam if (!connected) 130110294Ssam return; 130210294Ssam (void) command("QUIT"); 130326049Sminshall if (cout) { 130426049Sminshall (void) fclose(cout); 130526049Sminshall } 130610294Ssam cout = NULL; 130710294Ssam connected = 0; 130810294Ssam data = -1; 130926049Sminshall if (!proxy) { 131026049Sminshall macnum = 0; 131126049Sminshall } 131210294Ssam } 131311353Ssam 131411650Ssam confirm(cmd, file) 131511353Ssam char *cmd, *file; 131611353Ssam { 131711353Ssam char line[BUFSIZ]; 131811353Ssam 131911353Ssam if (!interactive) 132011650Ssam return (1); 132111353Ssam printf("%s %s? ", cmd, file); 132226497Sminshall (void) fflush(stdout); 132326497Sminshall (void) gets(line); 132411650Ssam return (*line != 'n' && *line != 'N'); 132511353Ssam } 132611353Ssam 132711353Ssam fatal(msg) 132811353Ssam char *msg; 132911353Ssam { 133011353Ssam 133126497Sminshall fprintf(stderr, "ftp: %s\n", msg); 133211353Ssam exit(1); 133311353Ssam } 133411353Ssam 133511353Ssam /* 133611353Ssam * Glob a local file name specification with 133711353Ssam * the expectation of a single return value. 133811353Ssam * Can't control multiple values being expanded 133911353Ssam * from the expression, we return only the first. 134011353Ssam */ 134111353Ssam globulize(cpp) 134211353Ssam char **cpp; 134311353Ssam { 134411353Ssam char **globbed; 134511353Ssam 134611353Ssam if (!doglob) 134711353Ssam return (1); 134811353Ssam globbed = glob(*cpp); 134911353Ssam if (globerr != NULL) { 135011353Ssam printf("%s: %s\n", *cpp, globerr); 135111353Ssam if (globbed) 135211353Ssam blkfree(globbed); 135311353Ssam return (0); 135411353Ssam } 135511353Ssam if (globbed) { 135611353Ssam *cpp = *globbed++; 135711353Ssam /* don't waste too much memory */ 135811353Ssam if (*globbed) 135911353Ssam blkfree(globbed); 136011353Ssam } 136111353Ssam return (1); 136211353Ssam } 136326049Sminshall 136426049Sminshall account(argc,argv) 136526049Sminshall 136626049Sminshall int argc; 136726049Sminshall char **argv; 136826049Sminshall { 136926497Sminshall char acct[50], *mygetpass(), *ap; 137026049Sminshall 137126049Sminshall if (argc > 1) { 137226049Sminshall ++argv; 137326049Sminshall --argc; 137426049Sminshall (void) strncpy(acct,*argv,49); 137526049Sminshall acct[50] = '\0'; 137626049Sminshall while (argc > 1) { 137726049Sminshall --argc; 137826049Sminshall ++argv; 137926049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 138026049Sminshall } 138126049Sminshall ap = acct; 138226049Sminshall } 138326049Sminshall else { 138426497Sminshall ap = mygetpass("Account:"); 138526049Sminshall } 138626049Sminshall (void) command("ACCT %s", ap); 138726049Sminshall } 138826049Sminshall 138926049Sminshall jmp_buf abortprox; 139026049Sminshall 139126049Sminshall proxabort() 139226049Sminshall { 139326049Sminshall extern int proxy; 139426049Sminshall 139526049Sminshall if (!proxy) { 139626049Sminshall pswitch(1); 139726049Sminshall } 139826049Sminshall if (connected) { 139926049Sminshall proxflag = 1; 140026049Sminshall } 140126049Sminshall else { 140226049Sminshall proxflag = 0; 140326049Sminshall } 140426049Sminshall pswitch(0); 140526049Sminshall longjmp(abortprox,1); 140626049Sminshall } 140726049Sminshall 140826049Sminshall doproxy(argc,argv) 140926049Sminshall int argc; 141026049Sminshall char *argv[]; 141126049Sminshall { 141226049Sminshall int (*oldintr)(), proxabort(); 141326049Sminshall register struct cmd *c; 141426049Sminshall struct cmd *getcmd(); 141526049Sminshall extern struct cmd cmdtab[]; 141626049Sminshall extern jmp_buf abortprox; 141726049Sminshall 141826049Sminshall if (argc < 2) { 141926497Sminshall (void) strcat(line, " "); 142026049Sminshall printf("(command) "); 142126497Sminshall (void) gets(&line[strlen(line)]); 142226049Sminshall makeargv(); 142326049Sminshall argc = margc; 142426049Sminshall argv = margv; 142526049Sminshall } 142626049Sminshall if (argc < 2) { 142726049Sminshall printf("usage:%s command\n", argv[0]); 142826049Sminshall code = -1; 142926049Sminshall return; 143026049Sminshall } 143126049Sminshall c = getcmd(argv[1]); 143226049Sminshall if (c == (struct cmd *) -1) { 143326049Sminshall printf("?Ambiguous command\n"); 143426497Sminshall (void) fflush(stdout); 143526049Sminshall code = -1; 143626049Sminshall return; 143726049Sminshall } 143826049Sminshall if (c == 0) { 143926049Sminshall printf("?Invalid command\n"); 144026497Sminshall (void) fflush(stdout); 144126049Sminshall code = -1; 144226049Sminshall return; 144326049Sminshall } 144426049Sminshall if (!c->c_proxy) { 144526049Sminshall printf("?Invalid proxy command\n"); 144626497Sminshall (void) fflush(stdout); 144726049Sminshall code = -1; 144826049Sminshall return; 144926049Sminshall } 145026049Sminshall if (setjmp(abortprox)) { 145126049Sminshall code = -1; 145226049Sminshall return; 145326049Sminshall } 145426049Sminshall oldintr = signal(SIGINT, proxabort); 145526049Sminshall pswitch(1); 145626049Sminshall if (c->c_conn && !connected) { 145726049Sminshall printf("Not connected\n"); 145826497Sminshall (void) fflush(stdout); 145926049Sminshall pswitch(0); 146026049Sminshall (void) signal(SIGINT, oldintr); 146126049Sminshall code = -1; 146226049Sminshall return; 146326049Sminshall } 146426049Sminshall (*c->c_handler)(argc-1, argv+1); 146526049Sminshall if (connected) { 146626049Sminshall proxflag = 1; 146726049Sminshall } 146826049Sminshall else { 146926049Sminshall proxflag = 0; 147026049Sminshall } 147126049Sminshall pswitch(0); 147226049Sminshall (void) signal(SIGINT, oldintr); 147326049Sminshall } 147426049Sminshall 147526049Sminshall setcase() 147626049Sminshall { 147726049Sminshall mcase = !mcase; 147826049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 147926049Sminshall code = mcase; 148026049Sminshall } 148126049Sminshall 148226049Sminshall setcr() 148326049Sminshall { 148426049Sminshall crflag = !crflag; 148526049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 148626049Sminshall code = crflag; 148726049Sminshall } 148826049Sminshall 148926049Sminshall setntrans(argc,argv) 149026049Sminshall int argc; 149126049Sminshall char *argv[]; 149226049Sminshall { 149326049Sminshall if (argc == 1) { 149426049Sminshall ntflag = 0; 149526049Sminshall printf("Ntrans off.\n"); 149626049Sminshall code = ntflag; 149726049Sminshall return; 149826049Sminshall } 149926049Sminshall ntflag++; 150026049Sminshall code = ntflag; 150126049Sminshall (void) strncpy(ntin, argv[1], 16); 150226049Sminshall ntin[16] = '\0'; 150326049Sminshall if (argc == 2) { 150426049Sminshall ntout[0] = '\0'; 150526049Sminshall return; 150626049Sminshall } 150726049Sminshall (void) strncpy(ntout, argv[2], 16); 150826049Sminshall ntout[16] = '\0'; 150926049Sminshall } 151026049Sminshall 151126049Sminshall char * 151226049Sminshall dotrans(name) 151326049Sminshall char *name; 151426049Sminshall { 151526049Sminshall static char new[MAXPATHLEN]; 151626049Sminshall char *cp1, *cp2 = new; 151726049Sminshall register int i, ostop, found; 151826049Sminshall 151926049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 152026049Sminshall for (cp1 = name; *cp1; cp1++) { 152126049Sminshall found = 0; 152226049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 152326049Sminshall if (*cp1 == *(ntin + i)) { 152426049Sminshall found++; 152526049Sminshall if (i < ostop) { 152626049Sminshall *cp2++ = *(ntout + i); 152726049Sminshall } 152826049Sminshall break; 152926049Sminshall } 153026049Sminshall } 153126049Sminshall if (!found) { 153226049Sminshall *cp2++ = *cp1; 153326049Sminshall } 153426049Sminshall } 153526049Sminshall *cp2 = '\0'; 153626049Sminshall return(new); 153726049Sminshall } 153826049Sminshall 153926049Sminshall setnmap(argc, argv) 154026049Sminshall int argc; 154126049Sminshall char *argv[]; 154226049Sminshall { 154326049Sminshall char *cp; 154426049Sminshall 154526049Sminshall if (argc == 1) { 154626049Sminshall mapflag = 0; 154726049Sminshall printf("Nmap off.\n"); 154826049Sminshall code = mapflag; 154926049Sminshall return; 155026049Sminshall } 155126049Sminshall if (argc < 3) { 155226497Sminshall (void) strcat(line, " "); 155326049Sminshall printf("(mapout) "); 155426497Sminshall (void) gets(&line[strlen(line)]); 155526049Sminshall makeargv(); 155626049Sminshall argc = margc; 155726049Sminshall argv = margv; 155826049Sminshall } 155926049Sminshall if (argc < 3) { 156026049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 156126049Sminshall code = -1; 156226049Sminshall return; 156326049Sminshall } 156426049Sminshall mapflag = 1; 156526049Sminshall code = 1; 156626049Sminshall cp = index(altarg, ' '); 156726049Sminshall if (proxy) { 156826049Sminshall while(*++cp == ' '); 156926049Sminshall altarg = cp; 157026049Sminshall cp = index(altarg, ' '); 157126049Sminshall } 157226049Sminshall *cp = '\0'; 157326049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 157426049Sminshall while (*++cp == ' '); 157526049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 157626049Sminshall } 157726049Sminshall 157826049Sminshall char * 157926049Sminshall domap(name) 158026049Sminshall char *name; 158126049Sminshall { 158226049Sminshall static char new[MAXPATHLEN]; 158326049Sminshall register char *cp1 = name, *cp2 = mapin; 158426049Sminshall char *tp[9], *te[9]; 158526049Sminshall int i, toks[9], toknum, match = 1; 158626049Sminshall 158726049Sminshall for (i=0; i < 9; ++i) { 158826049Sminshall toks[i] = 0; 158926049Sminshall } 159026049Sminshall while (match && *cp1 && *cp2) { 159126049Sminshall switch (*cp2) { 159226049Sminshall case '\\': 159326049Sminshall if (*++cp2 != *cp1) { 159426049Sminshall match = 0; 159526049Sminshall } 159626049Sminshall break; 159726049Sminshall case '$': 159826049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 159926049Sminshall if (*cp1 != *(++cp2+1)) { 160026049Sminshall toks[toknum = *cp2 - '1']++; 160126049Sminshall tp[toknum] = cp1; 160226049Sminshall while (*++cp1 && *(cp2+1) 160326049Sminshall != *cp1); 160426049Sminshall te[toknum] = cp1; 160526049Sminshall } 160626049Sminshall cp2++; 160726049Sminshall break; 160826049Sminshall } 160926049Sminshall /* intentional drop through */ 161026049Sminshall default: 161126049Sminshall if (*cp2 != *cp1) { 161226049Sminshall match = 0; 161326049Sminshall } 161426049Sminshall break; 161526049Sminshall } 161626049Sminshall if (*cp1) { 161726049Sminshall cp1++; 161826049Sminshall } 161926049Sminshall if (*cp2) { 162026049Sminshall cp2++; 162126049Sminshall } 162226049Sminshall } 162326049Sminshall cp1 = new; 162426049Sminshall *cp1 = '\0'; 162526049Sminshall cp2 = mapout; 162626049Sminshall while (*cp2) { 162726049Sminshall match = 0; 162826049Sminshall switch (*cp2) { 162926049Sminshall case '\\': 163026049Sminshall if (*(cp2 + 1)) { 163126049Sminshall *cp1++ = *++cp2; 163226049Sminshall } 163326049Sminshall break; 163426049Sminshall case '[': 163526049Sminshall LOOP: 163626049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 163726049Sminshall if (*++cp2 == '0') { 163826049Sminshall char *cp3 = name; 163926049Sminshall 164026049Sminshall while (*cp3) { 164126049Sminshall *cp1++ = *cp3++; 164226049Sminshall } 164326049Sminshall match = 1; 164426049Sminshall } 164526049Sminshall else if (toks[toknum = *cp2 - '1']) { 164626049Sminshall char *cp3 = tp[toknum]; 164726049Sminshall 164826049Sminshall while (cp3 != te[toknum]) { 164926049Sminshall *cp1++ = *cp3++; 165026049Sminshall } 165126049Sminshall match = 1; 165226049Sminshall } 165326049Sminshall } 165426049Sminshall else { 165526049Sminshall while (*cp2 && *cp2 != ',' && 165626049Sminshall *cp2 != ']') { 165726049Sminshall if (*cp2 == '\\') { 165826049Sminshall cp2++; 165926049Sminshall } 166026049Sminshall else if (*cp2 == '$' && 166126049Sminshall isdigit(*(cp2+1))) { 166226049Sminshall if (*++cp2 == '0') { 166326049Sminshall char *cp3 = name; 166426049Sminshall 166526049Sminshall while (*cp3) { 166626049Sminshall *cp1++ = *cp3++; 166726049Sminshall } 166826049Sminshall } 166926049Sminshall else if (toks[toknum = 167026049Sminshall *cp2 - '1']) { 167126049Sminshall char *cp3=tp[toknum]; 167226049Sminshall 167326049Sminshall while (cp3 != 167426049Sminshall te[toknum]) { 167526049Sminshall *cp1++ = *cp3++; 167626049Sminshall } 167726049Sminshall } 167826049Sminshall } 167926049Sminshall else if (*cp2) { 168026049Sminshall *cp1++ = *cp2++; 168126049Sminshall } 168226049Sminshall } 168326049Sminshall if (!*cp2) { 168426049Sminshall printf("nmap: unbalanced brackets\n"); 168526049Sminshall return(name); 168626049Sminshall } 168726049Sminshall match = 1; 168826049Sminshall cp2--; 168926049Sminshall } 169026049Sminshall if (match) { 169126049Sminshall while (*++cp2 && *cp2 != ']') { 169226049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 169326049Sminshall cp2++; 169426049Sminshall } 169526049Sminshall } 169626049Sminshall if (!*cp2) { 169726049Sminshall printf("nmap: unbalanced brackets\n"); 169826049Sminshall return(name); 169926049Sminshall } 170026049Sminshall break; 170126049Sminshall } 170226049Sminshall switch (*++cp2) { 170326049Sminshall case ',': 170426049Sminshall goto LOOP; 170526049Sminshall case ']': 170626049Sminshall break; 170726049Sminshall default: 170826049Sminshall cp2--; 170926049Sminshall goto LOOP; 171026049Sminshall } 171126049Sminshall break; 171226049Sminshall case '$': 171326049Sminshall if (isdigit(*(cp2 + 1))) { 171426049Sminshall if (*++cp2 == '0') { 171526049Sminshall char *cp3 = name; 171626049Sminshall 171726049Sminshall while (*cp3) { 171826049Sminshall *cp1++ = *cp3++; 171926049Sminshall } 172026049Sminshall } 172126049Sminshall else if (toks[toknum = *cp2 - '1']) { 172226049Sminshall char *cp3 = tp[toknum]; 172326049Sminshall 172426049Sminshall while (cp3 != te[toknum]) { 172526049Sminshall *cp1++ = *cp3++; 172626049Sminshall } 172726049Sminshall } 172826049Sminshall break; 172926049Sminshall } 173026049Sminshall /* intentional drop through */ 173126049Sminshall default: 173226049Sminshall *cp1++ = *cp2; 173326049Sminshall break; 173426049Sminshall } 173526049Sminshall cp2++; 173626049Sminshall } 173726049Sminshall *cp1 = '\0'; 173826049Sminshall if (!*new) { 173926049Sminshall return(name); 174026049Sminshall } 174126049Sminshall return(new); 174226049Sminshall } 174326049Sminshall 174426049Sminshall setsunique() 174526049Sminshall { 174626049Sminshall sunique = !sunique; 174726049Sminshall printf("Store unique %s.\n", onoff(sunique)); 174826049Sminshall code = sunique; 174926049Sminshall } 175026049Sminshall 175126049Sminshall setrunique() 175226049Sminshall { 175326049Sminshall runique = !runique; 175426049Sminshall printf("Receive unique %s.\n", onoff(runique)); 175526049Sminshall code = runique; 175626049Sminshall } 175726049Sminshall 175826049Sminshall /* change directory to perent directory */ 175926049Sminshall cdup() 176026049Sminshall { 176126049Sminshall (void) command("CDUP"); 176226049Sminshall } 176326049Sminshall 176426049Sminshall macdef(argc, argv) 176526049Sminshall int argc; 176626049Sminshall char *argv[]; 176726049Sminshall { 176826049Sminshall char *tmp; 176926049Sminshall int c; 177026049Sminshall 177126049Sminshall if (macnum == 16) { 177226049Sminshall printf("Limit of 16 macros have already been defined\n"); 177326049Sminshall code = -1; 177426049Sminshall return; 177526049Sminshall } 177626049Sminshall if (argc < 2) { 177726497Sminshall (void) strcat(line, " "); 177826049Sminshall printf("(macro name) "); 177926497Sminshall (void) gets(&line[strlen(line)]); 178026049Sminshall makeargv(); 178126049Sminshall argc = margc; 178226049Sminshall argv = margv; 178326049Sminshall } 178426049Sminshall if (argc != 2) { 178526049Sminshall printf("Usage: %s macro_name\n",argv[0]); 178626049Sminshall code = -1; 178726049Sminshall return; 178826049Sminshall } 178926049Sminshall if (interactive) { 179026049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 179126049Sminshall } 179226497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 179326049Sminshall if (macnum == 0) { 179426049Sminshall macros[macnum].mac_start = macbuf; 179526049Sminshall } 179626049Sminshall else { 179726049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 179826049Sminshall } 179926049Sminshall tmp = macros[macnum].mac_start; 180026049Sminshall while (tmp != macbuf+4096) { 180126049Sminshall if ((c = getchar()) == EOF) { 180226049Sminshall printf("macdef:end of file encountered\n"); 180326049Sminshall code = -1; 180426049Sminshall return; 180526049Sminshall } 180626049Sminshall if ((*tmp = c) == '\n') { 180726049Sminshall if (tmp == macros[macnum].mac_start) { 180826049Sminshall macros[macnum++].mac_end = tmp; 180926049Sminshall code = 0; 181026049Sminshall return; 181126049Sminshall } 181226049Sminshall if (*(tmp-1) == '\0') { 181326049Sminshall macros[macnum++].mac_end = tmp - 1; 181426049Sminshall code = 0; 181526049Sminshall return; 181626049Sminshall } 181726049Sminshall *tmp = '\0'; 181826049Sminshall } 181926049Sminshall tmp++; 182026049Sminshall } 182126049Sminshall while (1) { 182226049Sminshall while ((c = getchar()) != '\n' && c != EOF); 182326049Sminshall if (c == EOF || getchar() == '\n') { 182426049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 182526049Sminshall code = -1; 182626049Sminshall return; 182726049Sminshall } 182826049Sminshall } 182926049Sminshall } 1830