121737Sdist /* 2*36942Skarels * Copyright (c) 1985, 1989 Regents of the University of California. 333737Sbostic * All rights reserved. 433737Sbostic * 533737Sbostic * Redistribution and use in source and binary forms are permitted 634901Sbostic * provided that the above copyright notice and this paragraph are 734901Sbostic * duplicated in all such forms and that any documentation, 834901Sbostic * advertising materials, and other materials related to such 934901Sbostic * distribution and use acknowledge that the software was developed 1034901Sbostic * by the University of California, Berkeley. The name of the 1134901Sbostic * University may not be used to endorse or promote products derived 1234901Sbostic * from this software without specific prior written permission. 1334901Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434901Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536935Skarels * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621737Sdist */ 1721737Sdist 1810294Ssam #ifndef lint 19*36942Skarels static char sccsid[] = "@(#)cmds.c 5.14.1.1 (Berkeley) 03/01/89"; 2033737Sbostic #endif /* not lint */ 2110294Ssam 2210294Ssam /* 2310294Ssam * FTP User Program -- Command Routines. 2410294Ssam */ 2536940Skarels #include <sys/param.h> 2636940Skarels #include <sys/wait.h> 2736940Skarels #include <sys/stat.h> 2810294Ssam #include <sys/socket.h> 2910294Ssam 3012396Ssam #include <arpa/ftp.h> 3112396Ssam 3210294Ssam #include <signal.h> 3310294Ssam #include <stdio.h> 3410294Ssam #include <errno.h> 3510294Ssam #include <netdb.h> 3626049Sminshall #include <ctype.h> 3736935Skarels #include <time.h> 3810294Ssam 3936940Skarels #include "ftp_var.h" 4010294Ssam 4136940Skarels 4211353Ssam extern char *globerr; 4311353Ssam extern char **glob(); 4411756Ssam extern char *home; 4511756Ssam extern char *remglob(); 4611756Ssam extern char *getenv(); 4711756Ssam extern char *index(); 4811756Ssam extern char *rindex(); 49*36942Skarels #ifdef RESTART 5036935Skarels extern off_t restart_point; 51*36942Skarels #endif 5236935Skarels extern char reply_string[]; 5336935Skarels 5426049Sminshall char *mname; 5526049Sminshall jmp_buf jabort; 5626049Sminshall char *dotrans(), *domap(); 5710294Ssam 5810294Ssam /* 5910294Ssam * Connect to peer server and 6010294Ssam * auto-login, if possible. 6110294Ssam */ 6210294Ssam setpeer(argc, argv) 6310294Ssam int argc; 6410294Ssam char *argv[]; 6510294Ssam { 6625903Skarels char *host, *hookup(); 6710294Ssam int port; 6810294Ssam 6910294Ssam if (connected) { 7026049Sminshall printf("Already connected to %s, use close first.\n", 7110294Ssam hostname); 7226049Sminshall code = -1; 7310294Ssam return; 7410294Ssam } 7510294Ssam if (argc < 2) { 7626497Sminshall (void) strcat(line, " "); 7710294Ssam printf("(to) "); 7826497Sminshall (void) gets(&line[strlen(line)]); 7910294Ssam makeargv(); 8010294Ssam argc = margc; 8110294Ssam argv = margv; 8210294Ssam } 8310294Ssam if (argc > 3) { 8410294Ssam printf("usage: %s host-name [port]\n", argv[0]); 8526049Sminshall code = -1; 8610294Ssam return; 8710294Ssam } 8810294Ssam port = sp->s_port; 8910294Ssam if (argc > 2) { 9011218Ssam port = atoi(argv[2]); 9110294Ssam if (port <= 0) { 9211218Ssam printf("%s: bad port number-- %s\n", argv[1], argv[2]); 9311218Ssam printf ("usage: %s host-name [port]\n", argv[0]); 9426049Sminshall code = -1; 9510294Ssam return; 9610294Ssam } 9710294Ssam port = htons(port); 9810294Ssam } 9910294Ssam host = hookup(argv[1], port); 10010294Ssam if (host) { 10110294Ssam connected = 1; 10236935Skarels if (autologin) { 10336935Skarels int overbose; 10436940Skarels 10526497Sminshall (void) login(argv[1]); 10636935Skarels #if defined(unix) && NBBY == 8 10736935Skarels /* 10836935Skarels * this ifdef is to keep someone form "porting" this to an incompatible 10936935Skarels * system and not checking this out. This way they have to think about it. 11036935Skarels */ 11136940Skarels overbose = verbose; 11236940Skarels if (debug == 0) 11336940Skarels verbose = -1; 11436935Skarels if (command("SYST") == COMPLETE && overbose) { 11536935Skarels register char *cp, c; 11636935Skarels cp = index(reply_string+4, ' '); 11736935Skarels if (cp == NULL) 11836935Skarels cp = index(reply_string+4, '\r'); 11936935Skarels if (cp) { 12036935Skarels if (cp[-1] == '.') 12136935Skarels cp--; 12236935Skarels c = *cp; 12336935Skarels *cp = '\0'; 12436935Skarels } 12536935Skarels 12636935Skarels printf("Remote system type is %s.\n", 12736935Skarels reply_string+4); 12836935Skarels if (cp) 12936935Skarels *cp = c; 13036935Skarels } 13136935Skarels if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { 13236935Skarels setbinary(); 13336935Skarels if (overbose) 13436940Skarels printf("Using %s mode to transfer files.\n", 13536940Skarels typename); 13636935Skarels } else if (overbose && 13736935Skarels !strncmp(reply_string, "215 TOPS20", 10)) { 13836940Skarels printf( 13936940Skarels "Remember to set tenex mode when transfering binary files from this machine.\n"); 14036935Skarels } 14136935Skarels verbose = overbose; 14236935Skarels #endif /* unix */ 14336935Skarels } 14410294Ssam } 14510294Ssam } 14610294Ssam 14710294Ssam struct types { 14810294Ssam char *t_name; 14910294Ssam char *t_mode; 15010294Ssam int t_type; 15111218Ssam char *t_arg; 15210294Ssam } types[] = { 15311218Ssam { "ascii", "A", TYPE_A, 0 }, 15411218Ssam { "binary", "I", TYPE_I, 0 }, 15511218Ssam { "image", "I", TYPE_I, 0 }, 15611218Ssam { "ebcdic", "E", TYPE_E, 0 }, 15711218Ssam { "tenex", "L", TYPE_L, bytename }, 15810294Ssam 0 15910294Ssam }; 16010294Ssam 16110294Ssam /* 16210294Ssam * Set transfer type. 16310294Ssam */ 16410294Ssam settype(argc, argv) 16510294Ssam char *argv[]; 16610294Ssam { 16710294Ssam register struct types *p; 16811218Ssam int comret; 16910294Ssam 17010294Ssam if (argc > 2) { 17110294Ssam char *sep; 17210294Ssam 17310294Ssam printf("usage: %s [", argv[0]); 17410294Ssam sep = " "; 17510294Ssam for (p = types; p->t_name; p++) { 17610294Ssam printf("%s%s", sep, p->t_name); 17710294Ssam if (*sep == ' ') 17810294Ssam sep = " | "; 17910294Ssam } 18010294Ssam printf(" ]\n"); 18126049Sminshall code = -1; 18210294Ssam return; 18310294Ssam } 18410294Ssam if (argc < 2) { 18510294Ssam printf("Using %s mode to transfer files.\n", typename); 18626049Sminshall code = 0; 18710294Ssam return; 18810294Ssam } 18910294Ssam for (p = types; p->t_name; p++) 19010294Ssam if (strcmp(argv[1], p->t_name) == 0) 19110294Ssam break; 19210294Ssam if (p->t_name == 0) { 19310294Ssam printf("%s: unknown mode\n", argv[1]); 19426049Sminshall code = -1; 19510294Ssam return; 19610294Ssam } 19711218Ssam if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) 19811218Ssam comret = command ("TYPE %s %s", p->t_mode, p->t_arg); 19911218Ssam else 20011218Ssam comret = command("TYPE %s", p->t_mode); 20111218Ssam if (comret == COMPLETE) { 20226497Sminshall (void) strcpy(typename, p->t_name); 20310294Ssam type = p->t_type; 20410294Ssam } 20510294Ssam } 20610294Ssam 20710294Ssam /* 20810294Ssam * Set binary transfer type. 20910294Ssam */ 21010294Ssam /*VARARGS*/ 21110294Ssam setbinary() 21210294Ssam { 21310294Ssam 21410294Ssam call(settype, "type", "binary", 0); 21510294Ssam } 21610294Ssam 21710294Ssam /* 21810294Ssam * Set ascii transfer type. 21910294Ssam */ 22010294Ssam /*VARARGS*/ 22110294Ssam setascii() 22210294Ssam { 22310294Ssam 22410294Ssam call(settype, "type", "ascii", 0); 22510294Ssam } 22610294Ssam 22710294Ssam /* 22810294Ssam * Set tenex transfer type. 22910294Ssam */ 23010294Ssam /*VARARGS*/ 23110294Ssam settenex() 23210294Ssam { 23310294Ssam 23410294Ssam call(settype, "type", "tenex", 0); 23510294Ssam } 23610294Ssam 23710294Ssam /* 23810294Ssam * Set ebcdic transfer type. 23910294Ssam */ 24010294Ssam /*VARARGS*/ 24110294Ssam setebcdic() 24210294Ssam { 24310294Ssam 24410294Ssam call(settype, "type", "ebcdic", 0); 24510294Ssam } 24610294Ssam 24710294Ssam /* 24810294Ssam * Set file transfer mode. 24910294Ssam */ 25026497Sminshall /*ARGSUSED*/ 25110294Ssam setmode(argc, argv) 25210294Ssam char *argv[]; 25310294Ssam { 25410294Ssam 25510294Ssam printf("We only support %s mode, sorry.\n", modename); 25626049Sminshall code = -1; 25710294Ssam } 25810294Ssam 25910294Ssam /* 26010294Ssam * Set file transfer format. 26110294Ssam */ 26226497Sminshall /*ARGSUSED*/ 26310294Ssam setform(argc, argv) 26410294Ssam char *argv[]; 26510294Ssam { 26610294Ssam 26710294Ssam printf("We only support %s format, sorry.\n", formname); 26826049Sminshall code = -1; 26910294Ssam } 27010294Ssam 27110294Ssam /* 27210294Ssam * Set file transfer structure. 27310294Ssam */ 27426497Sminshall /*ARGSUSED*/ 27510294Ssam setstruct(argc, argv) 27610294Ssam char *argv[]; 27710294Ssam { 27810294Ssam 27910294Ssam printf("We only support %s structure, sorry.\n", structname); 28026049Sminshall code = -1; 28110294Ssam } 28210294Ssam 28318286Sralph /* 28418286Sralph * Send a single file. 28518286Sralph */ 28610294Ssam put(argc, argv) 28711756Ssam int argc; 28810294Ssam char *argv[]; 28910294Ssam { 29011650Ssam char *cmd; 29126049Sminshall int loc = 0; 29225908Smckusick char *oldargv1; 29311650Ssam 29426049Sminshall if (argc == 2) { 29526049Sminshall argc++; 29626049Sminshall argv[2] = argv[1]; 29726049Sminshall loc++; 29826049Sminshall } 29910294Ssam if (argc < 2) { 30026497Sminshall (void) strcat(line, " "); 30110294Ssam printf("(local-file) "); 30226497Sminshall (void) gets(&line[strlen(line)]); 30310294Ssam makeargv(); 30410294Ssam argc = margc; 30510294Ssam argv = margv; 30610294Ssam } 30710294Ssam if (argc < 2) { 30810294Ssam usage: 30926049Sminshall printf("usage:%s local-file remote-file\n", argv[0]); 31026049Sminshall code = -1; 31110294Ssam return; 31210294Ssam } 31310294Ssam if (argc < 3) { 31426497Sminshall (void) strcat(line, " "); 31510294Ssam printf("(remote-file) "); 31626497Sminshall (void) gets(&line[strlen(line)]); 31710294Ssam makeargv(); 31810294Ssam argc = margc; 31910294Ssam argv = margv; 32010294Ssam } 32110294Ssam if (argc < 3) 32210294Ssam goto usage; 32325908Smckusick oldargv1 = argv[1]; 32426049Sminshall if (!globulize(&argv[1])) { 32526049Sminshall code = -1; 32611353Ssam return; 32726049Sminshall } 32825908Smckusick /* 32925908Smckusick * If "globulize" modifies argv[1], and argv[2] is a copy of 33025908Smckusick * the old argv[1], make it a copy of the new argv[1]. 33125908Smckusick */ 33226049Sminshall if (argv[1] != oldargv1 && argv[2] == oldargv1) { 33325908Smckusick argv[2] = argv[1]; 33426049Sminshall } 33526049Sminshall cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); 33626049Sminshall if (loc && ntflag) { 33726049Sminshall argv[2] = dotrans(argv[2]); 33826049Sminshall } 33926049Sminshall if (loc && mapflag) { 34026049Sminshall argv[2] = domap(argv[2]); 34126049Sminshall } 34211650Ssam sendrequest(cmd, argv[1], argv[2]); 34310294Ssam } 34410294Ssam 34510294Ssam /* 34611756Ssam * Send multiple files. 34710294Ssam */ 34811353Ssam mput(argc, argv) 34911353Ssam char *argv[]; 35011353Ssam { 35113212Ssam register int i; 35226049Sminshall int ointer, (*oldintr)(), mabort(); 35326049Sminshall extern jmp_buf jabort; 35426049Sminshall char *tp; 35511353Ssam 35611650Ssam if (argc < 2) { 35726497Sminshall (void) strcat(line, " "); 35811650Ssam printf("(local-files) "); 35926497Sminshall (void) gets(&line[strlen(line)]); 36011650Ssam makeargv(); 36111650Ssam argc = margc; 36211650Ssam argv = margv; 36311353Ssam } 36411353Ssam if (argc < 2) { 36526049Sminshall printf("usage:%s local-files\n", argv[0]); 36626049Sminshall code = -1; 36711353Ssam return; 36811353Ssam } 36926049Sminshall mname = argv[0]; 37026049Sminshall mflag = 1; 37126049Sminshall oldintr = signal(SIGINT, mabort); 37226049Sminshall (void) setjmp(jabort); 37326049Sminshall if (proxy) { 37426049Sminshall char *cp, *tp2, tmpbuf[MAXPATHLEN]; 37526049Sminshall 37626497Sminshall while ((cp = remglob(argv,0)) != NULL) { 37726049Sminshall if (*cp == 0) { 37826049Sminshall mflag = 0; 37926049Sminshall continue; 38026049Sminshall } 38126049Sminshall if (mflag && confirm(argv[0], cp)) { 38226049Sminshall tp = cp; 38326049Sminshall if (mcase) { 38426049Sminshall while (*tp && !islower(*tp)) { 38526049Sminshall tp++; 38626049Sminshall } 38726049Sminshall if (!*tp) { 38826049Sminshall tp = cp; 38926049Sminshall tp2 = tmpbuf; 39026049Sminshall while ((*tp2 = *tp) != NULL) { 39126049Sminshall if (isupper(*tp2)) { 39226049Sminshall *tp2 = 'a' + *tp2 - 'A'; 39326049Sminshall } 39426049Sminshall tp++; 39526049Sminshall tp2++; 39626049Sminshall } 39726049Sminshall } 39826049Sminshall tp = tmpbuf; 39926049Sminshall } 40026049Sminshall if (ntflag) { 40126049Sminshall tp = dotrans(tp); 40226049Sminshall } 40326049Sminshall if (mapflag) { 40426049Sminshall tp = domap(tp); 40526049Sminshall } 40626049Sminshall sendrequest((sunique) ? "STOU" : "STOR", cp,tp); 40726049Sminshall if (!mflag && fromatty) { 40826049Sminshall ointer = interactive; 40926049Sminshall interactive = 1; 41026049Sminshall if (confirm("Continue with","mput")) { 41126049Sminshall mflag++; 41226049Sminshall } 41326049Sminshall interactive = ointer; 41426049Sminshall } 41526049Sminshall } 41626049Sminshall } 41726049Sminshall (void) signal(SIGINT, oldintr); 41826049Sminshall mflag = 0; 41926049Sminshall return; 42026049Sminshall } 42113212Ssam for (i = 1; i < argc; i++) { 42213212Ssam register char **cpp, **gargs; 42313212Ssam 42413212Ssam if (!doglob) { 42526049Sminshall if (mflag && confirm(argv[0], argv[i])) { 42626049Sminshall tp = (ntflag) ? dotrans(argv[i]) : argv[i]; 42726049Sminshall tp = (mapflag) ? domap(tp) : tp; 42826049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 42926049Sminshall argv[i], tp); 43026049Sminshall if (!mflag && fromatty) { 43126049Sminshall ointer = interactive; 43226049Sminshall interactive = 1; 43326049Sminshall if (confirm("Continue with","mput")) { 43426049Sminshall mflag++; 43526049Sminshall } 43626049Sminshall interactive = ointer; 43726049Sminshall } 43826049Sminshall } 43913212Ssam continue; 44013212Ssam } 44113212Ssam gargs = glob(argv[i]); 44211650Ssam if (globerr != NULL) { 44311650Ssam printf("%s\n", globerr); 44436421Sbostic if (gargs) { 44511650Ssam blkfree(gargs); 44636421Sbostic free(gargs); 44736421Sbostic } 44813212Ssam continue; 44911353Ssam } 45026049Sminshall for (cpp = gargs; cpp && *cpp != NULL; cpp++) { 45126049Sminshall if (mflag && confirm(argv[0], *cpp)) { 45226049Sminshall tp = (ntflag) ? dotrans(*cpp) : *cpp; 45326049Sminshall tp = (mapflag) ? domap(tp) : tp; 45426049Sminshall sendrequest((sunique) ? "STOU" : "STOR", 45526049Sminshall *cpp, tp); 45626049Sminshall if (!mflag && fromatty) { 45726049Sminshall ointer = interactive; 45826049Sminshall interactive = 1; 45926049Sminshall if (confirm("Continue with","mput")) { 46026049Sminshall mflag++; 46126049Sminshall } 46226049Sminshall interactive = ointer; 46326049Sminshall } 46426049Sminshall } 46526049Sminshall } 46636421Sbostic if (gargs != NULL) { 46713212Ssam blkfree(gargs); 46836421Sbostic free(gargs); 46936421Sbostic } 47011353Ssam } 47126049Sminshall (void) signal(SIGINT, oldintr); 47226049Sminshall mflag = 0; 47311353Ssam } 47411353Ssam 475*36942Skarels #ifdef RESTART 47636935Skarels reget(argc, argv) 47736935Skarels char *argv[]; 47836935Skarels { 47936935Skarels (void) getit(argc, argv, 1, "r+w"); 48036935Skarels } 48136935Skarels 48236935Skarels get(argc, argv) 48336935Skarels char *argv[]; 48436935Skarels { 48536935Skarels (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); 48636935Skarels } 487*36942Skarels #endif 48836935Skarels 48911353Ssam /* 49011353Ssam * Receive one file. 49111353Ssam */ 492*36942Skarels #ifdef RESTART 49336935Skarels getit(argc, argv, restartit, mode) 494*36942Skarels #else 495*36942Skarels get(argc, argv) 496*36942Skarels #endif 49710294Ssam char *argv[]; 498*36942Skarels #ifdef RESTART 49936935Skarels char *mode; 500*36942Skarels #endif 50110294Ssam { 50226049Sminshall int loc = 0; 50310294Ssam 50426049Sminshall if (argc == 2) { 50526049Sminshall argc++; 50626049Sminshall argv[2] = argv[1]; 50726049Sminshall loc++; 50826049Sminshall } 50910294Ssam if (argc < 2) { 51026497Sminshall (void) strcat(line, " "); 51110294Ssam printf("(remote-file) "); 51226497Sminshall (void) gets(&line[strlen(line)]); 51310294Ssam makeargv(); 51410294Ssam argc = margc; 51510294Ssam argv = margv; 51610294Ssam } 51710294Ssam if (argc < 2) { 51810294Ssam usage: 51926049Sminshall printf("usage: %s remote-file [ local-file ]\n", argv[0]); 52026049Sminshall code = -1; 521*36942Skarels #ifndef RESTART 522*36942Skarels return; 523*36942Skarels #else 52436940Skarels return (0); 525*36942Skarels #endif 52610294Ssam } 52710294Ssam if (argc < 3) { 52826497Sminshall (void) strcat(line, " "); 52910294Ssam printf("(local-file) "); 53026497Sminshall (void) gets(&line[strlen(line)]); 53110294Ssam makeargv(); 53210294Ssam argc = margc; 53310294Ssam argv = margv; 53410294Ssam } 53510294Ssam if (argc < 3) 53610294Ssam goto usage; 53726049Sminshall if (!globulize(&argv[2])) { 53826049Sminshall code = -1; 539*36942Skarels #ifndef RESTART 540*36942Skarels return; 541*36942Skarels #else 54236940Skarels return (0); 543*36942Skarels #endif 54426049Sminshall } 54526049Sminshall if (loc && mcase) { 54626049Sminshall char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; 54726049Sminshall 54826049Sminshall while (*tp && !islower(*tp)) { 54926049Sminshall tp++; 55026049Sminshall } 55126049Sminshall if (!*tp) { 55226049Sminshall tp = argv[2]; 55326049Sminshall tp2 = tmpbuf; 55426049Sminshall while ((*tp2 = *tp) != NULL) { 55526049Sminshall if (isupper(*tp2)) { 55626049Sminshall *tp2 = 'a' + *tp2 - 'A'; 55726049Sminshall } 55826049Sminshall tp++; 55926049Sminshall tp2++; 56026049Sminshall } 56126049Sminshall argv[2] = tmpbuf; 56226049Sminshall } 56326049Sminshall } 56436940Skarels if (loc && ntflag) 56526049Sminshall argv[2] = dotrans(argv[2]); 56636940Skarels if (loc && mapflag) 56726049Sminshall argv[2] = domap(argv[2]); 568*36942Skarels #ifdef RESTART 56936935Skarels if (restartit) { 57036935Skarels struct stat stbuf; 57136935Skarels int ret; 57236940Skarels 57336935Skarels ret = stat(argv[2], &stbuf); 57436935Skarels if (restartit == 1) { 57536935Skarels if (ret < 0) { 57636935Skarels perror(argv[2]); 57736940Skarels return (0); 57836935Skarels } 57936935Skarels restart_point = stbuf.st_size; 58036935Skarels } else { 58136935Skarels if (ret == 0) { 58236935Skarels int overbose; 58336940Skarels 58436940Skarels overbose = verbose; 58536940Skarels if (debug == 0) 58636940Skarels verbose = -1; 58736935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 58836935Skarels int yy, mo, day, hour, min, sec; 58936935Skarels struct tm *tm; 59036935Skarels verbose = overbose; 59136935Skarels sscanf(reply_string, 59236935Skarels "%*s %04d%02d%02d%02d%02d%02d", 59336935Skarels &yy, &mo, &day, &hour, &min, &sec); 59436935Skarels tm = gmtime(&stbuf.st_mtime); 59536935Skarels tm->tm_mon++; 59636935Skarels if (tm->tm_year > yy%100) 59736940Skarels return (1); 59836935Skarels else if (tm->tm_year == yy%100) { 59936935Skarels if (tm->tm_mon > mo) 60036940Skarels return (1); 60136935Skarels } else if (tm->tm_mon == mo) { 60236935Skarels if (tm->tm_mday > day) 60336940Skarels return (1); 60436935Skarels } else if (tm->tm_mday == day) { 60536935Skarels if (tm->tm_hour > hour) 60636940Skarels return (1); 60736935Skarels } else if (tm->tm_hour == hour) { 60836935Skarels if (tm->tm_min > min) 60936940Skarels return (1); 61036935Skarels } else if (tm->tm_min == min) { 61136935Skarels if (tm->tm_sec > sec) 61236940Skarels return (1); 61336935Skarels } 61436935Skarels } else { 61536935Skarels fputs(reply_string, stdout); 61636935Skarels verbose = overbose; 61736940Skarels return (0); 61836935Skarels } 61936935Skarels } 62036935Skarels } 62136935Skarels } 62236935Skarels 62336935Skarels recvrequest("RETR", argv[2], argv[1], mode); 62436935Skarels restart_point = 0; 62536940Skarels return (0); 626*36942Skarels #else 627*36942Skarels recvrequest("RETR", argv[2], argv[1], "w"); 628*36942Skarels #endif 62910294Ssam } 63010294Ssam 63126049Sminshall mabort() 63226049Sminshall { 63326049Sminshall int ointer; 63426049Sminshall extern jmp_buf jabort; 63526049Sminshall 63626049Sminshall printf("\n"); 63726049Sminshall (void) fflush(stdout); 63826049Sminshall if (mflag && fromatty) { 63926049Sminshall ointer = interactive; 64026049Sminshall interactive = 1; 64126049Sminshall if (confirm("Continue with", mname)) { 64226049Sminshall interactive = ointer; 64326049Sminshall longjmp(jabort,0); 64426049Sminshall } 64526049Sminshall interactive = ointer; 64626049Sminshall } 64726049Sminshall mflag = 0; 64826049Sminshall longjmp(jabort,0); 64926049Sminshall } 65026049Sminshall 65111353Ssam /* 65211353Ssam * Get multiple files. 65311353Ssam */ 65411353Ssam mget(argc, argv) 65511353Ssam char *argv[]; 65611353Ssam { 65726049Sminshall char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; 65826049Sminshall int ointer, (*oldintr)(), mabort(); 65926049Sminshall extern jmp_buf jabort; 66011353Ssam 66111353Ssam if (argc < 2) { 66226497Sminshall (void) strcat(line, " "); 66311756Ssam printf("(remote-files) "); 66426497Sminshall (void) gets(&line[strlen(line)]); 66511353Ssam makeargv(); 66611353Ssam argc = margc; 66711353Ssam argv = margv; 66811353Ssam } 66911353Ssam if (argc < 2) { 67026049Sminshall printf("usage:%s remote-files\n", argv[0]); 67126049Sminshall code = -1; 67211353Ssam return; 67311353Ssam } 67426049Sminshall mname = argv[0]; 67526049Sminshall mflag = 1; 67626049Sminshall oldintr = signal(SIGINT,mabort); 67726049Sminshall (void) setjmp(jabort); 67826497Sminshall while ((cp = remglob(argv,proxy)) != NULL) { 67926049Sminshall if (*cp == '\0') { 68026049Sminshall mflag = 0; 68126049Sminshall continue; 68226049Sminshall } 68326049Sminshall if (mflag && confirm(argv[0], cp)) { 68426049Sminshall tp = cp; 68526049Sminshall if (mcase) { 68626049Sminshall while (*tp && !islower(*tp)) { 68726049Sminshall tp++; 68826049Sminshall } 68926049Sminshall if (!*tp) { 69026049Sminshall tp = cp; 69126049Sminshall tp2 = tmpbuf; 69226049Sminshall while ((*tp2 = *tp) != NULL) { 69326049Sminshall if (isupper(*tp2)) { 69426049Sminshall *tp2 = 'a' + *tp2 - 'A'; 69526049Sminshall } 69626049Sminshall tp++; 69726049Sminshall tp2++; 69826049Sminshall } 69926049Sminshall } 70026049Sminshall tp = tmpbuf; 70126049Sminshall } 70226049Sminshall if (ntflag) { 70326049Sminshall tp = dotrans(tp); 70426049Sminshall } 70526049Sminshall if (mapflag) { 70626049Sminshall tp = domap(tp); 70726049Sminshall } 70826049Sminshall recvrequest("RETR", tp, cp, "w"); 70926049Sminshall if (!mflag && fromatty) { 71026049Sminshall ointer = interactive; 71126049Sminshall interactive = 1; 71226049Sminshall if (confirm("Continue with","mget")) { 71326049Sminshall mflag++; 71426049Sminshall } 71526049Sminshall interactive = ointer; 71626049Sminshall } 71726049Sminshall } 71826049Sminshall } 71926049Sminshall (void) signal(SIGINT,oldintr); 72026049Sminshall mflag = 0; 72111650Ssam } 72211650Ssam 72311650Ssam char * 72426497Sminshall remglob(argv,doswitch) 72511650Ssam char *argv[]; 72626497Sminshall int doswitch; 72711650Ssam { 72811756Ssam char temp[16]; 72911650Ssam static char buf[MAXPATHLEN]; 73011650Ssam static FILE *ftemp = NULL; 73111650Ssam static char **args; 73213212Ssam int oldverbose, oldhash; 73311756Ssam char *cp, *mode; 73411650Ssam 73526049Sminshall if (!mflag) { 73626049Sminshall if (!doglob) { 73726049Sminshall args = NULL; 73826049Sminshall } 73926049Sminshall else { 74026049Sminshall if (ftemp) { 74126497Sminshall (void) fclose(ftemp); 74226049Sminshall ftemp = NULL; 74326049Sminshall } 74426049Sminshall } 74526049Sminshall return(NULL); 74626049Sminshall } 74711650Ssam if (!doglob) { 74811756Ssam if (args == NULL) 74911650Ssam args = argv; 75011650Ssam if ((cp = *++args) == NULL) 75111650Ssam args = NULL; 75211650Ssam return (cp); 75311353Ssam } 75411650Ssam if (ftemp == NULL) { 75526497Sminshall (void) strcpy(temp, "/tmp/ftpXXXXXX"); 75626497Sminshall (void) mktemp(temp); 75711650Ssam oldverbose = verbose, verbose = 0; 75813212Ssam oldhash = hash, hash = 0; 75926049Sminshall if (doswitch) { 76026049Sminshall pswitch(!proxy); 76126049Sminshall } 76211756Ssam for (mode = "w"; *++argv != NULL; mode = "a") 76311756Ssam recvrequest ("NLST", temp, *argv, mode); 76426049Sminshall if (doswitch) { 76526049Sminshall pswitch(!proxy); 76626049Sminshall } 76713212Ssam verbose = oldverbose; hash = oldhash; 76811650Ssam ftemp = fopen(temp, "r"); 76926497Sminshall (void) unlink(temp); 77011650Ssam if (ftemp == NULL) { 77111650Ssam printf("can't find list of remote files, oops\n"); 77211756Ssam return (NULL); 77311353Ssam } 77411353Ssam } 77511650Ssam if (fgets(buf, sizeof (buf), ftemp) == NULL) { 77626497Sminshall (void) fclose(ftemp), ftemp = NULL; 77711650Ssam return (NULL); 77811353Ssam } 77911650Ssam if ((cp = index(buf, '\n')) != NULL) 78011650Ssam *cp = '\0'; 78111650Ssam return (buf); 78211353Ssam } 78311353Ssam 78410294Ssam char * 78510294Ssam onoff(bool) 78610294Ssam int bool; 78710294Ssam { 78810294Ssam 78910294Ssam return (bool ? "on" : "off"); 79010294Ssam } 79110294Ssam 79210294Ssam /* 79310294Ssam * Show status. 79410294Ssam */ 79526497Sminshall /*ARGSUSED*/ 79610294Ssam status(argc, argv) 79710294Ssam char *argv[]; 79810294Ssam { 79926049Sminshall int i; 80010294Ssam 80110294Ssam if (connected) 80210294Ssam printf("Connected to %s.\n", hostname); 80310294Ssam else 80410294Ssam printf("Not connected.\n"); 80526049Sminshall if (!proxy) { 80626049Sminshall pswitch(1); 80726049Sminshall if (connected) { 80826049Sminshall printf("Connected for proxy commands to %s.\n", hostname); 80926049Sminshall } 81026049Sminshall else { 81126049Sminshall printf("No proxy connection.\n"); 81226049Sminshall } 81326049Sminshall pswitch(0); 81426049Sminshall } 81510294Ssam printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", 81610294Ssam modename, typename, formname, structname); 81711353Ssam printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 81811353Ssam onoff(verbose), onoff(bell), onoff(interactive), 81911353Ssam onoff(doglob)); 82026049Sminshall printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), 82126049Sminshall onoff(runique)); 82226049Sminshall printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); 82326049Sminshall if (ntflag) { 82426049Sminshall printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); 82526049Sminshall } 82626049Sminshall else { 82726049Sminshall printf("Ntrans: off\n"); 82826049Sminshall } 82926049Sminshall if (mapflag) { 83026049Sminshall printf("Nmap: (in) %s (out) %s\n", mapin, mapout); 83126049Sminshall } 83226049Sminshall else { 83326049Sminshall printf("Nmap: off\n"); 83426049Sminshall } 83514143Ssam printf("Hash mark printing: %s; Use of PORT cmds: %s\n", 83614143Ssam onoff(hash), onoff(sendport)); 83726049Sminshall if (macnum > 0) { 83826049Sminshall printf("Macros:\n"); 83926049Sminshall for (i=0; i<macnum; i++) { 84026049Sminshall printf("\t%s\n",macros[i].mac_name); 84126049Sminshall } 84226049Sminshall } 84326049Sminshall code = 0; 84410294Ssam } 84510294Ssam 84610294Ssam /* 84710294Ssam * Set beep on cmd completed mode. 84810294Ssam */ 84910294Ssam /*VARARGS*/ 85010294Ssam setbell() 85110294Ssam { 85210294Ssam 85310294Ssam bell = !bell; 85410294Ssam printf("Bell mode %s.\n", onoff(bell)); 85526049Sminshall code = bell; 85610294Ssam } 85710294Ssam 85810294Ssam /* 85910294Ssam * Turn on packet tracing. 86010294Ssam */ 86110294Ssam /*VARARGS*/ 86210294Ssam settrace() 86310294Ssam { 86410294Ssam 86510294Ssam trace = !trace; 86610294Ssam printf("Packet tracing %s.\n", onoff(trace)); 86726049Sminshall code = trace; 86810294Ssam } 86910294Ssam 87010294Ssam /* 87111650Ssam * Toggle hash mark printing during transfers. 87211650Ssam */ 87311650Ssam /*VARARGS*/ 87411650Ssam sethash() 87511650Ssam { 87611650Ssam 87711650Ssam hash = !hash; 87811650Ssam printf("Hash mark printing %s", onoff(hash)); 87926049Sminshall code = hash; 88011650Ssam if (hash) 88111650Ssam printf(" (%d bytes/hash mark)", BUFSIZ); 88211650Ssam printf(".\n"); 88311650Ssam } 88411650Ssam 88511650Ssam /* 88610294Ssam * Turn on printing of server echo's. 88710294Ssam */ 88810294Ssam /*VARARGS*/ 88910294Ssam setverbose() 89010294Ssam { 89110294Ssam 89210294Ssam verbose = !verbose; 89310294Ssam printf("Verbose mode %s.\n", onoff(verbose)); 89426049Sminshall code = verbose; 89510294Ssam } 89610294Ssam 89710294Ssam /* 89811650Ssam * Toggle PORT cmd use before each data connection. 89911650Ssam */ 90011650Ssam /*VARARGS*/ 90111650Ssam setport() 90211650Ssam { 90311650Ssam 90411650Ssam sendport = !sendport; 90511650Ssam printf("Use of PORT cmds %s.\n", onoff(sendport)); 90626049Sminshall code = sendport; 90711650Ssam } 90811650Ssam 90911650Ssam /* 91010294Ssam * Turn on interactive prompting 91110294Ssam * during mget, mput, and mdelete. 91210294Ssam */ 91310294Ssam /*VARARGS*/ 91410294Ssam setprompt() 91510294Ssam { 91610294Ssam 91710294Ssam interactive = !interactive; 91810294Ssam printf("Interactive mode %s.\n", onoff(interactive)); 91926049Sminshall code = interactive; 92010294Ssam } 92110294Ssam 92210294Ssam /* 92311353Ssam * Toggle metacharacter interpretation 92411353Ssam * on local file names. 92511353Ssam */ 92611353Ssam /*VARARGS*/ 92711353Ssam setglob() 92811353Ssam { 92911353Ssam 93011353Ssam doglob = !doglob; 93111353Ssam printf("Globbing %s.\n", onoff(doglob)); 93226049Sminshall code = doglob; 93311353Ssam } 93411353Ssam 93511353Ssam /* 93610294Ssam * Set debugging mode on/off and/or 93710294Ssam * set level of debugging. 93810294Ssam */ 93911756Ssam /*VARARGS*/ 94010294Ssam setdebug(argc, argv) 94110294Ssam char *argv[]; 94210294Ssam { 94310294Ssam int val; 94410294Ssam 94510294Ssam if (argc > 1) { 94610294Ssam val = atoi(argv[1]); 94710294Ssam if (val < 0) { 94810294Ssam printf("%s: bad debugging value.\n", argv[1]); 94926049Sminshall code = -1; 95010294Ssam return; 95110294Ssam } 95210294Ssam } else 95310294Ssam val = !debug; 95410294Ssam debug = val; 95510294Ssam if (debug) 95610294Ssam options |= SO_DEBUG; 95710294Ssam else 95810294Ssam options &= ~SO_DEBUG; 95910294Ssam printf("Debugging %s (debug=%d).\n", onoff(debug), debug); 96026049Sminshall code = debug > 0; 96110294Ssam } 96210294Ssam 96310294Ssam /* 96410294Ssam * Set current working directory 96510294Ssam * on remote machine. 96610294Ssam */ 96710294Ssam cd(argc, argv) 96810294Ssam char *argv[]; 96910294Ssam { 97010294Ssam 97110294Ssam if (argc < 2) { 97226497Sminshall (void) strcat(line, " "); 97310294Ssam printf("(remote-directory) "); 97426497Sminshall (void) gets(&line[strlen(line)]); 97510294Ssam makeargv(); 97610294Ssam argc = margc; 97710294Ssam argv = margv; 97810294Ssam } 97910294Ssam if (argc < 2) { 98026049Sminshall printf("usage:%s remote-directory\n", argv[0]); 98126049Sminshall code = -1; 98210294Ssam return; 98310294Ssam } 98410294Ssam (void) command("CWD %s", argv[1]); 98510294Ssam } 98610294Ssam 98710294Ssam /* 98810294Ssam * Set current working directory 98910294Ssam * on local machine. 99010294Ssam */ 99110294Ssam lcd(argc, argv) 99210294Ssam char *argv[]; 99310294Ssam { 99411353Ssam char buf[MAXPATHLEN]; 99510294Ssam 99611353Ssam if (argc < 2) 99711353Ssam argc++, argv[1] = home; 99810294Ssam if (argc != 2) { 99926049Sminshall printf("usage:%s local-directory\n", argv[0]); 100026049Sminshall code = -1; 100110294Ssam return; 100210294Ssam } 100326049Sminshall if (!globulize(&argv[1])) { 100426049Sminshall code = -1; 100511353Ssam return; 100626049Sminshall } 100711353Ssam if (chdir(argv[1]) < 0) { 100810294Ssam perror(argv[1]); 100926049Sminshall code = -1; 101011353Ssam return; 101111353Ssam } 101211353Ssam printf("Local directory now %s\n", getwd(buf)); 101326049Sminshall code = 0; 101410294Ssam } 101510294Ssam 101610294Ssam /* 101710294Ssam * Delete a single file. 101810294Ssam */ 101910294Ssam delete(argc, argv) 102010294Ssam char *argv[]; 102110294Ssam { 102210294Ssam 102310294Ssam if (argc < 2) { 102426497Sminshall (void) strcat(line, " "); 102510294Ssam printf("(remote-file) "); 102626497Sminshall (void) gets(&line[strlen(line)]); 102710294Ssam makeargv(); 102810294Ssam argc = margc; 102910294Ssam argv = margv; 103010294Ssam } 103110294Ssam if (argc < 2) { 103226049Sminshall printf("usage:%s remote-file\n", argv[0]); 103326049Sminshall code = -1; 103410294Ssam return; 103510294Ssam } 103610294Ssam (void) command("DELE %s", argv[1]); 103710294Ssam } 103810294Ssam 103910294Ssam /* 104011650Ssam * Delete multiple files. 104111650Ssam */ 104211650Ssam mdelete(argc, argv) 104311650Ssam char *argv[]; 104411650Ssam { 104511650Ssam char *cp; 104626049Sminshall int ointer, (*oldintr)(), mabort(); 104726049Sminshall extern jmp_buf jabort; 104811650Ssam 104911650Ssam if (argc < 2) { 105026497Sminshall (void) strcat(line, " "); 105111650Ssam printf("(remote-files) "); 105226497Sminshall (void) gets(&line[strlen(line)]); 105311650Ssam makeargv(); 105411650Ssam argc = margc; 105511650Ssam argv = margv; 105611650Ssam } 105711650Ssam if (argc < 2) { 105826049Sminshall printf("usage:%s remote-files\n", argv[0]); 105926049Sminshall code = -1; 106011650Ssam return; 106111650Ssam } 106226049Sminshall mname = argv[0]; 106326049Sminshall mflag = 1; 106426049Sminshall oldintr = signal(SIGINT, mabort); 106526049Sminshall (void) setjmp(jabort); 106626497Sminshall while ((cp = remglob(argv,0)) != NULL) { 106726049Sminshall if (*cp == '\0') { 106826049Sminshall mflag = 0; 106926049Sminshall continue; 107026049Sminshall } 107126049Sminshall if (mflag && confirm(argv[0], cp)) { 107211650Ssam (void) command("DELE %s", cp); 107326049Sminshall if (!mflag && fromatty) { 107426049Sminshall ointer = interactive; 107526049Sminshall interactive = 1; 107626049Sminshall if (confirm("Continue with", "mdelete")) { 107726049Sminshall mflag++; 107826049Sminshall } 107926049Sminshall interactive = ointer; 108026049Sminshall } 108126049Sminshall } 108226049Sminshall } 108326049Sminshall (void) signal(SIGINT, oldintr); 108426049Sminshall mflag = 0; 108511650Ssam } 108611756Ssam 108711650Ssam /* 108810294Ssam * Rename a remote file. 108910294Ssam */ 109010294Ssam renamefile(argc, argv) 109110294Ssam char *argv[]; 109210294Ssam { 109310294Ssam 109410294Ssam if (argc < 2) { 109526497Sminshall (void) strcat(line, " "); 109610294Ssam printf("(from-name) "); 109726497Sminshall (void) gets(&line[strlen(line)]); 109810294Ssam makeargv(); 109910294Ssam argc = margc; 110010294Ssam argv = margv; 110110294Ssam } 110210294Ssam if (argc < 2) { 110310294Ssam usage: 110410294Ssam printf("%s from-name to-name\n", argv[0]); 110526049Sminshall code = -1; 110610294Ssam return; 110710294Ssam } 110810294Ssam if (argc < 3) { 110926497Sminshall (void) strcat(line, " "); 111010294Ssam printf("(to-name) "); 111126497Sminshall (void) gets(&line[strlen(line)]); 111210294Ssam makeargv(); 111310294Ssam argc = margc; 111410294Ssam argv = margv; 111510294Ssam } 111610294Ssam if (argc < 3) 111710294Ssam goto usage; 111810294Ssam if (command("RNFR %s", argv[1]) == CONTINUE) 111910294Ssam (void) command("RNTO %s", argv[2]); 112010294Ssam } 112110294Ssam 112210294Ssam /* 112310294Ssam * Get a directory listing 112410294Ssam * of remote files. 112510294Ssam */ 112610294Ssam ls(argc, argv) 112710294Ssam char *argv[]; 112810294Ssam { 112911756Ssam char *cmd; 113010294Ssam 113110294Ssam if (argc < 2) 113210294Ssam argc++, argv[1] = NULL; 113310294Ssam if (argc < 3) 113410294Ssam argc++, argv[2] = "-"; 113511756Ssam if (argc > 3) { 113611756Ssam printf("usage: %s remote-directory local-file\n", argv[0]); 113726049Sminshall code = -1; 113811756Ssam return; 113911756Ssam } 114036935Skarels cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; 114126049Sminshall if (strcmp(argv[2], "-") && !globulize(&argv[2])) { 114226049Sminshall code = -1; 114311353Ssam return; 114426049Sminshall } 114532344Scsvsj if (strcmp(argv[2], "-") && *argv[2] != '|') 114632344Scsvsj if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { 114732344Scsvsj code = -1; 114832344Scsvsj return; 114932344Scsvsj } 115011756Ssam recvrequest(cmd, argv[2], argv[1], "w"); 115110294Ssam } 115210294Ssam 115310294Ssam /* 115411756Ssam * Get a directory listing 115511756Ssam * of multiple remote files. 115611756Ssam */ 115711756Ssam mls(argc, argv) 115811756Ssam char *argv[]; 115911756Ssam { 116026049Sminshall char *cmd, mode[1], *dest; 116126049Sminshall int ointer, i, (*oldintr)(), mabort(); 116226049Sminshall extern jmp_buf jabort; 116311756Ssam 116413212Ssam if (argc < 2) { 116526497Sminshall (void) strcat(line, " "); 116613212Ssam printf("(remote-files) "); 116726497Sminshall (void) gets(&line[strlen(line)]); 116813212Ssam makeargv(); 116913212Ssam argc = margc; 117013212Ssam argv = margv; 117113212Ssam } 117213212Ssam if (argc < 3) { 117326497Sminshall (void) strcat(line, " "); 117413212Ssam printf("(local-file) "); 117526497Sminshall (void) gets(&line[strlen(line)]); 117613212Ssam makeargv(); 117713212Ssam argc = margc; 117813212Ssam argv = margv; 117913212Ssam } 118013212Ssam if (argc < 3) { 118126049Sminshall printf("usage:%s remote-files local-file\n", argv[0]); 118226049Sminshall code = -1; 118313212Ssam return; 118413212Ssam } 118513212Ssam dest = argv[argc - 1]; 118613212Ssam argv[argc - 1] = NULL; 118726049Sminshall if (strcmp(dest, "-") && *dest != '|') 118826049Sminshall if (!globulize(&dest) || !confirm("output to local-file:", dest)) { 118926049Sminshall code = -1; 119013212Ssam return; 119126049Sminshall } 119236940Skarels cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; 119326049Sminshall mname = argv[0]; 119426049Sminshall mflag = 1; 119526049Sminshall oldintr = signal(SIGINT, mabort); 119626049Sminshall (void) setjmp(jabort); 119726049Sminshall for (i = 1; mflag && i < argc-1; ++i) { 119826049Sminshall *mode = (i == 1) ? 'w' : 'a'; 119926049Sminshall recvrequest(cmd, dest, argv[i], mode); 120026049Sminshall if (!mflag && fromatty) { 120126049Sminshall ointer = interactive; 120226049Sminshall interactive = 1; 120326049Sminshall if (confirm("Continue with", argv[0])) { 120426049Sminshall mflag ++; 120526049Sminshall } 120626049Sminshall interactive = ointer; 120726049Sminshall } 120826049Sminshall } 120926049Sminshall (void) signal(SIGINT, oldintr); 121026049Sminshall mflag = 0; 121111756Ssam } 121211756Ssam 121311756Ssam /* 121410294Ssam * Do a shell escape 121510294Ssam */ 121626497Sminshall /*ARGSUSED*/ 121710294Ssam shell(argc, argv) 121810294Ssam char *argv[]; 121910294Ssam { 122026497Sminshall int pid, (*old1)(), (*old2)(); 122126049Sminshall char shellnam[40], *shell, *namep; 122226497Sminshall union wait status; 122310294Ssam 122411756Ssam old1 = signal (SIGINT, SIG_IGN); 122511756Ssam old2 = signal (SIGQUIT, SIG_IGN); 122611756Ssam if ((pid = fork()) == 0) { 122711756Ssam for (pid = 3; pid < 20; pid++) 122826497Sminshall (void) close(pid); 122926497Sminshall (void) signal(SIGINT, SIG_DFL); 123026497Sminshall (void) signal(SIGQUIT, SIG_DFL); 123125908Smckusick shell = getenv("SHELL"); 123225908Smckusick if (shell == NULL) 123325908Smckusick shell = "/bin/sh"; 123425908Smckusick namep = rindex(shell,'/'); 123525908Smckusick if (namep == NULL) 123625908Smckusick namep = shell; 123726497Sminshall (void) strcpy(shellnam,"-"); 123826497Sminshall (void) strcat(shellnam, ++namep); 123926049Sminshall if (strcmp(namep, "sh") != 0) 124026049Sminshall shellnam[0] = '+'; 124126049Sminshall if (debug) { 124226049Sminshall printf ("%s\n", shell); 124326497Sminshall (void) fflush (stdout); 124411756Ssam } 124526049Sminshall if (argc > 1) { 124626049Sminshall execl(shell,shellnam,"-c",altarg,(char *)0); 124726049Sminshall } 124826049Sminshall else { 124926049Sminshall execl(shell,shellnam,(char *)0); 125026049Sminshall } 125125908Smckusick perror(shell); 125226049Sminshall code = -1; 125311756Ssam exit(1); 125426049Sminshall } 125511756Ssam if (pid > 0) 125611756Ssam while (wait(&status) != pid) 125711756Ssam ; 125826497Sminshall (void) signal(SIGINT, old1); 125926497Sminshall (void) signal(SIGQUIT, old2); 126026049Sminshall if (pid == -1) { 126111756Ssam perror("Try again later"); 126226049Sminshall code = -1; 126326049Sminshall } 126426049Sminshall else { 126526049Sminshall code = 0; 126626049Sminshall } 126711756Ssam return (0); 126810294Ssam } 126910294Ssam 127010294Ssam /* 127110294Ssam * Send new user information (re-login) 127210294Ssam */ 127310294Ssam user(argc, argv) 127410294Ssam int argc; 127510294Ssam char **argv; 127610294Ssam { 127735658Sbostic char acct[80], *getpass(); 127826049Sminshall int n, aflag = 0; 127910294Ssam 128010294Ssam if (argc < 2) { 128126497Sminshall (void) strcat(line, " "); 128210294Ssam printf("(username) "); 128326497Sminshall (void) gets(&line[strlen(line)]); 128410294Ssam makeargv(); 128510294Ssam argc = margc; 128610294Ssam argv = margv; 128710294Ssam } 128810294Ssam if (argc > 4) { 128910294Ssam printf("usage: %s username [password] [account]\n", argv[0]); 129026049Sminshall code = -1; 129111756Ssam return (0); 129210294Ssam } 129310294Ssam n = command("USER %s", argv[1]); 129410294Ssam if (n == CONTINUE) { 129510294Ssam if (argc < 3 ) 129635658Sbostic argv[2] = getpass("Password: "), argc++; 129710294Ssam n = command("PASS %s", argv[2]); 129810294Ssam } 129910294Ssam if (n == CONTINUE) { 130010294Ssam if (argc < 4) { 130110294Ssam printf("Account: "); (void) fflush(stdout); 130210294Ssam (void) fgets(acct, sizeof(acct) - 1, stdin); 130310294Ssam acct[strlen(acct) - 1] = '\0'; 130410294Ssam argv[3] = acct; argc++; 130510294Ssam } 130626049Sminshall n = command("ACCT %s", argv[3]); 130726049Sminshall aflag++; 130810294Ssam } 130910294Ssam if (n != COMPLETE) { 131026497Sminshall fprintf(stdout, "Login failed.\n"); 131110294Ssam return (0); 131210294Ssam } 131326049Sminshall if (!aflag && argc == 4) { 131426049Sminshall (void) command("ACCT %s", argv[3]); 131526049Sminshall } 131610294Ssam return (1); 131710294Ssam } 131810294Ssam 131910294Ssam /* 132010294Ssam * Print working directory. 132110294Ssam */ 132210294Ssam /*VARARGS*/ 132310294Ssam pwd() 132410294Ssam { 132511756Ssam 132626049Sminshall (void) command("PWD"); 132710294Ssam } 132810294Ssam 132910294Ssam /* 133010294Ssam * Make a directory. 133110294Ssam */ 133210294Ssam makedir(argc, argv) 133310294Ssam char *argv[]; 133410294Ssam { 133510294Ssam 133610294Ssam if (argc < 2) { 133726497Sminshall (void) strcat(line, " "); 133810294Ssam printf("(directory-name) "); 133926497Sminshall (void) gets(&line[strlen(line)]); 134010294Ssam makeargv(); 134110294Ssam argc = margc; 134210294Ssam argv = margv; 134310294Ssam } 134410294Ssam if (argc < 2) { 134526049Sminshall printf("usage: %s directory-name\n", argv[0]); 134626049Sminshall code = -1; 134710294Ssam return; 134810294Ssam } 134926049Sminshall (void) command("MKD %s", argv[1]); 135010294Ssam } 135110294Ssam 135210294Ssam /* 135310294Ssam * Remove a directory. 135410294Ssam */ 135510294Ssam removedir(argc, argv) 135610294Ssam char *argv[]; 135710294Ssam { 135810294Ssam 135910294Ssam if (argc < 2) { 136026497Sminshall (void) strcat(line, " "); 136110294Ssam printf("(directory-name) "); 136226497Sminshall (void) gets(&line[strlen(line)]); 136310294Ssam makeargv(); 136410294Ssam argc = margc; 136510294Ssam argv = margv; 136610294Ssam } 136710294Ssam if (argc < 2) { 136826049Sminshall printf("usage: %s directory-name\n", argv[0]); 136926049Sminshall code = -1; 137010294Ssam return; 137110294Ssam } 137226049Sminshall (void) command("RMD %s", argv[1]); 137310294Ssam } 137410294Ssam 137510294Ssam /* 137610294Ssam * Send a line, verbatim, to the remote machine. 137710294Ssam */ 137810294Ssam quote(argc, argv) 137910294Ssam char *argv[]; 138010294Ssam { 138110294Ssam int i; 138210294Ssam char buf[BUFSIZ]; 138310294Ssam 138410294Ssam if (argc < 2) { 138526497Sminshall (void) strcat(line, " "); 138610294Ssam printf("(command line to send) "); 138726497Sminshall (void) gets(&line[strlen(line)]); 138810294Ssam makeargv(); 138910294Ssam argc = margc; 139010294Ssam argv = margv; 139110294Ssam } 139210294Ssam if (argc < 2) { 139310294Ssam printf("usage: %s line-to-send\n", argv[0]); 139426049Sminshall code = -1; 139510294Ssam return; 139610294Ssam } 139726497Sminshall (void) strcpy(buf, argv[1]); 139810294Ssam for (i = 2; i < argc; i++) { 139926497Sminshall (void) strcat(buf, " "); 140026497Sminshall (void) strcat(buf, argv[i]); 140110294Ssam } 140226049Sminshall if (command(buf) == PRELIM) { 140326049Sminshall while (getreply(0) == PRELIM); 140426049Sminshall } 140510294Ssam } 140610294Ssam 140710294Ssam /* 140810294Ssam * Ask the other side for help. 140910294Ssam */ 141010294Ssam rmthelp(argc, argv) 141110294Ssam char *argv[]; 141210294Ssam { 141310294Ssam int oldverbose = verbose; 141410294Ssam 141510294Ssam verbose = 1; 141610294Ssam (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); 141710294Ssam verbose = oldverbose; 141810294Ssam } 141910294Ssam 142010294Ssam /* 142110294Ssam * Terminate session and exit. 142210294Ssam */ 142310294Ssam /*VARARGS*/ 142410294Ssam quit() 142510294Ssam { 142610294Ssam 142718286Sralph if (connected) 142818286Sralph disconnect(); 142926049Sminshall pswitch(1); 143026049Sminshall if (connected) { 143126049Sminshall disconnect(); 143226049Sminshall } 143310294Ssam exit(0); 143410294Ssam } 143510294Ssam 143610294Ssam /* 143710294Ssam * Terminate session, but don't exit. 143810294Ssam */ 143910294Ssam disconnect() 144010294Ssam { 144110294Ssam extern FILE *cout; 144210294Ssam extern int data; 144310294Ssam 144410294Ssam if (!connected) 144510294Ssam return; 144610294Ssam (void) command("QUIT"); 144726049Sminshall if (cout) { 144826049Sminshall (void) fclose(cout); 144926049Sminshall } 145010294Ssam cout = NULL; 145110294Ssam connected = 0; 145210294Ssam data = -1; 145326049Sminshall if (!proxy) { 145426049Sminshall macnum = 0; 145526049Sminshall } 145610294Ssam } 145711353Ssam 145811650Ssam confirm(cmd, file) 145911353Ssam char *cmd, *file; 146011353Ssam { 146111353Ssam char line[BUFSIZ]; 146211353Ssam 146311353Ssam if (!interactive) 146411650Ssam return (1); 146511353Ssam printf("%s %s? ", cmd, file); 146626497Sminshall (void) fflush(stdout); 146726497Sminshall (void) gets(line); 146811650Ssam return (*line != 'n' && *line != 'N'); 146911353Ssam } 147011353Ssam 147111353Ssam fatal(msg) 147211353Ssam char *msg; 147311353Ssam { 147411353Ssam 147526497Sminshall fprintf(stderr, "ftp: %s\n", msg); 147611353Ssam exit(1); 147711353Ssam } 147811353Ssam 147911353Ssam /* 148011353Ssam * Glob a local file name specification with 148111353Ssam * the expectation of a single return value. 148211353Ssam * Can't control multiple values being expanded 148311353Ssam * from the expression, we return only the first. 148411353Ssam */ 148511353Ssam globulize(cpp) 148611353Ssam char **cpp; 148711353Ssam { 148811353Ssam char **globbed; 148911353Ssam 149011353Ssam if (!doglob) 149111353Ssam return (1); 149211353Ssam globbed = glob(*cpp); 149311353Ssam if (globerr != NULL) { 149411353Ssam printf("%s: %s\n", *cpp, globerr); 149536421Sbostic if (globbed) { 149611353Ssam blkfree(globbed); 149736421Sbostic free(globbed); 149836421Sbostic } 149911353Ssam return (0); 150011353Ssam } 150111353Ssam if (globbed) { 150211353Ssam *cpp = *globbed++; 150311353Ssam /* don't waste too much memory */ 150436421Sbostic if (*globbed) { 150511353Ssam blkfree(globbed); 150636421Sbostic free(globbed); 150736421Sbostic } 150811353Ssam } 150911353Ssam return (1); 151011353Ssam } 151126049Sminshall 151226049Sminshall account(argc,argv) 151326049Sminshall int argc; 151426049Sminshall char **argv; 151526049Sminshall { 151635658Sbostic char acct[50], *getpass(), *ap; 151726049Sminshall 151826049Sminshall if (argc > 1) { 151926049Sminshall ++argv; 152026049Sminshall --argc; 152126049Sminshall (void) strncpy(acct,*argv,49); 152236268Sbostic acct[49] = '\0'; 152326049Sminshall while (argc > 1) { 152426049Sminshall --argc; 152526049Sminshall ++argv; 152626049Sminshall (void) strncat(acct,*argv, 49-strlen(acct)); 152726049Sminshall } 152826049Sminshall ap = acct; 152926049Sminshall } 153026049Sminshall else { 153135658Sbostic ap = getpass("Account:"); 153226049Sminshall } 153326049Sminshall (void) command("ACCT %s", ap); 153426049Sminshall } 153526049Sminshall 153626049Sminshall jmp_buf abortprox; 153726049Sminshall 153826049Sminshall proxabort() 153926049Sminshall { 154026049Sminshall extern int proxy; 154126049Sminshall 154226049Sminshall if (!proxy) { 154326049Sminshall pswitch(1); 154426049Sminshall } 154526049Sminshall if (connected) { 154626049Sminshall proxflag = 1; 154726049Sminshall } 154826049Sminshall else { 154926049Sminshall proxflag = 0; 155026049Sminshall } 155126049Sminshall pswitch(0); 155226049Sminshall longjmp(abortprox,1); 155326049Sminshall } 155426049Sminshall 155526049Sminshall doproxy(argc,argv) 155626049Sminshall int argc; 155726049Sminshall char *argv[]; 155826049Sminshall { 155926049Sminshall int (*oldintr)(), proxabort(); 156026049Sminshall register struct cmd *c; 156126049Sminshall struct cmd *getcmd(); 156226049Sminshall extern struct cmd cmdtab[]; 156326049Sminshall extern jmp_buf abortprox; 156426049Sminshall 156526049Sminshall if (argc < 2) { 156626497Sminshall (void) strcat(line, " "); 156726049Sminshall printf("(command) "); 156826497Sminshall (void) gets(&line[strlen(line)]); 156926049Sminshall makeargv(); 157026049Sminshall argc = margc; 157126049Sminshall argv = margv; 157226049Sminshall } 157326049Sminshall if (argc < 2) { 157426049Sminshall printf("usage:%s command\n", argv[0]); 157526049Sminshall code = -1; 157626049Sminshall return; 157726049Sminshall } 157826049Sminshall c = getcmd(argv[1]); 157926049Sminshall if (c == (struct cmd *) -1) { 158026049Sminshall printf("?Ambiguous command\n"); 158126497Sminshall (void) fflush(stdout); 158226049Sminshall code = -1; 158326049Sminshall return; 158426049Sminshall } 158526049Sminshall if (c == 0) { 158626049Sminshall printf("?Invalid command\n"); 158726497Sminshall (void) fflush(stdout); 158826049Sminshall code = -1; 158926049Sminshall return; 159026049Sminshall } 159126049Sminshall if (!c->c_proxy) { 159226049Sminshall printf("?Invalid proxy command\n"); 159326497Sminshall (void) fflush(stdout); 159426049Sminshall code = -1; 159526049Sminshall return; 159626049Sminshall } 159726049Sminshall if (setjmp(abortprox)) { 159826049Sminshall code = -1; 159926049Sminshall return; 160026049Sminshall } 160126049Sminshall oldintr = signal(SIGINT, proxabort); 160226049Sminshall pswitch(1); 160326049Sminshall if (c->c_conn && !connected) { 160426049Sminshall printf("Not connected\n"); 160526497Sminshall (void) fflush(stdout); 160626049Sminshall pswitch(0); 160726049Sminshall (void) signal(SIGINT, oldintr); 160826049Sminshall code = -1; 160926049Sminshall return; 161026049Sminshall } 161126049Sminshall (*c->c_handler)(argc-1, argv+1); 161226049Sminshall if (connected) { 161326049Sminshall proxflag = 1; 161426049Sminshall } 161526049Sminshall else { 161626049Sminshall proxflag = 0; 161726049Sminshall } 161826049Sminshall pswitch(0); 161926049Sminshall (void) signal(SIGINT, oldintr); 162026049Sminshall } 162126049Sminshall 162226049Sminshall setcase() 162326049Sminshall { 162426049Sminshall mcase = !mcase; 162526049Sminshall printf("Case mapping %s.\n", onoff(mcase)); 162626049Sminshall code = mcase; 162726049Sminshall } 162826049Sminshall 162926049Sminshall setcr() 163026049Sminshall { 163126049Sminshall crflag = !crflag; 163226049Sminshall printf("Carriage Return stripping %s.\n", onoff(crflag)); 163326049Sminshall code = crflag; 163426049Sminshall } 163526049Sminshall 163626049Sminshall setntrans(argc,argv) 163726049Sminshall int argc; 163826049Sminshall char *argv[]; 163926049Sminshall { 164026049Sminshall if (argc == 1) { 164126049Sminshall ntflag = 0; 164226049Sminshall printf("Ntrans off.\n"); 164326049Sminshall code = ntflag; 164426049Sminshall return; 164526049Sminshall } 164626049Sminshall ntflag++; 164726049Sminshall code = ntflag; 164826049Sminshall (void) strncpy(ntin, argv[1], 16); 164926049Sminshall ntin[16] = '\0'; 165026049Sminshall if (argc == 2) { 165126049Sminshall ntout[0] = '\0'; 165226049Sminshall return; 165326049Sminshall } 165426049Sminshall (void) strncpy(ntout, argv[2], 16); 165526049Sminshall ntout[16] = '\0'; 165626049Sminshall } 165726049Sminshall 165826049Sminshall char * 165926049Sminshall dotrans(name) 166026049Sminshall char *name; 166126049Sminshall { 166226049Sminshall static char new[MAXPATHLEN]; 166326049Sminshall char *cp1, *cp2 = new; 166426049Sminshall register int i, ostop, found; 166526049Sminshall 166626049Sminshall for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); 166726049Sminshall for (cp1 = name; *cp1; cp1++) { 166826049Sminshall found = 0; 166926049Sminshall for (i = 0; *(ntin + i) && i < 16; i++) { 167026049Sminshall if (*cp1 == *(ntin + i)) { 167126049Sminshall found++; 167226049Sminshall if (i < ostop) { 167326049Sminshall *cp2++ = *(ntout + i); 167426049Sminshall } 167526049Sminshall break; 167626049Sminshall } 167726049Sminshall } 167826049Sminshall if (!found) { 167926049Sminshall *cp2++ = *cp1; 168026049Sminshall } 168126049Sminshall } 168226049Sminshall *cp2 = '\0'; 168326049Sminshall return(new); 168426049Sminshall } 168526049Sminshall 168626049Sminshall setnmap(argc, argv) 168726049Sminshall int argc; 168826049Sminshall char *argv[]; 168926049Sminshall { 169026049Sminshall char *cp; 169126049Sminshall 169226049Sminshall if (argc == 1) { 169326049Sminshall mapflag = 0; 169426049Sminshall printf("Nmap off.\n"); 169526049Sminshall code = mapflag; 169626049Sminshall return; 169726049Sminshall } 169826049Sminshall if (argc < 3) { 169926497Sminshall (void) strcat(line, " "); 170026049Sminshall printf("(mapout) "); 170126497Sminshall (void) gets(&line[strlen(line)]); 170226049Sminshall makeargv(); 170326049Sminshall argc = margc; 170426049Sminshall argv = margv; 170526049Sminshall } 170626049Sminshall if (argc < 3) { 170726049Sminshall printf("Usage: %s [mapin mapout]\n",argv[0]); 170826049Sminshall code = -1; 170926049Sminshall return; 171026049Sminshall } 171126049Sminshall mapflag = 1; 171226049Sminshall code = 1; 171326049Sminshall cp = index(altarg, ' '); 171426049Sminshall if (proxy) { 171526049Sminshall while(*++cp == ' '); 171626049Sminshall altarg = cp; 171726049Sminshall cp = index(altarg, ' '); 171826049Sminshall } 171926049Sminshall *cp = '\0'; 172026049Sminshall (void) strncpy(mapin, altarg, MAXPATHLEN - 1); 172126049Sminshall while (*++cp == ' '); 172226049Sminshall (void) strncpy(mapout, cp, MAXPATHLEN - 1); 172326049Sminshall } 172426049Sminshall 172526049Sminshall char * 172626049Sminshall domap(name) 172726049Sminshall char *name; 172826049Sminshall { 172926049Sminshall static char new[MAXPATHLEN]; 173026049Sminshall register char *cp1 = name, *cp2 = mapin; 173126049Sminshall char *tp[9], *te[9]; 173236689Scsvsj int i, toks[9], toknum = 0, match = 1; 173326049Sminshall 173426049Sminshall for (i=0; i < 9; ++i) { 173526049Sminshall toks[i] = 0; 173626049Sminshall } 173726049Sminshall while (match && *cp1 && *cp2) { 173826049Sminshall switch (*cp2) { 173926049Sminshall case '\\': 174026049Sminshall if (*++cp2 != *cp1) { 174126049Sminshall match = 0; 174226049Sminshall } 174326049Sminshall break; 174426049Sminshall case '$': 174526049Sminshall if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { 174626049Sminshall if (*cp1 != *(++cp2+1)) { 174726049Sminshall toks[toknum = *cp2 - '1']++; 174826049Sminshall tp[toknum] = cp1; 174926049Sminshall while (*++cp1 && *(cp2+1) 175026049Sminshall != *cp1); 175126049Sminshall te[toknum] = cp1; 175226049Sminshall } 175326049Sminshall cp2++; 175426049Sminshall break; 175526049Sminshall } 175636935Skarels /* FALLTHROUGH */ 175726049Sminshall default: 175826049Sminshall if (*cp2 != *cp1) { 175926049Sminshall match = 0; 176026049Sminshall } 176126049Sminshall break; 176226049Sminshall } 176336689Scsvsj if (match && *cp1) { 176426049Sminshall cp1++; 176526049Sminshall } 176636689Scsvsj if (match && *cp2) { 176726049Sminshall cp2++; 176826049Sminshall } 176926049Sminshall } 177036689Scsvsj if (!match && *cp1) /* last token mismatch */ 177136689Scsvsj { 177236689Scsvsj toks[toknum] = 0; 177336689Scsvsj } 177426049Sminshall cp1 = new; 177526049Sminshall *cp1 = '\0'; 177626049Sminshall cp2 = mapout; 177726049Sminshall while (*cp2) { 177826049Sminshall match = 0; 177926049Sminshall switch (*cp2) { 178026049Sminshall case '\\': 178126049Sminshall if (*(cp2 + 1)) { 178226049Sminshall *cp1++ = *++cp2; 178326049Sminshall } 178426049Sminshall break; 178526049Sminshall case '[': 178626049Sminshall LOOP: 178726049Sminshall if (*++cp2 == '$' && isdigit(*(cp2+1))) { 178826049Sminshall if (*++cp2 == '0') { 178926049Sminshall char *cp3 = name; 179026049Sminshall 179126049Sminshall while (*cp3) { 179226049Sminshall *cp1++ = *cp3++; 179326049Sminshall } 179426049Sminshall match = 1; 179526049Sminshall } 179626049Sminshall else if (toks[toknum = *cp2 - '1']) { 179726049Sminshall char *cp3 = tp[toknum]; 179826049Sminshall 179926049Sminshall while (cp3 != te[toknum]) { 180026049Sminshall *cp1++ = *cp3++; 180126049Sminshall } 180226049Sminshall match = 1; 180326049Sminshall } 180426049Sminshall } 180526049Sminshall else { 180626049Sminshall while (*cp2 && *cp2 != ',' && 180726049Sminshall *cp2 != ']') { 180826049Sminshall if (*cp2 == '\\') { 180926049Sminshall cp2++; 181026049Sminshall } 181126049Sminshall else if (*cp2 == '$' && 181226049Sminshall isdigit(*(cp2+1))) { 181326049Sminshall if (*++cp2 == '0') { 181426049Sminshall char *cp3 = name; 181526049Sminshall 181626049Sminshall while (*cp3) { 181726049Sminshall *cp1++ = *cp3++; 181826049Sminshall } 181926049Sminshall } 182026049Sminshall else if (toks[toknum = 182126049Sminshall *cp2 - '1']) { 182226049Sminshall char *cp3=tp[toknum]; 182326049Sminshall 182426049Sminshall while (cp3 != 182526049Sminshall te[toknum]) { 182626049Sminshall *cp1++ = *cp3++; 182726049Sminshall } 182826049Sminshall } 182926049Sminshall } 183026049Sminshall else if (*cp2) { 183126049Sminshall *cp1++ = *cp2++; 183226049Sminshall } 183326049Sminshall } 183426049Sminshall if (!*cp2) { 183526049Sminshall printf("nmap: unbalanced brackets\n"); 183626049Sminshall return(name); 183726049Sminshall } 183826049Sminshall match = 1; 183926049Sminshall cp2--; 184026049Sminshall } 184126049Sminshall if (match) { 184226049Sminshall while (*++cp2 && *cp2 != ']') { 184326049Sminshall if (*cp2 == '\\' && *(cp2 + 1)) { 184426049Sminshall cp2++; 184526049Sminshall } 184626049Sminshall } 184726049Sminshall if (!*cp2) { 184826049Sminshall printf("nmap: unbalanced brackets\n"); 184926049Sminshall return(name); 185026049Sminshall } 185126049Sminshall break; 185226049Sminshall } 185326049Sminshall switch (*++cp2) { 185426049Sminshall case ',': 185526049Sminshall goto LOOP; 185626049Sminshall case ']': 185726049Sminshall break; 185826049Sminshall default: 185926049Sminshall cp2--; 186026049Sminshall goto LOOP; 186126049Sminshall } 186226049Sminshall break; 186326049Sminshall case '$': 186426049Sminshall if (isdigit(*(cp2 + 1))) { 186526049Sminshall if (*++cp2 == '0') { 186626049Sminshall char *cp3 = name; 186726049Sminshall 186826049Sminshall while (*cp3) { 186926049Sminshall *cp1++ = *cp3++; 187026049Sminshall } 187126049Sminshall } 187226049Sminshall else if (toks[toknum = *cp2 - '1']) { 187326049Sminshall char *cp3 = tp[toknum]; 187426049Sminshall 187526049Sminshall while (cp3 != te[toknum]) { 187626049Sminshall *cp1++ = *cp3++; 187726049Sminshall } 187826049Sminshall } 187926049Sminshall break; 188026049Sminshall } 188126049Sminshall /* intentional drop through */ 188226049Sminshall default: 188326049Sminshall *cp1++ = *cp2; 188426049Sminshall break; 188526049Sminshall } 188626049Sminshall cp2++; 188726049Sminshall } 188826049Sminshall *cp1 = '\0'; 188926049Sminshall if (!*new) { 189026049Sminshall return(name); 189126049Sminshall } 189226049Sminshall return(new); 189326049Sminshall } 189426049Sminshall 189526049Sminshall setsunique() 189626049Sminshall { 189726049Sminshall sunique = !sunique; 189826049Sminshall printf("Store unique %s.\n", onoff(sunique)); 189926049Sminshall code = sunique; 190026049Sminshall } 190126049Sminshall 190226049Sminshall setrunique() 190326049Sminshall { 190426049Sminshall runique = !runique; 190526049Sminshall printf("Receive unique %s.\n", onoff(runique)); 190626049Sminshall code = runique; 190726049Sminshall } 190826049Sminshall 190926049Sminshall /* change directory to perent directory */ 191026049Sminshall cdup() 191126049Sminshall { 191226049Sminshall (void) command("CDUP"); 191326049Sminshall } 191426049Sminshall 1915*36942Skarels #ifdef RESTART 191636935Skarels /* restart transfer at specific point */ 191736935Skarels restart(argc, argv) 191836935Skarels int argc; 191936935Skarels char *argv[]; 192036935Skarels { 192136935Skarels extern long atol(); 192236935Skarels if (argc != 2) 192336935Skarels printf("restart: offset not specified\n"); 192436935Skarels else { 192536935Skarels restart_point = atol(argv[1]); 192636940Skarels printf("restarting at %ld. %s\n", restart_point, 192736940Skarels "execute get, put or append to initiate transfer"); 192836935Skarels } 192936935Skarels } 1930*36942Skarels #endif 193136935Skarels 193236935Skarels /* show remote system type */ 193336935Skarels syst() 193436935Skarels { 193536935Skarels (void) command("SYST"); 193636935Skarels } 193736935Skarels 193826049Sminshall macdef(argc, argv) 193926049Sminshall int argc; 194026049Sminshall char *argv[]; 194126049Sminshall { 194226049Sminshall char *tmp; 194326049Sminshall int c; 194426049Sminshall 194526049Sminshall if (macnum == 16) { 194626049Sminshall printf("Limit of 16 macros have already been defined\n"); 194726049Sminshall code = -1; 194826049Sminshall return; 194926049Sminshall } 195026049Sminshall if (argc < 2) { 195126497Sminshall (void) strcat(line, " "); 195226049Sminshall printf("(macro name) "); 195326497Sminshall (void) gets(&line[strlen(line)]); 195426049Sminshall makeargv(); 195526049Sminshall argc = margc; 195626049Sminshall argv = margv; 195726049Sminshall } 195826049Sminshall if (argc != 2) { 195926049Sminshall printf("Usage: %s macro_name\n",argv[0]); 196026049Sminshall code = -1; 196126049Sminshall return; 196226049Sminshall } 196326049Sminshall if (interactive) { 196426049Sminshall printf("Enter macro line by line, terminating it with a null line\n"); 196526049Sminshall } 196626497Sminshall (void) strncpy(macros[macnum].mac_name, argv[1], 8); 196726049Sminshall if (macnum == 0) { 196826049Sminshall macros[macnum].mac_start = macbuf; 196926049Sminshall } 197026049Sminshall else { 197126049Sminshall macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; 197226049Sminshall } 197326049Sminshall tmp = macros[macnum].mac_start; 197426049Sminshall while (tmp != macbuf+4096) { 197526049Sminshall if ((c = getchar()) == EOF) { 197626049Sminshall printf("macdef:end of file encountered\n"); 197726049Sminshall code = -1; 197826049Sminshall return; 197926049Sminshall } 198026049Sminshall if ((*tmp = c) == '\n') { 198126049Sminshall if (tmp == macros[macnum].mac_start) { 198226049Sminshall macros[macnum++].mac_end = tmp; 198326049Sminshall code = 0; 198426049Sminshall return; 198526049Sminshall } 198626049Sminshall if (*(tmp-1) == '\0') { 198726049Sminshall macros[macnum++].mac_end = tmp - 1; 198826049Sminshall code = 0; 198926049Sminshall return; 199026049Sminshall } 199126049Sminshall *tmp = '\0'; 199226049Sminshall } 199326049Sminshall tmp++; 199426049Sminshall } 199526049Sminshall while (1) { 199636935Skarels while ((c = getchar()) != '\n' && c != EOF) 199736935Skarels /* LOOP */; 199826049Sminshall if (c == EOF || getchar() == '\n') { 199926049Sminshall printf("Macro not defined - 4k buffer exceeded\n"); 200026049Sminshall code = -1; 200126049Sminshall return; 200226049Sminshall } 200326049Sminshall } 200426049Sminshall } 200536935Skarels 200636935Skarels /* 200736935Skarels * get size of file on remote machine 200836935Skarels */ 200936935Skarels sizecmd(argc, argv) 201036935Skarels char *argv[]; 201136935Skarels { 201236935Skarels 201336935Skarels if (argc < 2) { 201436935Skarels (void) strcat(line, " "); 201536935Skarels printf("(filename) "); 201636935Skarels (void) gets(&line[strlen(line)]); 201736935Skarels makeargv(); 201836935Skarels argc = margc; 201936935Skarels argv = margv; 202036935Skarels } 202136935Skarels if (argc < 2) { 202236935Skarels printf("usage:%s filename\n", argv[0]); 202336935Skarels code = -1; 202436935Skarels return; 202536935Skarels } 202636935Skarels (void) command("SIZE %s", argv[1]); 202736935Skarels } 202836935Skarels 202936935Skarels /* 203036935Skarels * get last modification time of file on remote machine 203136935Skarels */ 203236935Skarels modtime(argc, argv) 203336935Skarels char *argv[]; 203436935Skarels { 203536935Skarels int overbose; 203636935Skarels 203736935Skarels if (argc < 2) { 203836935Skarels (void) strcat(line, " "); 203936935Skarels printf("(filename) "); 204036935Skarels (void) gets(&line[strlen(line)]); 204136935Skarels makeargv(); 204236935Skarels argc = margc; 204336935Skarels argv = margv; 204436935Skarels } 204536935Skarels if (argc < 2) { 204636935Skarels printf("usage:%s filename\n", argv[0]); 204736935Skarels code = -1; 204836935Skarels return; 204936935Skarels } 205036940Skarels overbose = verbose; 205136940Skarels if (debug == 0) 205236940Skarels verbose = -1; 205336935Skarels if (command("MDTM %s", argv[1]) == COMPLETE) { 205436935Skarels int yy, mo, day, hour, min, sec; 205536935Skarels sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, 205636935Skarels &day, &hour, &min, &sec); 205736935Skarels /* might want to print this in local time */ 205836935Skarels printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], 205936935Skarels mo, day, yy, hour, min, sec); 206036935Skarels } else 206136935Skarels fputs(reply_string, stdout); 206236935Skarels verbose = overbose; 206336935Skarels } 206436935Skarels 206536935Skarels /* 2066*36942Skarels * show status on remote machine 206736935Skarels */ 206836935Skarels rmtstatus(argc, argv) 206936935Skarels char *argv[]; 207036935Skarels { 207136935Skarels (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); 207236935Skarels } 2073*36942Skarels #ifdef RESTART 207436935Skarels 207536935Skarels /* 207636935Skarels * get file if modtime is more recent than current file 207736935Skarels */ 207836935Skarels newer(argc, argv) 207936935Skarels char *argv[]; 208036935Skarels { 208136935Skarels if (getit(argc, argv, -1, "w")) 208236935Skarels printf("Local file \"%s\" is newer than remote file \"%s\"\n", 208336935Skarels argv[1], argv[2]); 208436935Skarels } 2085*36942Skarels #endif 2086