diff --git a/reactos/apps/utils/net/ftp/cmds.c b/reactos/apps/utils/net/ftp/cmds.c new file mode 100644 index 00000000000..d155320b2ed --- /dev/null +++ b/reactos/apps/utils/net/ftp/cmds.c @@ -0,0 +1,2376 @@ +/* + * Copyright (c) 1985, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmds.c 5.18 (Berkeley) 4/20/89"; +#endif /* not lint */ + +/* + * FTP User Program -- Command Routines. + */ +//#include +//#include +#include +#if !defined(WIN32) +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "ftp_var.h" +#include "pathnames.h" +#include "prototypes.h" + +extern char *globerr; +extern char **glob(); +extern char home[]; +extern char *remglob(); +extern char *getenv(); +extern int allbinary; +extern off_t restart_point; +extern char reply_string[]; + +char *mname; +jmp_buf jabort; +char *dotrans(), *domap(); + +extern short portnum; +extern char *hostname; +extern int autologin; +/* + * Connect to peer server and + * auto-login, if possible. + */ +void setpeer(int argc, char *argv[]) +{ + char *host, *hookup(); + + if (connected) { + printf("Already connected to %s, use close first.\n", + hostname); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 2) { + (void) strcat(line, " "); + printf("(to) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc > 3) { + printf("usage: %s host-name [port]\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (argc > 2) { + portnum = atoi(argv[2]); + if (portnum <= 0) { + printf("%s: bad port number-- %s\n", argv[1], argv[2]); + printf ("usage: %s host-name [port]\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + portnum = htons(portnum); + } + host = hookup(argv[1], portnum); + if (host) { +#if defined(unix) && NBBY == 8 + int overbose; +#endif + connected = 1; + if (autologin) + (void) login(argv[1]); + +#if defined(unix) && NBBY == 8 +/* + * this ifdef is to keep someone form "porting" this to an incompatible + * system and not checking this out. This way they have to think about it. + */ + overbose = verbose; + if (debug == 0) + verbose = -1; + allbinary = 0; + if (command("SYST") == COMPLETE && overbose) { + register char *cp, c; + cp = index(reply_string+4, ' '); + if (cp == NULL) + cp = index(reply_string+4, '\r'); + if (cp) { + if (cp[-1] == '.') + cp--; + c = *cp; + *cp = '\0'; + } + + printf("Remote system type is %s.\n", + reply_string+4); + if (cp) + *cp = c; + } + if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { + setbinary(); + /* allbinary = 1; this violates the RFC */ + if (overbose) + printf("Using %s mode to transfer files.\n", + typename); + } else if (overbose && + !strncmp(reply_string, "215 TOPS20", 10)) { + printf( +"Remember to set tenex mode when transfering binary files from this machine.\n"); + } + verbose = overbose; +#endif /* unix */ + } + (void) fflush(stdout); +} + +struct types { + char *t_name; + char *t_mode; + int t_type; + char *t_arg; +} types[] = { + { "ascii", "A", TYPE_A, 0 }, + { "binary", "I", TYPE_I, 0 }, + { "image", "I", TYPE_I, 0 }, + { "ebcdic", "E", TYPE_E, 0 }, + { "tenex", "L", TYPE_L, bytename }, + 0 +}; + +/* + * Set transfer type. + */ +void settype(argc, argv) + char *argv[]; +{ + register struct types *p; + int comret; + + if (argc > 2) { + char *sep; + + printf("usage: %s [", argv[0]); + sep = " "; + for (p = types; p->t_name; p++) { + printf("%s%s", sep, p->t_name); + if (*sep == ' ') + sep = " | "; + } + printf(" ]\n"); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 2) { + printf("Using %s mode to transfer files.\n", typename); + (void) fflush(stdout); + code = 0; + return; + } + for (p = types; p->t_name; p++) + if (strcmp(argv[1], p->t_name) == 0) + break; + if (p->t_name == 0) { + printf("%s: unknown mode\n", argv[1]); + (void) fflush(stdout); + code = -1; + return; + } + if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) + comret = command ("TYPE %s %s", p->t_mode, p->t_arg); + else + comret = command("TYPE %s", p->t_mode); + if (comret == COMPLETE) { + (void) strcpy(typename, p->t_name); + type = p->t_type; + } +} + +char *stype[] = { + "type", + "", + 0 +}; + +/* + * Set binary transfer type. + */ +/*VARARGS*/ +void setbinary() +{ + stype[1] = "binary"; + settype(2, stype); +} + +/* + * Set ascii transfer type. + */ +/*VARARGS*/ +void setascii() +{ + stype[1] = "ascii"; + settype(2, stype); +} + +/* + * Set tenex transfer type. + */ +/*VARARGS*/ +void settenex() +{ + stype[1] = "tenex"; + settype(2, stype); +} + +/* + * Set ebcdic transfer type. + */ +/*VARARGS*/ +void setebcdic() +{ + stype[1] = "ebcdic"; + settype(2, stype); +} + +/* + * Set file transfer mode. + */ +#if 0 +/*ARGSUSED*/ +void setmode(argc, argv) + char *argv[]; +{ + + printf("We only support %s mode, sorry.\n", modename); + (void) fflush(stdout); + code = -1; +} +#endif + +/* + * Set file transfer format. + */ +/*ARGSUSED*/ +void setform(argc, argv) + char *argv[]; +{ + + printf("We only support %s format, sorry.\n", formname); + (void) fflush(stdout); + code = -1; +} + +/* + * Set file transfer structure. + */ +/*ARGSUSED*/ +void setstruct(argc, argv) + char *argv[]; +{ + + printf("We only support %s structure, sorry.\n", structname); + (void) fflush(stdout); + code = -1; +} + +/* + * Send a single file. + */ +void put(argc, argv) + int argc; + char *argv[]; +{ + char *cmd; + int loc = 0; + char *oldargv1, *oldargv2; + + if (argc == 2) { + argc++; + argv[2] = argv[1]; + loc++; + } + if (argc < 2) { + (void) strcat(line, " "); + printf("(local-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { +usage: + printf("usage:%s local-file remote-file\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(remote-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) + goto usage; + oldargv1 = argv[1]; + oldargv2 = argv[2]; + if (!globulize(&argv[1])) { + code = -1; + return; + } + /* + * If "globulize" modifies argv[1], and argv[2] is a copy of + * the old argv[1], make it a copy of the new argv[1]. + */ + if (argv[1] != oldargv1 && argv[2] == oldargv1) { + argv[2] = argv[1]; + } + cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR"); + if (loc && ntflag) { + argv[2] = dotrans(argv[2]); + } + if (loc && mapflag) { + argv[2] = domap(argv[2]); + } + sendrequest(cmd, argv[1], argv[2], + argv[1] != oldargv1 || argv[2] != oldargv2); +} + +/* + * Send multiple files. + */ +void mput(argc, argv) + char *argv[]; +{ + register int i; + int ointer; + void mabort(); + extern jmp_buf jabort; + char *tp; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(local-files) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s local-files\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + mname = argv[0]; + mflag = 1; +// oldintr = signal(SIGINT, mabort); + (void) setjmp(jabort); + if (proxy) { + char *cp, *tp2, tmpbuf[MAXPATHLEN]; + + while ((cp = remglob(argv,0)) != NULL) { + if (*cp == 0) { + mflag = 0; + continue; + } + if (mflag && confirm(argv[0], cp)) { + tp = cp; + if (mcase) { + while (*tp && !islower(*tp)) { + tp++; + } + if (!*tp) { + tp = cp; + tp2 = tmpbuf; + while ((*tp2 = *tp) != (int) NULL) { + if (isupper(*tp2)) { + *tp2 = 'a' + *tp2 - 'A'; + } + tp++; + tp2++; + } + } + tp = tmpbuf; + } + if (ntflag) { + tp = dotrans(tp); + } + if (mapflag) { + tp = domap(tp); + } + sendrequest((sunique) ? "STOU" : "STOR", + cp, tp, cp != tp || !interactive); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with","mput")) { + mflag++; + } + interactive = ointer; + } + } + } +// (void) signal(SIGINT, oldintr); + mflag = 0; + return; + } + for (i = 1; i < argc; i++) { + register char **cpp, **gargs; + + if (!doglob) { + if (mflag && confirm(argv[0], argv[i])) { + tp = (ntflag) ? dotrans(argv[i]) : argv[i]; + tp = (mapflag) ? domap(tp) : tp; + sendrequest((sunique) ? "STOU" : "STOR", + argv[i], tp, tp != argv[i] || !interactive); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with","mput")) { + mflag++; + } + interactive = ointer; + } + } + continue; + } + gargs = glob(argv[i]); + if (globerr != NULL) { + printf("%s\n", globerr); + (void) fflush(stdout); + if (gargs) { + blkfree(gargs); + free((char *)gargs); + } + continue; + } + for (cpp = gargs; cpp && *cpp != NULL; cpp++) { + if (mflag && confirm(argv[0], *cpp)) { + tp = (ntflag) ? dotrans(*cpp) : *cpp; + tp = (mapflag) ? domap(tp) : tp; + sendrequest((sunique) ? "STOU" : "STOR", + *cpp, tp, *cpp != tp || !interactive); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with","mput")) { + mflag++; + } + interactive = ointer; + } + } + } + if (gargs != NULL) { + blkfree(gargs); + free((char *)gargs); + } + } +// (void) signal(SIGINT, oldintr); + mflag = 0; +} + +void reget(argc, argv) + char *argv[]; +{ + (void) getit(argc, argv, 1, "r+w"); +} + +void get(argc, argv) + char *argv[]; +{ + (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" ); +} + +/* + * Receive one file. + */ +int getit(argc, argv, restartit, mode) + char *argv[]; + char *mode; +{ + int loc = 0; + char *oldargv1, *oldargv2; + + if (argc == 2) { + argc++; + argv[2] = argv[1]; + loc++; + } + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { +usage: + printf("usage: %s remote-file [ local-file ]\n", argv[0]); + (void) fflush(stdout); + code = -1; + return (0); + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(local-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) + goto usage; + oldargv1 = argv[1]; + oldargv2 = argv[2]; + if (!globulize(&argv[2])) { + code = -1; + return (0); + } + if (loc && mcase) { + char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN]; + + while (*tp && !islower(*tp)) { + tp++; + } + if (!*tp) { + tp = argv[2]; + tp2 = tmpbuf; + while ((*tp2 = *tp) != (int) NULL) { + if (isupper(*tp2)) { + *tp2 = 'a' + *tp2 - 'A'; + } + tp++; + tp2++; + } + argv[2] = tmpbuf; + } + } + if (loc && ntflag) + argv[2] = dotrans(argv[2]); + if (loc && mapflag) + argv[2] = domap(argv[2]); + if (restartit) { + struct stat stbuf; + int ret; + + ret = stat(argv[2], &stbuf); + if (restartit == 1) { + if (ret < 0) { + perror(argv[2]); + return (0); + } + restart_point = stbuf.st_size; + } else { + if (ret == 0) { + int overbose; + + overbose = verbose; + if (debug == 0) + verbose = -1; + if (command("MDTM %s", argv[1]) == COMPLETE) { + int yy, mo, day, hour, min, sec; + struct tm *tm; + verbose = overbose; + sscanf(reply_string, + "%*s %04d%02d%02d%02d%02d%02d", + &yy, &mo, &day, &hour, &min, &sec); + tm = gmtime(&stbuf.st_mtime); + tm->tm_mon++; + if (tm->tm_year > yy%100) + return (1); + else if (tm->tm_year == yy%100) { + if (tm->tm_mon > mo) + return (1); + } else if (tm->tm_mon == mo) { + if (tm->tm_mday > day) + return (1); + } else if (tm->tm_mday == day) { + if (tm->tm_hour > hour) + return (1); + } else if (tm->tm_hour == hour) { + if (tm->tm_min > min) + return (1); + } else if (tm->tm_min == min) { + if (tm->tm_sec > sec) + return (1); + } + } else { + printf("%s\n", reply_string); + (void) fflush(stdout); + verbose = overbose; + return (0); + } + } + } + } + + recvrequest("RETR", argv[2], argv[1], mode, + argv[1] != oldargv1 || argv[2] != oldargv2); + restart_point = 0; + return (0); +} + +void +mabort() +{ + int ointer; + extern jmp_buf jabort; + + printf("\n"); + (void) fflush(stdout); + if (mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with", mname)) { + interactive = ointer; + longjmp(jabort,0); + } + interactive = ointer; + } + mflag = 0; + longjmp(jabort,0); +} + +/* + * Get multiple files. + */ +void mget(argc, argv) + char *argv[]; +{ + char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN]; + int ointer; + void mabort(); + extern jmp_buf jabort; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-files) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s remote-files\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + mname = argv[0]; + mflag = 1; +// oldintr = signal(SIGINT,mabort); + (void) setjmp(jabort); + while ((cp = remglob(argv,proxy)) != NULL) { + if (*cp == '\0') { + mflag = 0; + continue; + } + if (mflag && confirm(argv[0], cp)) { + tp = cp; + if (mcase) { + while (*tp && !islower(*tp)) { + tp++; + } + if (!*tp) { + tp = cp; + tp2 = tmpbuf; + while ((*tp2 = *tp) != (int) NULL) { + if (isupper(*tp2)) { + *tp2 = 'a' + *tp2 - 'A'; + } + tp++; + tp2++; + } + } + tp = tmpbuf; + } + if (ntflag) { + tp = dotrans(tp); + } + if (mapflag) { + tp = domap(tp); + } + recvrequest("RETR", tp, cp, "w", + tp != cp || !interactive); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with","mget")) { + mflag++; + } + interactive = ointer; + } + } + } +// (void) signal(SIGINT,oldintr); + mflag = 0; +} + +char * +remglob(argv,doswitch) + char *argv[]; + int doswitch; +{ + char temp[16]; + static char buf[MAXPATHLEN]; + static FILE *ftemp = NULL; + static char **args; + int oldverbose, oldhash; + char *cp, *mode; + + if (!mflag) { + if (!doglob) { + args = NULL; + } + else { + if (ftemp) { + (void) fclose(ftemp); + ftemp = NULL; + } + } + return(NULL); + } + if (!doglob) { + if (args == NULL) + args = argv; + if ((cp = *++args) == NULL) + args = NULL; + return (cp); + } + if (ftemp == NULL) { + (void) strcpy(temp, _PATH_TMP); + (void) mktemp(temp); + oldverbose = verbose, verbose = 0; + oldhash = hash, hash = 0; + if (doswitch) { + pswitch(!proxy); + } + for (mode = "w"; *++argv != NULL; mode = "a") + recvrequest ("NLST", temp, *argv, mode, 0); + if (doswitch) { + pswitch(!proxy); + } + verbose = oldverbose; hash = oldhash; + ftemp = fopen(temp, "r"); + (void) unlink(temp); + if (ftemp == NULL) { + printf("can't find list of remote files, oops\n"); + (void) fflush(stdout); + return (NULL); + } + } + if (fgets(buf, sizeof (buf), ftemp) == NULL) { + (void) fclose(ftemp), ftemp = NULL; + return (NULL); + } + if ((cp = index(buf, '\n')) != NULL) + *cp = '\0'; + return (buf); +} + +char * +onoff(bool) + int bool; +{ + + return (bool ? "on" : "off"); +} + +/* + * Show status. + */ +/*ARGSUSED*/ +void status(argc, argv) + char *argv[]; +{ + int i; + + if (connected) + printf("Connected to %s.\n", hostname); + else + printf("Not connected.\n"); + if (!proxy) { + pswitch(1); + if (connected) { + printf("Connected for proxy commands to %s.\n", hostname); + } + else { + printf("No proxy connection.\n"); + } + pswitch(0); + } + printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n", + modename, typename, formname, structname); + printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", + onoff(verbose), onoff(bell), onoff(interactive), + onoff(doglob)); + printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), + onoff(runique)); + printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); + if (ntflag) { + printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); + } + else { + printf("Ntrans: off\n"); + } + if (mapflag) { + printf("Nmap: (in) %s (out) %s\n", mapin, mapout); + } + else { + printf("Nmap: off\n"); + } + printf("Hash mark printing: %s; Use of PORT cmds: %s\n", + onoff(hash), onoff(sendport)); + if (macnum > 0) { + printf("Macros:\n"); + for (i=0; i 1) { + val = atoi(argv[1]); + if (val < 0) { + printf("%s: bad debugging value.\n", argv[1]); + (void) fflush(stdout); + code = -1; + return; + } + } else + val = !debug; + debug = val; + if (debug) + options |= SO_DEBUG; + else + options &= ~SO_DEBUG; + printf("Debugging %s (debug=%d).\n", onoff(debug), debug); + (void) fflush(stdout); + code = debug > 0; +} + +/* + * Set current working directory + * on remote machine. + */ +void cd(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-directory) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s remote-directory\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (command("CWD %s", argv[1]) == ERROR && code == 500) { + if (verbose) { + printf("CWD command not recognized, trying XCWD\n"); + (void) fflush(stdout); + } + (void) command("XCWD %s", argv[1]); + } +} + +/* + * Set current working directory + * on local machine. + */ +void lcd(argc, argv) + char *argv[]; +{ + char buf[MAXPATHLEN]; + + if (argc < 2) + argc++, argv[1] = home; + if (argc != 2) { + printf("usage:%s local-directory\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (!globulize(&argv[1])) { + code = -1; + return; + } + if (chdir(argv[1]) < 0) { + perror(argv[1]); + code = -1; + return; + } + printf("Local directory now %s\n", getcwd(buf,sizeof(buf))); + (void) fflush(stdout); + code = 0; +} + +/* + * Delete a single file. + */ +void delete(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s remote-file\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + (void) command("DELE %s", argv[1]); +} + +/* + * Delete multiple files. + */ +void mdelete(argc, argv) + char *argv[]; +{ + char *cp; + int ointer; + void mabort(); + extern jmp_buf jabort; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-files) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s remote-files\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + mname = argv[0]; + mflag = 1; +// oldintr = signal(SIGINT, mabort); + (void) setjmp(jabort); + while ((cp = remglob(argv,0)) != NULL) { + if (*cp == '\0') { + mflag = 0; + continue; + } + if (mflag && confirm(argv[0], cp)) { + (void) command("DELE %s", cp); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with", "mdelete")) { + mflag++; + } + interactive = ointer; + } + } + } +// (void) signal(SIGINT, oldintr); + mflag = 0; +} + +/* + * Rename a remote file. + */ +void renamefile(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(from-name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { +usage: + printf("%s from-name to-name\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(to-name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) + goto usage; + if (command("RNFR %s", argv[1]) == CONTINUE) + (void) command("RNTO %s", argv[2]); +} + +/* + * Get a directory listing + * of remote files. + */ +void ls(argc, argv) + char *argv[]; +{ + char *cmd; + + if (argc < 2) + argc++, argv[1] = NULL; + if (argc < 3) + argc++, argv[2] = "-"; + if (argc > 3) { + printf("usage: %s remote-directory local-file\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; +// cmd = argv[0][0] == 'n' ? "NLST -CF" : "NLST -CF"; + if (strcmp(argv[2], "-") && !globulize(&argv[2])) { + code = -1; + return; + } + if (strcmp(argv[2], "-") && *argv[2] != '|') + if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) { + code = -1; + return; + } + recvrequest(cmd, argv[2], argv[1], "w", 0); +} + +/* + * Get a directory listing + * of multiple remote files. + */ +void mls(argc, argv) + char *argv[]; +{ + char *cmd, mode[1], *dest; + int ointer, i; + void mabort(); + extern jmp_buf jabort; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(remote-files) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(local-file) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) { + printf("usage:%s remote-files local-file\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + dest = argv[argc - 1]; + argv[argc - 1] = NULL; + if (strcmp(dest, "-") && *dest != '|') + if (!globulize(&dest) || !confirm("output to local-file:", dest)) { + code = -1; + return; + } + cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; + mname = argv[0]; + mflag = 1; +// oldintr = signal(SIGINT, mabort); + (void) setjmp(jabort); + for (i = 1; mflag && i < argc-1; ++i) { + *mode = (i == 1) ? 'w' : 'a'; + recvrequest(cmd, dest, argv[i], mode, 0); + if (!mflag && fromatty) { + ointer = interactive; + interactive = 1; + if (confirm("Continue with", argv[0])) { + mflag ++; + } + interactive = ointer; + } + } +// (void) signal(SIGINT, oldintr); + mflag = 0; +} + +/* + * Do a shell escape + */ +/*ARGSUSED*/ +shell(argc, argv) + char *argv[]; +{ +#if 0 + int pid; + sig_t (*old1)(), (*old2)(); + char shellnam[40], *shell, *namep; + union wait status; + + old1 = signal (SIGINT, SIG_IGN); + old2 = signal (SIGQUIT, SIG_IGN); + if ((pid = fork()) == 0) { + for (pid = 3; pid < 20; pid++) + (void) close(pid); + (void) signal(SIGINT, SIG_DFL); + (void) signal(SIGQUIT, SIG_DFL); + shell = getenv("SHELL"); + if (shell == NULL) + shell = _PATH_BSHELL; + namep = rindex(shell,'/'); + if (namep == NULL) + namep = shell; + (void) strcpy(shellnam,"-"); + (void) strcat(shellnam, ++namep); + if (strcmp(namep, "sh") != 0) + shellnam[0] = '+'; + if (debug) { + printf ("%s\n", shell); + (void) fflush (stdout); + } + if (argc > 1) { + execl(shell,shellnam,"-c",altarg,(char *)0); + } + else { + execl(shell,shellnam,(char *)0); + } + perror(shell); + code = -1; + exit(1); + } + if (pid > 0) + while (wait(&status) != pid) + ; + (void) signal(SIGINT, old1); + (void) signal(SIGQUIT, old2); + if (pid == -1) { + perror("Try again later"); + code = -1; + } + else { + code = 0; + } +#endif + + char * AppName; + char ShellCmd[MAX_PATH]; + char CmdLine[MAX_PATH]; + int i; + PROCESS_INFORMATION ProcessInformation; + BOOL Result; + STARTUPINFO StartupInfo; + char ShellName[] = "COMSPEC"; + int NumBytes; + + NumBytes = GetEnvironmentVariable( ShellName, ShellCmd, MAX_PATH); + + if (NumBytes == 0) + { + return(-1); + } + + AppName = ShellCmd; + strcpy( CmdLine, ShellCmd ); + + if (argc > 1) + { + strncat(CmdLine, " /C", MAX_PATH); + } + + for (i=1; i 4) { + printf("usage: %s username [password] [account]\n", argv[0]); + (void) fflush(stdout); + code = -1; + return (0); + } + n = command("USER %s", argv[1]); + if (n == CONTINUE) { + if (argc < 3 ) + argv[2] = getpass("Password: "), argc++; + n = command("PASS %s", argv[2]); + } + if (n == CONTINUE) { + if (argc < 4) { + printf("Account: "); (void) fflush(stdout); + (void) fflush(stdout); + (void) fgets(acct, sizeof(acct) - 1, stdin); + acct[strlen(acct) - 1] = '\0'; + argv[3] = acct; argc++; + } + n = command("ACCT %s", argv[3]); + aflag++; + } + if (n != COMPLETE) { + fprintf(stdout, "Login failed.\n"); + (void) fflush(stdout); + return (0); + } + if (!aflag && argc == 4) { + (void) command("ACCT %s", argv[3]); + } + return (1); +} + +/* + * Print working directory. + */ +/*VARARGS*/ +void pwd() +{ + int oldverbose = verbose; + + /* + * If we aren't verbose, this doesn't do anything! + */ + verbose = 1; + if (command("PWD") == ERROR && code == 500) { + printf("PWD command not recognized, trying XPWD\n"); + (void) fflush(stdout); + (void) command("XPWD"); + } + verbose = oldverbose; +} + +/* + * Make a directory. + */ +void makedir(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(directory-name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage: %s directory-name\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (command("MKD %s", argv[1]) == ERROR && code == 500) { + if (verbose) { + printf("MKD command not recognized, trying XMKD\n"); + (void) fflush(stdout); + } + (void) command("XMKD %s", argv[1]); + } +} + +/* + * Remove a directory. + */ +void removedir(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(directory-name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage: %s directory-name\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (command("RMD %s", argv[1]) == ERROR && code == 500) { + if (verbose) { + printf("RMD command not recognized, trying XRMD\n"); + (void) fflush(stdout); + } + (void) command("XRMD %s", argv[1]); + } +} + +/* + * Send a line, verbatim, to the remote machine. + */ +void quote(argc, argv) + char *argv[]; +{ + int i; + char buf[BUFSIZ]; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(command line to send) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage: %s line-to-send\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + (void) strcpy(buf, argv[1]); + for (i = 2; i < argc; i++) { + (void) strcat(buf, " "); + (void) strcat(buf, argv[i]); + } + if (command(buf) == PRELIM) { + while (getreply(0) == PRELIM); + } +} + +/* + * Send a SITE command to the remote machine. The line + * is sent almost verbatim to the remote machine, the + * first argument is changed to SITE. + */ + +void site(argc, argv) + char *argv[]; +{ + int i; + char buf[BUFSIZ]; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(arguments to SITE command) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage: %s line-to-send\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + (void) strcpy(buf, "SITE "); + (void) strcat(buf, argv[1]); + for (i = 2; i < argc; i++) { + (void) strcat(buf, " "); + (void) strcat(buf, argv[i]); + } + if (command(buf) == PRELIM) { + while (getreply(0) == PRELIM); + } +} + +void do_chmod(argc, argv) + char *argv[]; +{ + if (argc == 2) { + printf("usage: %s mode file-name\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(mode and file-name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc != 3) { + printf("usage: %s mode file-name\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + (void)command("SITE CHMOD %s %s", argv[1], argv[2]); +} + +void do_umask(argc, argv) + char *argv[]; +{ + int oldverbose = verbose; + + verbose = 1; + (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]); + verbose = oldverbose; +} + +void idle(argc, argv) + char *argv[]; +{ + int oldverbose = verbose; + + verbose = 1; + (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]); + verbose = oldverbose; +} + +/* + * Ask the other side for help. + */ +void rmthelp(argc, argv) + char *argv[]; +{ + int oldverbose = verbose; + + verbose = 1; + (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]); + verbose = oldverbose; +} + +/* + * Terminate session and exit. + */ +/*VARARGS*/ +void quit() +{ + + if (connected) + disconnect(); + pswitch(1); + if (connected) { + disconnect(); + } + exit(0); +} + +/* + * Terminate session, but don't exit. + */ +void disconnect() +{ + extern int cout; + extern int data; + + if (!connected) + return; + (void) command("QUIT"); + cout = (int) NULL; + connected = 0; + data = -1; + if (!proxy) { + macnum = 0; + } +} + +confirm(cmd, file) + char *cmd, *file; +{ + char line[BUFSIZ]; + + if (!interactive) + return (1); + printf("%s %s? ", cmd, file); + (void) fflush(stdout); + (void) gets(line); + return (*line != 'n' && *line != 'N'); +} + +void fatal(msg) + char *msg; +{ + + fprintf(stderr, "ftp: %s\n", msg); + exit(1); +} + +/* + * Glob a local file name specification with + * the expectation of a single return value. + * Can't control multiple values being expanded + * from the expression, we return only the first. + */ +globulize(cpp) + char **cpp; +{ + char **globbed; + + if (!doglob) + return (1); + globbed = glob(*cpp); + if (globerr != NULL) { + printf("%s: %s\n", *cpp, globerr); + (void) fflush(stdout); + if (globbed) { + blkfree(globbed); + free((char *)globbed); + } + return (0); + } + if (globbed) { + *cpp = *globbed++; + /* don't waste too much memory */ + if (*globbed) { + blkfree(globbed); + free((char *)globbed); + } + } + return (1); +} + +void account(argc,argv) + int argc; + char **argv; +{ + char acct[50], *getpass(), *ap; + + if (argc > 1) { + ++argv; + --argc; + (void) strncpy(acct,*argv,49); + acct[49] = '\0'; + while (argc > 1) { + --argc; + ++argv; + (void) strncat(acct,*argv, 49-strlen(acct)); + } + ap = acct; + } + else { + ap = getpass("Account:"); + } + (void) command("ACCT %s", ap); +} + +jmp_buf abortprox; + +void +proxabort() +{ + extern int proxy; + + if (!proxy) { + pswitch(1); + } + if (connected) { + proxflag = 1; + } + else { + proxflag = 0; + } + pswitch(0); + longjmp(abortprox,1); +} + +void doproxy(argc,argv) + int argc; + char *argv[]; +{ + void proxabort(); + register struct cmd *c; + struct cmd *getcmd(); + extern struct cmd cmdtab[]; + extern jmp_buf abortprox; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(command) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s command\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + c = getcmd(argv[1]); + if (c == (struct cmd *) -1) { + printf("?Ambiguous command\n"); + (void) fflush(stdout); + code = -1; + return; + } + if (c == 0) { + printf("?Invalid command\n"); + (void) fflush(stdout); + code = -1; + return; + } + if (!c->c_proxy) { + printf("?Invalid proxy command\n"); + (void) fflush(stdout); + code = -1; + return; + } + if (setjmp(abortprox)) { + code = -1; + return; + } +// oldintr = signal(SIGINT, proxabort); + pswitch(1); + if (c->c_conn && !connected) { + printf("Not connected\n"); + (void) fflush(stdout); + pswitch(0); +// (void) signal(SIGINT, oldintr); + code = -1; + return; + } + (*c->c_handler)(argc-1, argv+1); + if (connected) { + proxflag = 1; + } + else { + proxflag = 0; + } + pswitch(0); +// (void) signal(SIGINT, oldintr); +} + +void setcase() +{ + mcase = !mcase; + printf("Case mapping %s.\n", onoff(mcase)); + (void) fflush(stdout); + code = mcase; +} + +void setcr() +{ + crflag = !crflag; + printf("Carriage Return stripping %s.\n", onoff(crflag)); + (void) fflush(stdout); + code = crflag; +} + +void setntrans(argc,argv) + int argc; + char *argv[]; +{ + if (argc == 1) { + ntflag = 0; + printf("Ntrans off.\n"); + (void) fflush(stdout); + code = ntflag; + return; + } + ntflag++; + code = ntflag; + (void) strncpy(ntin, argv[1], 16); + ntin[16] = '\0'; + if (argc == 2) { + ntout[0] = '\0'; + return; + } + (void) strncpy(ntout, argv[2], 16); + ntout[16] = '\0'; +} + +char * +dotrans(name) + char *name; +{ + static char new[MAXPATHLEN]; + char *cp1, *cp2 = new; + register int i, ostop, found; + + for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++); + for (cp1 = name; *cp1; cp1++) { + found = 0; + for (i = 0; *(ntin + i) && i < 16; i++) { + if (*cp1 == *(ntin + i)) { + found++; + if (i < ostop) { + *cp2++ = *(ntout + i); + } + break; + } + } + if (!found) { + *cp2++ = *cp1; + } + } + *cp2 = '\0'; + return(new); +} + + +void +setpassive(argc, argv) + int argc; + char *argv[]; +{ + passivemode = !passivemode; + printf("Passive mode %s.\n", onoff(passivemode)); + (void) fflush(stdout); + code = passivemode; +} + +void setnmap(argc, argv) + int argc; + char *argv[]; +{ + char *cp; + + if (argc == 1) { + mapflag = 0; + printf("Nmap off.\n"); + (void) fflush(stdout); + code = mapflag; + return; + } + if (argc < 3) { + (void) strcat(line, " "); + printf("(mapout) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 3) { + printf("Usage: %s [mapin mapout]\n",argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + mapflag = 1; + code = 1; + cp = index(altarg, ' '); + if (proxy) { + while(*++cp == ' '); + altarg = cp; + cp = index(altarg, ' '); + } + *cp = '\0'; + (void) strncpy(mapin, altarg, MAXPATHLEN - 1); + while (*++cp == ' '); + (void) strncpy(mapout, cp, MAXPATHLEN - 1); +} + +char * +domap(name) + char *name; +{ + static char new[MAXPATHLEN]; + register char *cp1 = name, *cp2 = mapin; + char *tp[9], *te[9]; + int i, toks[9], toknum = 0, match = 1; + + for (i=0; i < 9; ++i) { + toks[i] = 0; + } + while (match && *cp1 && *cp2) { + switch (*cp2) { + case '\\': + if (*++cp2 != *cp1) { + match = 0; + } + break; + case '$': + if (*(cp2+1) >= '1' && (*cp2+1) <= '9') { + if (*cp1 != *(++cp2+1)) { + toks[toknum = *cp2 - '1']++; + tp[toknum] = cp1; + while (*++cp1 && *(cp2+1) + != *cp1); + te[toknum] = cp1; + } + cp2++; + break; + } + /* FALLTHROUGH */ + default: + if (*cp2 != *cp1) { + match = 0; + } + break; + } + if (match && *cp1) { + cp1++; + } + if (match && *cp2) { + cp2++; + } + } + if (!match && *cp1) /* last token mismatch */ + { + toks[toknum] = 0; + } + cp1 = new; + *cp1 = '\0'; + cp2 = mapout; + while (*cp2) { + match = 0; + switch (*cp2) { + case '\\': + if (*(cp2 + 1)) { + *cp1++ = *++cp2; + } + break; + case '[': +LOOP: + if (*++cp2 == '$' && isdigit(*(cp2+1))) { + if (*++cp2 == '0') { + char *cp3 = name; + + while (*cp3) { + *cp1++ = *cp3++; + } + match = 1; + } + else if (toks[toknum = *cp2 - '1']) { + char *cp3 = tp[toknum]; + + while (cp3 != te[toknum]) { + *cp1++ = *cp3++; + } + match = 1; + } + } + else { + while (*cp2 && *cp2 != ',' && + *cp2 != ']') { + if (*cp2 == '\\') { + cp2++; + } + else if (*cp2 == '$' && + isdigit(*(cp2+1))) { + if (*++cp2 == '0') { + char *cp3 = name; + + while (*cp3) { + *cp1++ = *cp3++; + } + } + else if (toks[toknum = + *cp2 - '1']) { + char *cp3=tp[toknum]; + + while (cp3 != + te[toknum]) { + *cp1++ = *cp3++; + } + } + } + else if (*cp2) { + *cp1++ = *cp2++; + } + } + if (!*cp2) { + printf("nmap: unbalanced brackets\n"); + (void) fflush(stdout); + return(name); + } + match = 1; + cp2--; + } + if (match) { + while (*++cp2 && *cp2 != ']') { + if (*cp2 == '\\' && *(cp2 + 1)) { + cp2++; + } + } + if (!*cp2) { + printf("nmap: unbalanced brackets\n"); + (void) fflush(stdout); + return(name); + } + break; + } + switch (*++cp2) { + case ',': + goto LOOP; + case ']': + break; + default: + cp2--; + goto LOOP; + } + break; + case '$': + if (isdigit(*(cp2 + 1))) { + if (*++cp2 == '0') { + char *cp3 = name; + + while (*cp3) { + *cp1++ = *cp3++; + } + } + else if (toks[toknum = *cp2 - '1']) { + char *cp3 = tp[toknum]; + + while (cp3 != te[toknum]) { + *cp1++ = *cp3++; + } + } + break; + } + /* intentional drop through */ + default: + *cp1++ = *cp2; + break; + } + cp2++; + } + *cp1 = '\0'; + if (!*new) { + return(name); + } + return(new); +} + +void setsunique() +{ + sunique = !sunique; + printf("Store unique %s.\n", onoff(sunique)); + (void) fflush(stdout); + code = sunique; +} + +void setrunique() +{ + runique = !runique; + printf("Receive unique %s.\n", onoff(runique)); + (void) fflush(stdout); + code = runique; +} + +/* change directory to perent directory */ +void cdup() +{ + if (command("CDUP") == ERROR && code == 500) { + if (verbose) { + printf("CDUP command not recognized, trying XCUP\n"); + (void) fflush(stdout); + } + (void) command("XCUP"); + } +} + +/* restart transfer at specific point */ +void restart(argc, argv) + int argc; + char *argv[]; +{ + extern long atol(); + if (argc != 2) + printf("restart: offset not specified\n"); + else { + restart_point = atol(argv[1]); + printf("restarting at %ld. %s\n", restart_point, + "execute get, put or append to initiate transfer"); + } + (void) fflush(stdout); +} + +/* show remote system type */ +void syst() +{ + (void) command("SYST"); +} + +void macdef(argc, argv) + int argc; + char *argv[]; +{ + char *tmp; + int c; + + if (macnum == 16) { + printf("Limit of 16 macros have already been defined\n"); + (void) fflush(stdout); + code = -1; + return; + } + if (argc < 2) { + (void) strcat(line, " "); + printf("(macro name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc != 2) { + printf("Usage: %s macro_name\n",argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + if (interactive) { + printf("Enter macro line by line, terminating it with a null line\n"); + (void) fflush(stdout); + } + (void) strncpy(macros[macnum].mac_name, argv[1], 8); + if (macnum == 0) { + macros[macnum].mac_start = macbuf; + } + else { + macros[macnum].mac_start = macros[macnum - 1].mac_end + 1; + } + tmp = macros[macnum].mac_start; + while (tmp != macbuf+4096) { + if ((c = getchar()) == EOF) { + printf("macdef:end of file encountered\n"); + (void) fflush(stdout); + code = -1; + return; + } + if ((*tmp = c) == '\n') { + if (tmp == macros[macnum].mac_start) { + macros[macnum++].mac_end = tmp; + code = 0; + return; + } + if (*(tmp-1) == '\0') { + macros[macnum++].mac_end = tmp - 1; + code = 0; + return; + } + *tmp = '\0'; + } + tmp++; + } + while (1) { + while ((c = getchar()) != '\n' && c != EOF) + /* LOOP */; + if (c == EOF || getchar() == '\n') { + printf("Macro not defined - 4k buffer exceeded\n"); + (void) fflush(stdout); + code = -1; + return; + } + } +} + +/* + * get size of file on remote machine + */ +void sizecmd(argc, argv) + char *argv[]; +{ + + if (argc < 2) { + (void) strcat(line, " "); + printf("(filename) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s filename\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + (void) command("SIZE %s", argv[1]); +} + +/* + * get last modification time of file on remote machine + */ +void modtime(argc, argv) + char *argv[]; +{ + int overbose; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(filename) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("usage:%s filename\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + overbose = verbose; + if (debug == 0) + verbose = -1; + if (command("MDTM %s", argv[1]) == COMPLETE) { + int yy, mo, day, hour, min, sec; + sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo, + &day, &hour, &min, &sec); + /* might want to print this in local time */ + printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1], + mo, day, yy, hour, min, sec); + } else + printf("%s\n", reply_string); + verbose = overbose; + (void) fflush(stdout); +} + +/* + * show status on reomte machine + */ +void rmtstatus(argc, argv) + char *argv[]; +{ + (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]); +} + +/* + * get file if modtime is more recent than current file + */ +void newer(argc, argv) + char *argv[]; +{ + if (getit(argc, argv, -1, "w")) { + printf("Local file \"%s\" is newer than remote file \"%s\"\n", + argv[1], argv[2]); + (void) fflush(stdout); + } +} diff --git a/reactos/apps/utils/net/ftp/cmdtab.c b/reactos/apps/utils/net/ftp/cmdtab.c new file mode 100644 index 00000000000..5dd04ff340f --- /dev/null +++ b/reactos/apps/utils/net/ftp/cmdtab.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 1985, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)cmdtab.c 5.9 (Berkeley) 3/21/89"; +#endif /* not lint */ + +#include "ftp_var.h" + +/* + * User FTP -- Command Tables. + */ +int setascii(), setbell(), setbinary(), setdebug(), setform(); +int setglob(), sethash(), setmode(), setpeer(), setpassive(), setport(); +int setprompt(), setstruct(); +int settenex(), settrace(), settype(), setverbose(); +int disconnect(), restart(), reget(), syst(); +int cd(), lcd(), delete(), mdelete(), user(); +int ls(), mls(), get(), mget(), help(), append(), put(), mput(); +int quit(), renamefile(), status(); +int quote(), rmthelp(), shell(), site(); +int pwd(), makedir(), removedir(), setcr(); +int account(), doproxy(), reset(), setcase(), setntrans(), setnmap(); +int setsunique(), setrunique(), cdup(), macdef(), domacro(); +int sizecmd(), modtime(), newer(), rmtstatus(); +int do_chmod(), do_umask(), idle(); + +char accounthelp[] = "send account command to remote server"; +char appendhelp[] = "append to a file"; +char asciihelp[] = "set ascii transfer type"; +char beephelp[] = "beep when command completed"; +char binaryhelp[] = "set binary transfer type"; +char casehelp[] = "toggle mget upper/lower case id mapping"; +char cdhelp[] = "change remote working directory"; +char cduphelp[] = "change remote working directory to parent directory"; +char chmodhelp[] = "change file permissions of remote file"; +char connecthelp[] = "connect to remote tftp"; +char crhelp[] = "toggle carriage return stripping on ascii gets"; +char deletehelp[] = "delete remote file"; +char debughelp[] = "toggle/set debugging mode"; +char dirhelp[] = "list contents of remote directory"; +char disconhelp[] = "terminate ftp session"; +char domachelp[] = "execute macro"; +char formhelp[] = "set file transfer format"; +char globhelp[] = "toggle metacharacter expansion of local file names"; +char hashhelp[] = "toggle printing `#' for each buffer transferred"; +char helphelp[] = "print local help information"; +char idlehelp[] = "get (set) idle timer on remote side"; +char lcdhelp[] = "change local working directory"; +char lshelp[] = "list contents of remote directory"; +char macdefhelp[] = "define a macro"; +char mdeletehelp[] = "delete multiple files"; +char mdirhelp[] = "list contents of multiple remote directories"; +char mgethelp[] = "get multiple files"; +char mkdirhelp[] = "make directory on the remote machine"; +char mlshelp[] = "list contents of multiple remote directories"; +char modtimehelp[] = "show last modification time of remote file"; +char modehelp[] = "set file transfer mode"; +char mputhelp[] = "send multiple files"; +char newerhelp[] = "get file if remote file is newer than local file "; +char nlisthelp[] = "nlist contents of remote directory"; +char nmaphelp[] = "set templates for default file name mapping"; +char ntranshelp[] = "set translation table for default file name mapping"; +char porthelp[] = "toggle use of PORT cmd for each data connection"; +char prompthelp[] = "force interactive prompting on multiple commands"; +char proxyhelp[] = "issue command on alternate connection"; +char pwdhelp[] = "print working directory on remote machine"; +char quithelp[] = "terminate ftp session and exit"; +char quotehelp[] = "send arbitrary ftp command"; +char receivehelp[] = "receive file"; +char regethelp[] = "get file restarting at end of local file"; +char remotehelp[] = "get help from remote server"; +char renamehelp[] = "rename file"; +char restarthelp[]= "restart file transfer at bytecount"; +char rmdirhelp[] = "remove directory on the remote machine"; +char rmtstatushelp[]="show status of remote machine"; +char runiquehelp[] = "toggle store unique for local files"; +char resethelp[] = "clear queued command replies"; +char sendhelp[] = "send one file"; +char passivehelp[] = "enter passive transfer mode"; +char sitehelp[] = "send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information"; +char shellhelp[] = "escape to the shell"; +char sizecmdhelp[] = "show size of remote file"; +char statushelp[] = "show current status"; +char structhelp[] = "set file transfer structure"; +char suniquehelp[] = "toggle store unique on remote machine"; +char systemhelp[] = "show remote system type"; +char tenexhelp[] = "set tenex file transfer type"; +char tracehelp[] = "toggle packet tracing"; +char typehelp[] = "set file transfer type"; +char umaskhelp[] = "get (set) umask on remote side"; +char userhelp[] = "send new user information"; +char verbosehelp[] = "toggle verbose mode"; + +struct cmd cmdtab[] = { + { "!", shellhelp, 0, 0, 0, shell }, + { "$", domachelp, 1, 0, 0, domacro }, + { "account", accounthelp, 0, 1, 1, account}, + { "append", appendhelp, 1, 1, 1, put }, + { "ascii", asciihelp, 0, 1, 1, setascii }, + { "bell", beephelp, 0, 0, 0, setbell }, + { "binary", binaryhelp, 0, 1, 1, setbinary }, + { "bye", quithelp, 0, 0, 0, quit }, + { "case", casehelp, 0, 0, 1, setcase }, + { "cd", cdhelp, 0, 1, 1, cd }, + { "cdup", cduphelp, 0, 1, 1, cdup }, + { "chmod", chmodhelp, 0, 1, 1, do_chmod }, + { "close", disconhelp, 0, 1, 1, disconnect }, + { "cr", crhelp, 0, 0, 0, setcr }, + { "delete", deletehelp, 0, 1, 1, delete }, + { "debug", debughelp, 0, 0, 0, setdebug }, + { "dir", dirhelp, 1, 1, 1, ls }, + { "disconnect", disconhelp, 0, 1, 1, disconnect }, + { "form", formhelp, 0, 1, 1, setform }, + { "get", receivehelp, 1, 1, 1, get }, + { "glob", globhelp, 0, 0, 0, setglob }, + { "hash", hashhelp, 0, 0, 0, sethash }, + { "help", helphelp, 0, 0, 1, help }, + { "idle", idlehelp, 0, 1, 1, idle }, + { "image", binaryhelp, 0, 1, 1, setbinary }, + { "lcd", lcdhelp, 0, 0, 0, lcd }, + { "ls", lshelp, 1, 1, 1, ls }, + { "macdef", macdefhelp, 0, 0, 0, macdef }, + { "mdelete", mdeletehelp, 1, 1, 1, mdelete }, + { "mdir", mdirhelp, 1, 1, 1, mls }, + { "mget", mgethelp, 1, 1, 1, mget }, + { "mkdir", mkdirhelp, 0, 1, 1, makedir }, + { "mls", mlshelp, 1, 1, 1, mls }, + { "mode", modehelp, 0, 1, 1, setmode }, + { "modtime", modtimehelp, 0, 1, 1, modtime }, + { "mput", mputhelp, 1, 1, 1, mput }, + { "newer", newerhelp, 1, 1, 1, newer }, + { "nmap", nmaphelp, 0, 0, 1, setnmap }, + { "nlist", nlisthelp, 1, 1, 1, ls }, + { "ntrans", ntranshelp, 0, 0, 1, setntrans }, + { "open", connecthelp, 0, 0, 1, setpeer }, + { "passive",passivehelp,0, 0, 0, setpassive }, + { "prompt", prompthelp, 0, 0, 0, setprompt }, + { "proxy", proxyhelp, 0, 0, 1, doproxy }, + { "sendport", porthelp, 0, 0, 0, setport }, + { "put", sendhelp, 1, 1, 1, put }, + { "pwd", pwdhelp, 0, 1, 1, pwd }, + { "quit", quithelp, 0, 0, 0, quit }, + { "quote", quotehelp, 1, 1, 1, quote }, + { "recv", receivehelp, 1, 1, 1, get }, + { "reget", regethelp, 1, 1, 1, reget }, + { "rstatus", rmtstatushelp, 0, 1, 1, rmtstatus }, + { "rhelp", remotehelp, 0, 1, 1, rmthelp }, + { "rename", renamehelp, 0, 1, 1, renamefile }, + { "reset", resethelp, 0, 1, 1, reset }, + { "restart", restarthelp, 1, 1, 1, restart }, + { "rmdir", rmdirhelp, 0, 1, 1, removedir }, + { "runique", runiquehelp, 0, 0, 1, setrunique }, + { "send", sendhelp, 1, 1, 1, put }, + { "site", sitehelp, 0, 1, 1, site }, + { "size", sizecmdhelp, 1, 1, 1, sizecmd }, + { "status", statushelp, 0, 0, 1, status }, + { "struct", structhelp, 0, 1, 1, setstruct }, + { "system", systemhelp, 0, 1, 1, syst }, + { "sunique", suniquehelp, 0, 0, 1, setsunique }, + { "tenex", tenexhelp, 0, 1, 1, settenex }, + { "trace", tracehelp, 0, 0, 0, settrace }, + { "type", typehelp, 0, 1, 1, settype }, + { "user", userhelp, 0, 1, 1, user }, + { "umask", umaskhelp, 0, 1, 1, do_umask }, + { "verbose", verbosehelp, 0, 0, 0, setverbose }, + { "?", helphelp, 0, 0, 1, help }, + { 0 }, +}; + +int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1; diff --git a/reactos/apps/utils/net/ftp/domacro.c b/reactos/apps/utils/net/ftp/domacro.c new file mode 100644 index 00000000000..75905858591 --- /dev/null +++ b/reactos/apps/utils/net/ftp/domacro.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)domacro.c 1.6 (Berkeley) 2/28/89"; +#endif /* not lint */ + +#include "ftp_var.h" +#include "prototypes.h" + +#include +#include +//#include +#include +//#include + +void domacro(argc, argv) + int argc; + char *argv[]; +{ + register int i, j; + register char *cp1, *cp2; + int count = 2, loopflg = 0; + char line2[200]; + extern char **glob(), *globerr; + struct cmd *getcmd(), *c; + extern struct cmd cmdtab[]; + + if (argc < 2) { + (void) strcat(line, " "); + printf("(macro name) "); + (void) fflush(stdout); + (void) gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc < 2) { + printf("Usage: %s macro_name.\n", argv[0]); + (void) fflush(stdout); + code = -1; + return; + } + for (i = 0; i < macnum; ++i) { + if (!strncmp(argv[1], macros[i].mac_name, 9)) { + break; + } + } + if (i == macnum) { + printf("'%s' macro not found.\n", argv[1]); + (void) fflush(stdout); + code = -1; + return; + } + (void) strcpy(line2, line); +TOP: + cp1 = macros[i].mac_start; + while (cp1 != macros[i].mac_end) { + while (isspace(*cp1)) { + cp1++; + } + cp2 = line; + while (*cp1 != '\0') { + switch(*cp1) { + case '\\': + *cp2++ = *++cp1; + break; + case '$': + if (isdigit(*(cp1+1))) { + j = 0; + while (isdigit(*++cp1)) { + j = 10*j + *cp1 - '0'; + } + cp1--; + if (argc - 2 >= j) { + (void) strcpy(cp2, argv[j+1]); + cp2 += strlen(argv[j+1]); + } + break; + } + if (*(cp1+1) == 'i') { + loopflg = 1; + cp1++; + if (count < argc) { + (void) strcpy(cp2, argv[count]); + cp2 += strlen(argv[count]); + } + break; + } + /* intentional drop through */ + default: + *cp2++ = *cp1; + break; + } + if (*cp1 != '\0') { + cp1++; + } + } + *cp2 = '\0'; + makeargv(); + c = getcmd(margv[0]); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + code = -1; + } + else if (c == 0) { + printf("?Invalid command\n"); + code = -1; + } + else if (c->c_conn && !connected) { + printf("Not connected.\n"); + code = -1; + } + else { + if (verbose) { + printf("%s\n",line); + } + (*c->c_handler)(margc, margv); + if (bell && c->c_bell) { + (void) putchar('\007'); + } + (void) strcpy(line, line2); + makeargv(); + argc = margc; + argv = margv; + } + if (cp1 != macros[i].mac_end) { + cp1++; + } + (void) fflush(stdout); + } + if (loopflg && ++count < argc) { + goto TOP; + } +} diff --git a/reactos/apps/utils/net/ftp/fake.c b/reactos/apps/utils/net/ftp/fake.c new file mode 100644 index 00000000000..eae28d80102 --- /dev/null +++ b/reactos/apps/utils/net/ftp/fake.c @@ -0,0 +1,300 @@ +#include +#include +#include +#include "prototypes.h" + +#define MAX_ASCII 100 + +int checkRecv(SOCKET s); + +int checkRecv(SOCKET s) +{ + int testVal; + fd_set sSet; + struct timeval timeout; + timeout.tv_sec = 60; + + FD_ZERO(&sSet); + + FD_SET(s, &sSet); + + testVal = select(0, &sSet, NULL, NULL, &timeout); + + if (testVal == SOCKET_ERROR) + fprintf(stderr, "Socket Error"); + + return testVal; +} + +void blkfree(char **av0) +{ + register char **av = av0; + + while (*av) + free(*av++); +} + +char *glob(register char *v) +{ + return NULL; +} + + +int sleep(int time) +{ + return time; +} + +int herror(char *string) +{ + return 0; +} +#if 0 + +int gettimeofday(struct timeval *timenow, + struct timezone *zone) +{ + time_t t; + + t = clock(); + + timenow->tv_usec = t; + timenow->tv_sec = t / CLK_TCK; + + return 0; +} + +int fgetcSocket(int s) +{ + int c; + char buffer[10]; + +// checkRecv(s); + + c = recv(s, buffer, 1, 0); + +#ifdef DEBUG_IN + printf("%c", buffer[0]); +#endif + + if (c == INVALID_SOCKET) + return c; + + if (c == 0) + return EOF; + + return buffer[0]; +} + +#else + +int fgetcSocket(int s) +{ + static int index = 0; + static int total = 0; + static unsigned char buffer[4096]; + + if (index == total) + { + index = 0; + total = recv(s, buffer, sizeof(buffer), 0); + + if (total == INVALID_SOCKET) + { + total = 0; + return ERROR; + } + + if (total == 0) + return EOF; + } + return buffer[index++]; +} + +#endif + +char *fprintfSocket(int s, char *format, ...) +{ + va_list argptr; + char buffer[10009]; + + va_start(argptr, format); + vsprintf(buffer, format, argptr); + va_end(argptr); + + send(s, buffer, strlen(buffer), 0); + + return NULL; +} + +char *fputsSocket(char *format, int s) +{ + send(s, format, strlen(format), 0); + + return NULL; +} + +int fputcSocket(int s, char putChar) +{ + char buffer[2]; + + buffer[0] = putChar; + buffer[1] = '\0'; + + if(SOCKET_ERROR==send(s, buffer, 1, 0)) { + int iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; + } + else { + return putChar; + } +} +int fputSocket(int s, char *buffer, int len) +{ + int iret; + while(len) { + if(SOCKET_ERROR==(iret=send(s, buffer, len, 0))) + { + iret=WSAGetLastError (); + fprintf(stdout,"fputcSocket: %d\n",iret); + return 0; + } + else { + return len-=iret; + } + } + return 0; +} + +char *fgetsSocket(int s, char *string) +{ + char buffer[2] = {0}; + int i, count; + + for (i = 0, count = 1; count != 0 && buffer[0] != '\n'; i++) + { + checkRecv(s); + + count = recv(s, buffer, 1, 0); + + if (count == SOCKET_ERROR) + { + printf("Error in fgetssocket"); + return NULL; + } + + if (count == 1) + { + string[i] = buffer[0]; + + if (i == MAX_ASCII - 3) + { + count = 0; + string[++i] = '\n'; + string[++i] = '\0'; + } + } + else + { + if (i == 0) + return NULL; + else + { + string[i] = '\n'; + string[i + 1] = '\0'; // This is risky + return string; + } + + } + + } + string[i] = '\0'; + +#ifdef DEBUG_IN + printf("%s", string); +#endif + return string; +} + + +#if 0 +char *getpass(const char *prompt) +{ + static char string[64]; + + printf("%s", prompt); + + gets(string); + + return string; +} +#endif +char *getpass (const char * prompt) +{ + static char input[256]; + HANDLE in; + HANDLE err; + int count; + + in = GetStdHandle (STD_INPUT_HANDLE); + err = GetStdHandle (STD_ERROR_HANDLE); + + if (in == INVALID_HANDLE_VALUE || err == INVALID_HANDLE_VALUE) + return NULL; + + if (WriteFile (err, prompt, strlen (prompt), &count, NULL)) + { + int istty = (GetFileType (in) == FILE_TYPE_CHAR); + DWORD old_flags; + int rc; + + if (istty) + { + if (GetConsoleMode (in, &old_flags)) + SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); + else + istty = 0; + } + /* Need to read line one byte at time to avoid blocking, if not a + tty, so always do it this way. */ + count = 0; + while (1) + { + DWORD dummy; + char one_char; + + rc = ReadFile (in, &one_char, 1, &dummy, NULL); + if (rc == 0) + break; + if (one_char == '\r') + { + /* CR is always followed by LF if reading from tty. */ + if (istty) + continue; + else + break; + } + if (one_char == '\n') + break; + /* Silently truncate password string if overly long. */ + if (count < sizeof (input) - 1) + input[count++] = one_char; + } + input[count] = '\0'; + + WriteFile (err, "\r\n", 2, &count, NULL); + if (istty) + SetConsoleMode (in, old_flags); + if (rc) + return input; + } + + return NULL; +} + +// Stubbed out here. Should be changed in Source code... +int access(const char *filename, int accessmethod) +{ + return 0; +} diff --git a/reactos/apps/utils/net/ftp/fake.h b/reactos/apps/utils/net/ftp/fake.h new file mode 100644 index 00000000000..82197efba6a --- /dev/null +++ b/reactos/apps/utils/net/ftp/fake.h @@ -0,0 +1,10 @@ +#define bcopy(s,d,l) memcpy((d),(s),(l)) +#define bzero(cp,l) memset((cp),0,(l)) + +#define rindex strrchr +#define index strchr + +#define getwd getcwd + +#define strcasecmp strcmp +#define strncasecmp strnicmp diff --git a/reactos/apps/utils/net/ftp/ftp.c b/reactos/apps/utils/net/ftp/ftp.c new file mode 100644 index 00000000000..4e2bbb3d235 --- /dev/null +++ b/reactos/apps/utils/net/ftp/ftp.c @@ -0,0 +1,1805 @@ +#define L_SET SEEK_SET +#define L_INCR SEEK_CUR +#define caddr_t void * +/* + * Copyright (c) 1985, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)ftp.c 5.28 (Berkeley) 4/20/89"; +#endif /* not lint */ +#include + +#include + +#if !defined(WIN32) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include +#include + +#include "ftp_var.h" +#include "prototypes.h" +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#ifdef NOVFPRINTF +#define vfprintf(a,b,c) _doprnt(b,c,a) +#endif + +#ifdef sun +/* FD_SET wasn't defined until 4.0. its a cheap test for uid_t presence */ +#ifndef FD_SET +#define NBBY 8 /* number of bits in a byte */ +/* + * Select uses bit masks of file descriptors in longs. + * These macros manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here + * should be >= NOFILE (param.h). + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 256 +#endif + +typedef long fd_mask; +#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif + +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) + +typedef int uid_t; +typedef int gid_t; +#endif +#endif + +struct sockaddr_in hisctladdr; +struct sockaddr_in data_addr; +int data = -1; +int abrtflag = 0; +int ptflag = 0; +int allbinary; +struct sockaddr_in myctladdr; +uid_t getuid(); +sig_t lostpeer(); +off_t restart_point = 0; + +int cin, cout; +int dataconn(char *mode); + +int command(char *fmt, ...); + +char *hostname; + +typedef void (*Sig_t)(int); + +// Signal Handlers + +void psabort(int sig); + +char *hookup(char *host, int port) +{ + register struct hostent *hp = 0; + int s,len; + static char hostnamebuf[80]; + + bzero((char *)&hisctladdr, sizeof (hisctladdr)); + hisctladdr.sin_addr.s_addr = inet_addr(host); + if (hisctladdr.sin_addr.s_addr != -1) { + hisctladdr.sin_family = AF_INET; + (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf)); + } else { + hp = gethostbyname(host); + if (hp == NULL) { + fprintf(stderr, "ftp: %s: ", host); + herror((char *)NULL); + code = -1; + return((char *) 0); + } + hisctladdr.sin_family = hp->h_addrtype; + bcopy(hp->h_addr_list[0], + (caddr_t)&hisctladdr.sin_addr, hp->h_length); + (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); + } + hostname = hostnamebuf; + s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + if (s < 0) { + perror("ftp: socket"); + code = -1; + return (0); + } + hisctladdr.sin_port = port; + while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { + if (hp && hp->h_addr_list[1]) { + int oerrno = errno; + + fprintf(stderr, "ftp: connect to address %s: ", + inet_ntoa(hisctladdr.sin_addr)); + errno = oerrno; + perror((char *) 0); + hp->h_addr_list++; + bcopy(hp->h_addr_list[0], + (caddr_t)&hisctladdr.sin_addr, hp->h_length); + fprintf(stdout, "Trying %s...\n", + inet_ntoa(hisctladdr.sin_addr)); + (void) fflush(stdout); + (void) close(s); + s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + if (s < 0) { + perror("ftp: socket"); + code = -1; + return (0); + } + continue; + } + perror("ftp: connect"); + code = -1; + goto bad; + } + len = sizeof (myctladdr); + if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { + perror("ftp: getsockname"); + code = -1; + goto bad; + } + cin = cout = s; + if (verbose) { + printf("Connected to %s.\n", hostname); + (void) fflush(stdout); + } + if (getreply(0) > 2) { /* read startup message from server */ + closesocket(cin); + code = -1; + goto bad; + } +#ifdef SO_OOBINLINE + { + int on = 1; + + if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (const char *) &on, sizeof(on)) + < 0 && debug) { + perror("ftp: setsockopt"); + } + } +#endif SO_OOBINLINE + + return (hostname); +bad: + (void) close(s); + return ((char *)0); +} + +int login(char *host) +{ + char tmp[80]; + char *user, *pass, *acct; + int n, aflag = 0; + + user = pass = acct = 0; + if (ruserpass(host, &user, &pass, &acct) < 0) { + code = -1; + return(0); + } + while (user == NULL) { + char *myname = "none"; // This needs to become the usename env + + if (myname) + printf("Name (%s:%s): ", host, myname); + else + printf("Name (%s): ", host); + (void) fflush(stdout); + (void) fgets(tmp, sizeof(tmp) - 1, stdin); + tmp[strlen(tmp) - 1] = '\0'; + if (*tmp == '\0') + user = myname; + else + user = tmp; + } + n = command("USER %s", user); + if (n == CONTINUE) { + if (pass == NULL) + pass = getpass("Password:"); + n = command("PASS %s", pass); + fflush(stdin); + } + if (n == CONTINUE) { + aflag++; + acct = getpass("Account:"); + n = command("ACCT %s", acct); + } + if (n != COMPLETE) { + fprintf(stderr, "Login failed.\n"); + return (0); + } + if (!aflag && acct != NULL) + (void) command("ACCT %s", acct); + if (proxy) + return(1); + for (n = 0; n < macnum; ++n) { + if (!strcmp("init", macros[n].mac_name)) { + (void) strcpy(line, "$init"); + makeargv(); + domacro(margc, margv); + break; + } + } + return (1); +} + +void +cmdabort(int sig) +{ + extern jmp_buf ptabort; + + printf("\n"); + (void) fflush(stdout); + abrtflag++; + if (ptflag) + longjmp(ptabort,1); +} + +/*VARARGS1*/ +int command(char *fmt, ...) +{ + va_list ap; + int r; + void (*oldintr)(int), cmdabort(int); + + abrtflag = 0; + if (debug) { + printf("---> "); + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); + printf("\n"); + (void) fflush(stdout); + } + if (cout == (int) NULL) { + perror ("No control connection for command"); + code = -1; + return (0); + } + oldintr = signal(SIGINT,cmdabort); + { + char buffer[1024]; + + va_start(ap, fmt); + vsprintf(buffer, fmt, ap); + va_end(ap); +//DLJ: to work through firewalls - send the command as a single message + strcat(buffer,"\r\n"); + fprintfSocket(cout, buffer); + } +//DLJ: the following two lines are replaced by the strcat above - seems to +// make it work through firewalls. +// fprintfSocket(cout, "\r\n"); +// (void) fflush(cout); + cpend = 1; + r = getreply(!strcmp(fmt, "QUIT")); + if (abrtflag && oldintr != SIG_IGN) + (*oldintr)(SIGINT); +// (void) signal(SIGINT, oldintr); + return(r); +} + +char reply_string[BUFSIZ]; /* last line of previous reply */ + +#include + +getreply(expecteof) + int expecteof; +{ + register int c, n; + register int dig; + register char *cp; + int originalcode = 0, continuation = 0; + void (*oldintr)(int), cmdabort(int); + int pflag = 0; + char *pt = pasv; + + oldintr = signal(SIGINT,cmdabort); + for (;;) { + dig = n = code = 0; + cp = reply_string; + while ((c = fgetcSocket(cin)) != '\n') { + if (c == IAC) { /* handle telnet commands */ + switch (c = fgetcSocket(cin)) { + case WILL: + case WONT: + c = fgetcSocket(cin); + fprintfSocket(cout, "%c%c%c",IAC,DONT,c); + break; + case DO: + case DONT: + c = fgetcSocket(cin); + fprintfSocket(cout, "%c%c%c",IAC,WONT,c); + break; + default: + break; + } + continue; + } + dig++; + if (c == EOF) { + if (expecteof) { +// (void) signal(SIGINT,oldintr); + code = 221; + return (0); + } + lostpeer(); + if (verbose) { + printf("421 Service not available, remote server has closed connection\n"); + (void) fflush(stdout); + } + code = 421; + return(4); + } + if (c != '\r' && (verbose > 0 || + (verbose > -1 && n == '5' && dig > 4))) { + if (proxflag && + (dig == 1 || dig == 5 && verbose == 0)) + printf("%s:",hostname); + (void) putchar(c); + (void) fflush(stdout); + } + if (dig < 4 && isdigit(c)) + code = code * 10 + (c - '0'); + if (!pflag && code == 227) + pflag = 1; + if (dig > 4 && pflag == 1 && isdigit(c)) + pflag = 2; + if (pflag == 2) { + if (c != '\r' && c != ')') + *pt++ = c; + else { + *pt = '\0'; + pflag = 3; + } + } + if (dig == 4 && c == '-') { + if (continuation) + code = 0; + continuation++; + } + if (n == 0) + n = c; + if (cp < &reply_string[sizeof(reply_string) - 1]) + *cp++ = c; + } + if (verbose > 0 || verbose > -1 && n == '5') { + (void) putchar(c); + (void) fflush (stdout); + } + if (continuation && code != originalcode) { + if (originalcode == 0) + originalcode = code; + continue; + } + *cp = '\0'; + if (n != '1') + cpend = 0; + (void) signal(SIGINT,oldintr); + if (code == 421 || originalcode == 421) + lostpeer(); + if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) + (*oldintr)(SIGINT); + return (n - '0'); + } +} + +empty(mask, sec) + struct fd_set *mask; + int sec; +{ + struct timeval t; + + t.tv_sec = (long) sec; + t.tv_usec = 0; + return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t)); +} + +jmp_buf sendabort; + +void abortsend() +{ + + mflag = 0; + abrtflag = 0; + printf("\nsend aborted\n"); + (void) fflush(stdout); + longjmp(sendabort, 1); +} + +#define HASHBYTES 1024 + +void sendrequest(char *cmd, char *local, char *remote, int printnames) +{ + FILE *fin; + int dout = 0; + int (*closefunc)(), _pclose(), fclose(); + sig_t (*oldintr)(), (*oldintp)(); + void abortsend(); + char buf[BUFSIZ], *bufp; + long bytes = 0, hashbytes = HASHBYTES; + register int c, d; + struct stat st; + struct timeval start, stop; + char *mode; + + if (verbose && printnames) { + if (local && *local != '-') + printf("local: %s ", local); + if (remote) + printf("remote: %s\n", remote); + (void) fflush(stdout); + } + if (proxy) { + proxtrans(cmd, local, remote); + return; + } + closefunc = NULL; + oldintr = NULL; + oldintp = NULL; + mode = "w"; + if (setjmp(sendabort)) { + while (cpend) { + (void) getreply(0); + } + if (data >= 0) { + (void) close(data); + data = -1; + } + if (oldintr) +null();// (void) signal(SIGINT,oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE,oldintp); + code = -1; + return; + } +null();// oldintr = signal(SIGINT, abortsend); + if (strcmp(local, "-") == 0) + fin = stdin; + else if (*local == '|') { +null();// oldintp = signal(SIGPIPE,SIG_IGN); + fin = _popen(local + 1, "r"); + if (fin == NULL) { + perror(local + 1); +null();// (void) signal(SIGINT, oldintr); +null();// (void) signal(SIGPIPE, oldintp); + code = -1; + return; + } + closefunc = _pclose; + } else { + fin = fopen(local, "r"); + if (fin == NULL) { + perror(local); +null();// (void) signal(SIGINT, oldintr); + code = -1; + return; + } + closefunc = fclose; + if (fstat(fileno(fin), &st) < 0 || + (st.st_mode&S_IFMT) != S_IFREG) { + fprintf(stdout, "%s: not a plain file.\n", local); + (void) fflush(stdout); +null();// (void) signal(SIGINT, oldintr); + fclose(fin); + code = -1; + return; + } + } + if (initconn()) { +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + code = -1; + if (closefunc != NULL) + (*closefunc)(fin); + return; + } + if (setjmp(sendabort)) + goto abort; + + if (restart_point && + (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { + if (fseek(fin, (long) restart_point, 0) < 0) { + perror(local); + restart_point = 0; + if (closefunc != NULL) + (*closefunc)(fin); + return; + } + if (command("REST %ld", (long) restart_point) + != CONTINUE) { + restart_point = 0; + if (closefunc != NULL) + (*closefunc)(fin); + return; + } + restart_point = 0; + mode = "r+w"; + } + if (remote) { + if (command("%s %s", cmd, remote) != PRELIM) { +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + if (closefunc != NULL) + (*closefunc)(fin); + return; + } + } else + if (command("%s", cmd) != PRELIM) { +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + if (closefunc != NULL) + (*closefunc)(fin); + return; + } + dout = dataconn(mode); + if (dout == (int)NULL) + goto abort; + (void) gettimeofday(&start, (struct timezone *)0); +null();// oldintp = signal(SIGPIPE, SIG_IGN); + switch (type) { + + case TYPE_I: + case TYPE_L: + errno = d = 0; + while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { + bytes += c; + for (bufp = buf; c > 0; c -= d, bufp += d) + if ((d = send(dout, bufp, c, 0)) <= 0) + break; + if (hash) { + while (bytes >= hashbytes) { + (void) putchar('#'); + hashbytes += HASHBYTES; + } + (void) fflush(stdout); + } + } + if (hash && bytes > 0) { + if (bytes < HASHBYTES) + (void) putchar('#'); + (void) putchar('\n'); + (void) fflush(stdout); + } + if (c < 0) + perror(local); + if (d <= 0) { + if (d == 0) + fprintf(stderr, "netout: write returned 0?\n"); + else if (errno != EPIPE) + perror("netout"); + bytes = -1; + } + break; + + case TYPE_A: + { + char buf[1024]; + static int bufsize = 1024; + int ipos=0; + + while ((c = getc(fin)) != EOF) { + if (c == '\n') { + while (hash && (bytes >= hashbytes)) { + (void) putchar('#'); + (void) fflush(stdout); + hashbytes += HASHBYTES; + } +// Szurgot: The following code is unncessary on Win32. +// (void) fputcSocket(dout, '\r'); +// bytes++; + } + + if (ipos >= bufsize) { + fputSocket(dout,buf,ipos); + if(!hash) (void) putchar('.'); + ipos=0; + } + buf[ipos]=c; ++ipos; + bytes++; + } + if (ipos) { + fputSocket(dout,buf,ipos); + ipos=0; + } + if (hash) { + if (bytes < hashbytes) + (void) putchar('#'); + (void) putchar('\n'); + (void) fflush(stdout); + } + else { + (void) putchar('.'); + (void) putchar('\n'); + (void) fflush(stdout); + } + if (ferror(fin)) + perror(local); +// if (ferror(dout)) { +// if (errno != EPIPE) +// perror("netout"); +// bytes = -1; +// } + break; + } + } + (void) gettimeofday(&stop, (struct timezone *)0); + if (closefunc != NULL) + (*closefunc)(fin); + if(closesocket(dout)) { + int iret=WSAGetLastError (); + fprintf(stdout,"Error closing socket(%d)\n",iret); + (void) fflush(stdout); + } + (void) getreply(0); +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + if (bytes > 0) + ptransfer("sent", bytes, &start, &stop); + return; +abort: + (void) gettimeofday(&stop, (struct timezone *)0); +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + if (!cpend) { + code = -1; + return; + } + if (data >= 0) { + (void) close(data); + data = -1; + } + if (dout) + if(closesocket(dout)) { + int iret=WSAGetLastError (); + fprintf(stdout,"Error closing socket(%d)\n",iret); + (void) fflush(stdout); + } + + (void) getreply(0); + code = -1; + if (closefunc != NULL && fin != NULL) + (*closefunc)(fin); + if (bytes > 0) + ptransfer("sent", bytes, &start, &stop); +} + +jmp_buf recvabort; + + +void abortrecv() +{ + + mflag = 0; + abrtflag = 0; + printf("\n"); + (void) fflush(stdout); + longjmp(recvabort, 1); +} + +void recvrequest(char *cmd, char *local, char *remote, char *mode, + int printnames) +{ + FILE *fout; + int din = 0; + int (*closefunc)(), _pclose(), fclose(); + void (*oldintr)(int), (*oldintp)(int); + void abortrecv(); + int oldverbose, oldtype = 0, is_retr, tcrflag, nfnd, bare_lfs = 0; + char *gunique(), msg; +// static char *buf; // Szurgot: Shouldn't this go SOMEWHERE? + char buf[1024]; + static int bufsize = 1024; + long bytes = 0, hashbytes = HASHBYTES; +// struct + fd_set mask; + register int c, d; + struct timeval start, stop; +// struct stat st; + extern void *malloc(); + + is_retr = strcmp(cmd, "RETR") == 0; + if (is_retr && verbose && printnames) { + if (local && *local != '-') + printf("local: %s ", local); + if (remote) + printf("remote: %s\n", remote); + (void) fflush(stdout); + } + if (proxy && is_retr) { + proxtrans(cmd, local, remote); + return; + } + closefunc = NULL; + oldintr = NULL; + oldintp = NULL; + tcrflag = !crflag && is_retr; + if (setjmp(recvabort)) { + while (cpend) { + (void) getreply(0); + } + if (data >= 0) { + (void) close(data); + data = -1; + } + if (oldintr) +null();// (void) signal(SIGINT, oldintr); + code = -1; + return; + } +null();// oldintr = signal(SIGINT, abortrecv); + if (strcmp(local, "-") && *local != '|') { +#ifndef __WIN32__ +// This whole thing is a problem... access Won't work on non-existent files + if (access(local, 2) < 0) { + char *dir = rindex(local, '/'); + + if (errno != ENOENT && errno != EACCES) { + perror(local); + (void) signal(SIGINT, oldintr); + code = -1; + return; + } + if (dir != NULL) + *dir = 0; + d = access(dir ? local : ".", 2); + if (dir != NULL) + *dir = '/'; + if (d < 0) { + perror(local); + (void) signal(SIGINT, oldintr); + code = -1; + return; + } + if (!runique && errno == EACCES && + chmod(local, 0600) < 0) { + perror(local); + (void) signal(SIGINT, oldintr); + code = -1; + return; + } + if (runique && errno == EACCES && + (local = gunique(local)) == NULL) { + (void) signal(SIGINT, oldintr); + code = -1; + return; + } + } + else if (runique && (local = gunique(local)) == NULL) { + (void) signal(SIGINT, oldintr); + code = -1; + return; + } +#endif + } + if (initconn()) { +null();// (void) signal(SIGINT, oldintr); + code = -1; + return; + } + if (setjmp(recvabort)) + goto abort; + if (!is_retr) { + if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) { + oldtype = type; + oldverbose = verbose; + if (!debug) + verbose = 0; + setascii(); + verbose = oldverbose; + } + } else if (restart_point) { + if (command("REST %ld", (long) restart_point) != CONTINUE) + return; + } + if (remote) { + if (command("%s %s", cmd, remote) != PRELIM) { +null();// (void) signal(SIGINT, oldintr); + if (oldtype) { + if (!debug) + verbose = 0; + switch (oldtype) { + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + verbose = oldverbose; + } + return; + } + } else { + if (command("%s", cmd) != PRELIM) { +null();// (void) signal(SIGINT, oldintr); + if (oldtype) { + if (!debug) + verbose = 0; + switch (oldtype) { + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + verbose = oldverbose; + } + return; + } + } + din = dataconn("r"); + if (din == (int)NULL) + goto abort; + if (strcmp(local, "-") == 0) + fout = stdout; + else if (*local == '|') { +null();// oldintp = signal(SIGPIPE, SIG_IGN); + fout = _popen(local + 1, "w"); + if (fout == NULL) { + perror(local+1); + goto abort; + } + closefunc = _pclose; + } else { + fout = fopen(local, mode); + if (fout == NULL) { + perror(local); + goto abort; + } + closefunc = fclose; + } + (void) gettimeofday(&start, (struct timezone *)0); + switch (type) { + + case TYPE_I: + case TYPE_L: + if (restart_point && + lseek(fileno(fout), (long) restart_point, L_SET) < 0) { + perror(local); + if (closefunc != NULL) + (*closefunc)(fout); + return; + } + errno = d = 0; +// while ((c = recv(din, buf, bufsize, 1)) > 0) { +// if ((d = write(fileno(fout), buf, c)) != c) +// if ((d = write(fileno(fout), buf, c)) != c) +// break; + while ((c = recv(din, buf, bufsize, 0)) > 0) { + write(fileno(fout), buf, c); + bytes += c; + if (hash) { + while (bytes >= hashbytes) { + (void) putchar('#'); + hashbytes += HASHBYTES; + } + (void) fflush(stdout); + } + } + if (hash && bytes > 0) { + if (bytes < HASHBYTES) + (void) putchar('#'); + (void) putchar('\n'); + (void) fflush(stdout); + } +// if (c < 0) { +// if (errno != EPIPE) +// perror("netin"); +// bytes = -1; +// } +// if (d < c) { +// if (d < 0) +// perror(local); +// else +// fprintf(stderr, "%s: short write\n", local); +// } + break; + + case TYPE_A: + if (restart_point) { + register int i, n, c; + + if (fseek(fout, 0L, L_SET) < 0) + goto done; + n = restart_point; + i = 0; + while (i++ < n) { + if ((c=getc(fout)) == EOF) + goto done; + if (c == '\n') + i++; + } + if (fseek(fout, 0L, L_INCR) < 0) { +done: + perror(local); + if (closefunc != NULL) + (*closefunc)(fout); + return; + } + } + while ((c = fgetcSocket(din)) != EOF) { + if (c == '\n') + bare_lfs++; + while (c == '\r') { + while (hash && (bytes >= hashbytes)) { + (void) putchar('#'); + (void) fflush(stdout); + hashbytes += HASHBYTES; + } + bytes++; + if ((c = fgetcSocket(din)) != '\n' || tcrflag) { + if (ferror(fout)) + goto break2; + (void) putc('\r', fout); + if (c == '\0') { + bytes++; + goto contin2; + } + if (c == EOF) + goto contin2; + } + } + (void) putc(c, fout); + bytes++; + contin2: ; + } +break2: + if (bare_lfs) { + printf("WARNING! %d bare linefeeds received in ASCII mode\n"); + printf("File may not have transferred correctly.\n"); + (void) fflush(stdout); + } + if (hash) { + if (bytes < hashbytes) + (void) putchar('#'); + (void) putchar('\n'); + (void) fflush(stdout); + } +// if (ferror(din)) { +// if (errno != EPIPE) +// perror("netin"); +// bytes = -1; +// } + if (ferror(fout)) + perror(local); + break; + } + if (closefunc != NULL) + (*closefunc)(fout); +null();// (void) signal(SIGINT, oldintr); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintp); + (void) gettimeofday(&stop, (struct timezone *)0); + if(closesocket(din)) { + int iret=WSAGetLastError (); + fprintf(stdout,"Error closing socket(%d)\n",iret); + (void) fflush(stdout); + } + + (void) getreply(0); + if (bytes > 0 && is_retr) + ptransfer("received", bytes, &start, &stop); + if (oldtype) { + if (!debug) + verbose = 0; + switch (oldtype) { + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + verbose = oldverbose; + } + return; +abort: + +/* abort using RFC959 recommended IP,SYNC sequence */ + + (void) gettimeofday(&stop, (struct timezone *)0); + if (oldintp) +null();// (void) signal(SIGPIPE, oldintr); +null();// (void) signal(SIGINT,SIG_IGN); + if (oldtype) { + if (!debug) + verbose = 0; + switch (oldtype) { + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + verbose = oldverbose; + } + if (!cpend) { + code = -1; +null();// (void) signal(SIGINT,oldintr); + return; + } + + fprintfSocket(cout,"%c%c",IAC,IP); + msg = (char)IAC; +/* send IAC in urgent mode instead of DM because UNIX places oob mark */ +/* after urgent byte rather than before as now is protocol */ + if (send(cout,&msg,1,MSG_OOB) != 1) { + perror("abort"); + } + fprintfSocket(cout,"%cABOR\r\n",DM); + FD_ZERO(&mask); + FD_SET(cin, &mask); // Need to correct this + if (din) { + FD_SET(din, &mask); // Need to correct this + } + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + code = -1; + lostpeer(); + } + if (din && FD_ISSET(din, &mask)) { + while ((c = recv(din, buf, bufsize, 0)) > 0) + ; + } + if ((c = getreply(0)) == ERROR && code == 552) { /* needed for nic style abort */ + if (data >= 0) { + (void) close(data); + data = -1; + } + (void) getreply(0); + } + (void) getreply(0); + code = -1; + if (data >= 0) { + (void) close(data); + data = -1; + } + if (closefunc != NULL && fout != NULL) + (*closefunc)(fout); + if (din) + if(closesocket(din)) { + int iret=WSAGetLastError (); + fprintf(stdout,"Error closing socket(%d)\n",iret); + (void) fflush(stdout); + } + + if (bytes > 0) + ptransfer("received", bytes, &start, &stop); +null();// (void) signal(SIGINT,oldintr); +} + +/* + * Need to start a listen on the data channel + * before we send the command, otherwise the + * server's connect may fail. + */ +int sendport = -1; + +initconn() +{ + register char *p, *a; + int result, len, tmpno = 0; + int on = 1; + int a0, a1, a2, a3, p0, p1; + + + if (passivemode) { + data = socket(AF_INET, SOCK_STREAM, 0); + if (data < 0) { + perror("ftp: socket"); + return(1); + } + if ((options & SO_DEBUG) && + setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, + sizeof (on)) < 0) + perror("ftp: setsockopt (ignored)"); + if (command("PASV") != COMPLETE) { + printf("Passive mode refused.\n"); + goto bad; + } + + /* + * What we've got at this point is a string of comma + * separated one-byte unsigned integer values. + * The first four are the an IP address. The fifth is + * the MSB of the port number, the sixth is the LSB. + * From that we'll prepare a sockaddr_in. + */ + + if (sscanf(pasv,"%d,%d,%d,%d,%d,%d", + &a0, &a1, &a2, &a3, &p0, &p1) != 6) { + printf("Passive mode address scan failure. Shouldn't happen!\n"); + goto bad; + } + + bzero(&data_addr, sizeof(data_addr)); + data_addr.sin_family = AF_INET; + a = (char *)&data_addr.sin_addr.s_addr; + a[0] = a0 & 0xff; + a[1] = a1 & 0xff; + a[2] = a2 & 0xff; + a[3] = a3 & 0xff; + p = (char *)&data_addr.sin_port; + p[0] = p0 & 0xff; + p[1] = p1 & 0xff; + + if (connect(data, (struct sockaddr *)&data_addr, + sizeof(data_addr)) < 0) { + perror("ftp: connect"); + goto bad; + } + return(0); + } + + +noport: + data_addr = myctladdr; + if (sendport) + data_addr.sin_port = 0; /* let system pick one */ + if (data != -1) + (void) close (data); + data = socket(AF_INET, SOCK_STREAM, 0); + if (data < 0) { + perror("ftp: socket"); + if (tmpno) + sendport = 1; + return (1); + } + if (!sendport) + if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) { + perror("ftp: setsockopt (reuse address)"); + goto bad; + } + if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { + perror("ftp: bind"); + goto bad; + } + if (options & SO_DEBUG && + setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) + perror("ftp: setsockopt (ignored)"); + len = sizeof (data_addr); + if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { + perror("ftp: getsockname"); + goto bad; + } + if (listen(data, 1) < 0) + perror("ftp: listen"); + if (sendport) { + a = (char *)&data_addr.sin_addr; + p = (char *)&data_addr.sin_port; +#define UC(b) (((int)b)&0xff) + result = + command("PORT %d,%d,%d,%d,%d,%d", + UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), + UC(p[0]), UC(p[1])); + if (result == ERROR && sendport == -1) { + sendport = 0; + tmpno = 1; + goto noport; + } + return (result != COMPLETE); + } + if (tmpno) + sendport = 1; + return (0); +bad: + (void) fflush(stdout); + (void) close(data), data = -1; + if (tmpno) + sendport = 1; + return (1); +} + +int dataconn(char *mode) +{ + struct sockaddr_in from; + int s, fromlen = sizeof (from); + + if (passivemode) + return (data); + + s = accept(data, (struct sockaddr *) &from, &fromlen); + if (s < 0) { + perror("ftp: accept"); + (void) closesocket(data), data = -1; + return (int) (NULL); + } + if(closesocket(data)) { + int iret=WSAGetLastError (); + fprintf(stdout,"Error closing socket(%d)\n",iret); + (void) fflush(stdout); + } + + data = s; + return (data); +} + +void ptransfer(direction, bytes, t0, t1) + char *direction; + long bytes; + struct timeval *t0, *t1; +{ + struct timeval td; + double s, bs; + + if (verbose) { + tvsub(&td, t1, t0); + s = td.tv_sec + (td.tv_usec / 1000000.); +#define nz(x) ((x) == 0 ? 1 : (x)) + bs = bytes / nz(s); + printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n", + bytes, direction, s, bs / 1024.); + (void) fflush(stdout); + } +} + +/*tvadd(tsum, t0) + struct timeval *tsum, *t0; +{ + + tsum->tv_sec += t0->tv_sec; + tsum->tv_usec += t0->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} */ + +void tvsub(tdiff, t1, t0) + struct timeval *tdiff, *t1, *t0; +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +void psabort(int flag) +{ + extern int abrtflag; + + abrtflag++; +} + +void pswitch(int flag) +{ + extern int proxy, abrtflag; + Sig_t oldintr; + static struct comvars { + int connect; + char name[MAXHOSTNAMELEN]; + struct sockaddr_in mctl; + struct sockaddr_in hctl; + FILE *in; + FILE *out; + int tpe; + int cpnd; + int sunqe; + int runqe; + int mcse; + int ntflg; + char nti[17]; + char nto[17]; + int mapflg; + char mi[MAXPATHLEN]; + char mo[MAXPATHLEN]; + } proxstruct, tmpstruct; + struct comvars *ip, *op; + + abrtflag = 0; + oldintr = signal(SIGINT, psabort); + if (flag) { + if (proxy) + return; + ip = &tmpstruct; + op = &proxstruct; + proxy++; + } + else { + if (!proxy) + return; + ip = &proxstruct; + op = &tmpstruct; + proxy = 0; + } + ip->connect = connected; + connected = op->connect; + if (hostname) { + (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1); + ip->name[strlen(ip->name)] = '\0'; + } else + ip->name[0] = 0; + hostname = op->name; + ip->hctl = hisctladdr; + hisctladdr = op->hctl; + ip->mctl = myctladdr; + myctladdr = op->mctl; + (int) ip->in = cin; // What the hell am I looking at...? + cin = (int) op->in; + (int) ip->out = cout; // Same again... + cout = (int) op->out; + ip->tpe = type; + type = op->tpe; + if (!type) + type = 1; + ip->cpnd = cpend; + cpend = op->cpnd; + ip->sunqe = sunique; + sunique = op->sunqe; + ip->runqe = runique; + runique = op->runqe; + ip->mcse = mcase; + mcase = op->mcse; + ip->ntflg = ntflag; + ntflag = op->ntflg; + (void) strncpy(ip->nti, ntin, 16); + (ip->nti)[strlen(ip->nti)] = '\0'; + (void) strcpy(ntin, op->nti); + (void) strncpy(ip->nto, ntout, 16); + (ip->nto)[strlen(ip->nto)] = '\0'; + (void) strcpy(ntout, op->nto); + ip->mapflg = mapflag; + mapflag = op->mapflg; + (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1); + (ip->mi)[strlen(ip->mi)] = '\0'; + (void) strcpy(mapin, op->mi); + (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1); + (ip->mo)[strlen(ip->mo)] = '\0'; + (void) strcpy(mapout, op->mo); +// (void) signal(SIGINT, oldintr); + if (abrtflag) { + abrtflag = 0; + (*oldintr)(1); + } +} + +jmp_buf ptabort; +int ptabflg; + +void +abortpt() +{ + printf("\n"); + (void) fflush(stdout); + ptabflg++; + mflag = 0; + abrtflag = 0; + longjmp(ptabort, 1); +} + +void proxtrans(cmd, local, remote) + char *cmd, *local, *remote; +{ +// void (*oldintr)(int); + void abortpt(int); + int tmptype, oldtype = 0, secndflag = 0, nfnd; + extern jmp_buf ptabort; + char *cmd2; +// struct + fd_set mask; + + if (strcmp(cmd, "RETR")) + cmd2 = "RETR"; + else + cmd2 = runique ? "STOU" : "STOR"; + if (command("PASV") != COMPLETE) { + printf("proxy server does not support third part transfers.\n"); + (void) fflush(stdout); + return; + } + tmptype = type; + pswitch(0); + if (!connected) { + printf("No primary connection\n"); + (void) fflush(stdout); + pswitch(1); + code = -1; + return; + } + if (type != tmptype) { + oldtype = type; + switch (tmptype) { + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + } + if (command("PORT %s", pasv) != COMPLETE) { + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + pswitch(1); + return; + } + if (setjmp(ptabort)) + goto abort; +null();// oldintr = signal(SIGINT, abortpt); + if (command("%s %s", cmd, remote) != PRELIM) { +null();// (void) signal(SIGINT, oldintr); + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + pswitch(1); + return; + } + sleep(2); + pswitch(1); + secndflag++; + if (command("%s %s", cmd2, local) != PRELIM) + goto abort; + ptflag++; + (void) getreply(0); + pswitch(0); + (void) getreply(0); +null();// (void) signal(SIGINT, oldintr); + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + pswitch(1); + ptflag = 0; + printf("local: %s remote: %s\n", local, remote); + (void) fflush(stdout); + return; +abort: +null();// (void) signal(SIGINT, SIG_IGN); + ptflag = 0; + if (strcmp(cmd, "RETR") && !proxy) + pswitch(1); + else if (!strcmp(cmd, "RETR") && proxy) + pswitch(0); + if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ + if (command("%s %s", cmd2, local) != PRELIM) { + pswitch(0); + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + if (cpend) { + char msg[2]; + + fprintfSocket(cout,"%c%c",IAC,IP); + *msg = (char) IAC; + *(msg+1) = (char) DM; + if (send(cout,msg,2,MSG_OOB) != 2) + perror("abort"); + fprintfSocket(cout,"ABOR\r\n"); + FD_ZERO(&mask); +// FD_SET(fileno(cin), &mask); // Chris: Need to correct this + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + if (ptabflg) + code = -1; + lostpeer(); + } + (void) getreply(0); + (void) getreply(0); + } + } + pswitch(1); + if (ptabflg) + code = -1; +null();// (void) signal(SIGINT, oldintr); + return; + } + if (cpend) { + char msg[2]; + + fprintfSocket(cout,"%c%c",IAC,IP); + *msg = (char)IAC; + *(msg+1) = (char)DM; + if (send(cout,msg,2,MSG_OOB) != 2) + perror("abort"); + fprintfSocket(cout,"ABOR\r\n"); + FD_ZERO(&mask); +// FD_SET(fileno(cin), &mask); // Chris: Need to correct this... + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + if (ptabflg) + code = -1; + lostpeer(); + } + (void) getreply(0); + (void) getreply(0); + } + pswitch(!proxy); + if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ + if (command("%s %s", cmd2, local) != PRELIM) { + pswitch(0); + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + if (cpend) { + char msg[2]; + + fprintfSocket(cout,"%c%c",IAC,IP); + *msg = (char)IAC; + *(msg+1) = (char)DM; + if (send(cout,msg,2,MSG_OOB) != 2) + perror("abort"); + fprintfSocket(cout,"ABOR\r\n"); + FD_ZERO(&mask); +// FD_SET(fileno(cin), &mask); // Chris: + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + if (ptabflg) + code = -1; + lostpeer(); + } + (void) getreply(0); + (void) getreply(0); + } + pswitch(1); + if (ptabflg) + code = -1; +null();// (void) signal(SIGINT, oldintr); + return; + } + } + if (cpend) { + char msg[2]; + + fprintfSocket(cout,"%c%c",IAC,IP); + *msg = (char)IAC; + *(msg+1) = (char)DM; + if (send(cout,msg,2,MSG_OOB) != 2) + perror("abort"); + fprintfSocket(cout,"ABOR\r\n"); + FD_ZERO(&mask); +// FD_SET(fileno(cin), &mask); // Chris: + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + if (ptabflg) + code = -1; + lostpeer(); + } + (void) getreply(0); + (void) getreply(0); + } + pswitch(!proxy); + if (cpend) { + FD_ZERO(&mask); +// FD_SET(fileno(cin), &mask); // Chris: + if ((nfnd = empty(&mask,10)) <= 0) { + if (nfnd < 0) { + perror("abort"); + } + if (ptabflg) + code = -1; + lostpeer(); + } + (void) getreply(0); + (void) getreply(0); + } + if (proxy) + pswitch(0); + switch (oldtype) { + case 0: + break; + case TYPE_A: + setascii(); + break; + case TYPE_I: + setbinary(); + break; + case TYPE_E: + setebcdic(); + break; + case TYPE_L: + settenex(); + break; + } + pswitch(1); + if (ptabflg) + code = -1; +null();// (void) signal(SIGINT, oldintr); +} + +void reset() +{ +// struct + fd_set mask; + int nfnd = 1; + + FD_ZERO(&mask); + while (nfnd > 0) { +// FD_SET(fileno(cin), &mask); // Chris + if ((nfnd = empty(&mask,0)) < 0) { + perror("reset"); + code = -1; + lostpeer(); + } + else if (nfnd) { + (void) getreply(0); + } + } +} + +char * +gunique(local) + char *local; +{ + static char new[MAXPATHLEN]; + char *cp = rindex(local, '/'); + int d, count=0; + char ext = '1'; + + if (cp) + *cp = '\0'; + d = access(cp ? local : ".", 2); + if (cp) + *cp = '/'; + if (d < 0) { + perror(local); + return((char *) 0); + } + (void) strcpy(new, local); + cp = new + strlen(new); + *cp++ = '.'; + while (!d) { + if (++count == 100) { + printf("runique: can't find unique file name.\n"); + (void) fflush(stdout); + return((char *) 0); + } + *cp++ = ext; + *cp = '\0'; + if (ext == '9') + ext = '0'; + else + ext++; + if ((d = access(new, 0)) < 0) + break; + if (ext != '0') + cp--; + else if (*(cp - 2) == '.') + *(cp - 1) = '1'; + else { + *(cp - 2) = *(cp - 2) + 1; + cp--; + } + } + return(new); +} + +int null(void) +{ + return 0; +} diff --git a/reactos/apps/utils/net/ftp/ftp.mak b/reactos/apps/utils/net/ftp/ftp.mak new file mode 100644 index 00000000000..bdd46b3a39a --- /dev/null +++ b/reactos/apps/utils/net/ftp/ftp.mak @@ -0,0 +1,372 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on ftp.dsp +!IF "$(CFG)" == "" +CFG=ftp - Win32 Debug +!MESSAGE No configuration specified. Defaulting to ftp - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "ftp - Win32 Release" && "$(CFG)" != "ftp - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ftp.mak" CFG="ftp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ftp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ftp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "ftp - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\ftp.exe" + +!ELSE + +ALL : "$(OUTDIR)\ftp.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\cmds.obj" + -@erase "$(INTDIR)\cmdtab.obj" + -@erase "$(INTDIR)\domacro.obj" + -@erase "$(INTDIR)\fake.obj" + -@erase "$(INTDIR)\ftp.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\ruserpass.obj" + -@erase "$(INTDIR)\vc*.idb" + -@erase "$(OUTDIR)\ftp.exe" + -@erase "$(OUTDIR)\ftp.pch" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" \ + /D "HAVE_TIMEVAL" /Fp"$(INTDIR)\ftp.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c +CPP_OBJS=.\Release/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ftp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)\ftp.pdb" /machine:I386 /out:"$(OUTDIR)\ftp.exe" +LINK32_OBJS= \ + "$(INTDIR)\cmds.obj" \ + "$(INTDIR)\cmdtab.obj" \ + "$(INTDIR)\domacro.obj" \ + "$(INTDIR)\fake.obj" \ + "$(INTDIR)\ftp.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\ruserpass.obj" + +"$(OUTDIR)\ftp.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +TargetPath=.\Release\ftp.exe +InputPath=.\Release\ftp.exe +SOURCE=$(InputPath) + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\ftp.exe" + +!ELSE + +ALL : "$(OUTDIR)\ftp.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\cmds.obj" + -@erase "$(INTDIR)\cmdtab.obj" + -@erase "$(INTDIR)\domacro.obj" + -@erase "$(INTDIR)\fake.obj" + -@erase "$(INTDIR)\ftp.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\ruserpass.obj" + -@erase "$(INTDIR)\vc*.idb" + -@erase "$(INTDIR)\vc*.pdb" + -@erase "$(OUTDIR)\ftp.exe" + -@erase "$(OUTDIR)\ftp.ilk" + -@erase "$(OUTDIR)\ftp.pdb" + -@erase "$(OUTDIR)\ftp.pch" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS"\ + /Fp"$(INTDIR)\ftp.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\Debug/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ftp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)\ftp.pdb" /debug /machine:I386 /out:"$(OUTDIR)\ftp.exe"\ + /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\cmds.obj" \ + "$(INTDIR)\cmdtab.obj" \ + "$(INTDIR)\domacro.obj" \ + "$(INTDIR)\fake.obj" \ + "$(INTDIR)\ftp.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\ruserpass.obj" + +"$(OUTDIR)\ftp.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +TargetPath=.\Debug\ftp.exe +InputPath=.\Debug\ftp.exe +SOURCE=$(InputPath) + +!ENDIF + + +!IF "$(CFG)" == "ftp - Win32 Release" || "$(CFG)" == "ftp - Win32 Debug" +SOURCE=.\cmds.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_CMDS_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\pathnames.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\cmds.obj" : $(SOURCE) $(DEP_CPP_CMDS_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_CMDS_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\pathnames.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\cmds.obj" : $(SOURCE) $(DEP_CPP_CMDS_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\cmdtab.c +DEP_CPP_CMDTA=\ + ".\fake.h"\ + ".\ftp_var.h"\ + + +"$(INTDIR)\cmdtab.obj" : $(SOURCE) $(DEP_CPP_CMDTA) "$(INTDIR)" + + +SOURCE=.\domacro.c +DEP_CPP_DOMAC=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\domacro.obj" : $(SOURCE) $(DEP_CPP_DOMAC) "$(INTDIR)" + + +SOURCE=.\fake.c +DEP_CPP_FAKE_=\ + ".\prototypes.h"\ + + +"$(INTDIR)\fake.obj" : $(SOURCE) $(DEP_CPP_FAKE_) "$(INTDIR)" + + +SOURCE=.\ftp.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_FTP_C=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\ftp.obj" : $(SOURCE) $(DEP_CPP_FTP_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_FTP_C=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\ftp.obj" : $(SOURCE) $(DEP_CPP_FTP_C) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\main.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_MAIN_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_MAIN_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ruserpass.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_RUSER=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\ruserpass.obj" : $(SOURCE) $(DEP_CPP_RUSER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_RUSER=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\ruserpass.obj" : $(SOURCE) $(DEP_CPP_RUSER) "$(INTDIR)" + + +!ENDIF + + +!ENDIF diff --git a/reactos/apps/utils/net/ftp/ftp.mak.orig b/reactos/apps/utils/net/ftp/ftp.mak.orig new file mode 100644 index 00000000000..73af13e35ce --- /dev/null +++ b/reactos/apps/utils/net/ftp/ftp.mak.orig @@ -0,0 +1,400 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on ftp.dsp +!IF "$(CFG)" == "" +CFG=ftp - Win32 Debug +!MESSAGE No configuration specified. Defaulting to ftp - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "ftp - Win32 Release" && "$(CFG)" != "ftp - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ftp.mak" CFG="ftp - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ftp - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ftp - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "ftp - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\ftp.exe" "\emacs-19.34\bin\ftp.exe" + +!ELSE + +ALL : "$(OUTDIR)\ftp.exe" "\emacs-19.34\bin\ftp.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\cmds.obj" + -@erase "$(INTDIR)\cmdtab.obj" + -@erase "$(INTDIR)\domacro.obj" + -@erase "$(INTDIR)\fake.obj" + -@erase "$(INTDIR)\ftp.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\ruserpass.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(OUTDIR)\ftp.exe" + -@erase "\emacs-19.34\bin\ftp.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "C:\emacs-19.34\nt\inc" /I\ + "C:\emacs-19.34\src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D\ + "HAVE_TIMEVAL" /Fp"$(INTDIR)\ftp.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c +CPP_OBJS=.\Release/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ftp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)\ftp.pdb" /machine:I386 /out:"$(OUTDIR)\ftp.exe" +LINK32_OBJS= \ + "$(INTDIR)\cmds.obj" \ + "$(INTDIR)\cmdtab.obj" \ + "$(INTDIR)\domacro.obj" \ + "$(INTDIR)\fake.obj" \ + "$(INTDIR)\ftp.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\ruserpass.obj" \ + "d:\Program Files\DevStudio\VC\lib\WSOCK32.LIB" + +"$(OUTDIR)\ftp.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +TargetPath=.\Release\ftp.exe +InputPath=.\Release\ftp.exe +SOURCE=$(InputPath) + +"\emacs-19.34\bin\ftp.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" +# copy $(TargetPath) \emacs-19.34\bin + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\ftp.exe" "\emacs-19.34\bin\ftp.exe" + +!ELSE + +ALL : "$(OUTDIR)\ftp.exe" "\emacs-19.34\bin\ftp.exe" + +!ENDIF + +CLEAN : + -@erase "$(INTDIR)\cmds.obj" + -@erase "$(INTDIR)\cmdtab.obj" + -@erase "$(INTDIR)\domacro.obj" + -@erase "$(INTDIR)\fake.obj" + -@erase "$(INTDIR)\ftp.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\ruserpass.obj" + -@erase "$(INTDIR)\vc50.idb" + -@erase "$(INTDIR)\vc50.pdb" + -@erase "$(OUTDIR)\ftp.exe" + -@erase "$(OUTDIR)\ftp.ilk" + -@erase "$(OUTDIR)\ftp.pdb" + -@erase "\emacs-19.34\bin\ftp.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "C:\emacs-19.34\nt\inc" /I\ + "C:\emacs-19.34\src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS"\ + /Fp"$(INTDIR)\ftp.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=.\Debug/ +CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ftp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)\ftp.pdb" /debug /machine:I386 /out:"$(OUTDIR)\ftp.exe"\ + /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\cmds.obj" \ + "$(INTDIR)\cmdtab.obj" \ + "$(INTDIR)\domacro.obj" \ + "$(INTDIR)\fake.obj" \ + "$(INTDIR)\ftp.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\ruserpass.obj" \ + "d:\Program Files\DevStudio\VC\lib\WSOCK32.LIB" + +"$(OUTDIR)\ftp.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +TargetPath=.\Debug\ftp.exe +InputPath=.\Debug\ftp.exe +SOURCE=$(InputPath) + +"\emacs-19.34\bin\ftp.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" +# copy $(TargetPath) \emacs-19.34\bin + +!ENDIF + + +!IF "$(CFG)" == "ftp - Win32 Release" || "$(CFG)" == "ftp - Win32 Debug" +SOURCE=.\cmds.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_CMDS_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\pathnames.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\cmds.obj" : $(SOURCE) $(DEP_CPP_CMDS_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_CMDS_=\ + "..\..\..\emacs-19.34\nt\inc\netdb.h"\ + "..\..\..\emacs-19.34\nt\inc\netinet\in.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\socket.h"\ + "..\..\..\emacs-19.34\src\nt.h"\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\pathnames.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\cmds.obj" : $(SOURCE) $(DEP_CPP_CMDS_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\cmdtab.c +DEP_CPP_CMDTA=\ + ".\fake.h"\ + ".\ftp_var.h"\ + + +"$(INTDIR)\cmdtab.obj" : $(SOURCE) $(DEP_CPP_CMDTA) "$(INTDIR)" + + +SOURCE=.\domacro.c +DEP_CPP_DOMAC=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\domacro.obj" : $(SOURCE) $(DEP_CPP_DOMAC) "$(INTDIR)" + + +SOURCE=.\fake.c +DEP_CPP_FAKE_=\ + ".\prototypes.h"\ + + +"$(INTDIR)\fake.obj" : $(SOURCE) $(DEP_CPP_FAKE_) "$(INTDIR)" + + +SOURCE=.\ftp.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_FTP_C=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\ftp.obj" : $(SOURCE) $(DEP_CPP_FTP_C) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_FTP_C=\ + "..\..\..\emacs-19.34\nt\inc\netdb.h"\ + "..\..\..\emacs-19.34\nt\inc\netinet\in.h"\ + "..\..\..\emacs-19.34\nt\inc\pwd.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\file.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\ioctl.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\param.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\socket.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\time.h"\ + "..\..\..\emacs-19.34\src\nt.h"\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\ftp.obj" : $(SOURCE) $(DEP_CPP_FTP_C) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\main.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_MAIN_=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_MAIN_=\ + "..\..\..\emacs-19.34\nt\inc\netdb.h"\ + "..\..\..\emacs-19.34\nt\inc\pwd.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\ioctl.h"\ + "..\..\..\emacs-19.34\nt\inc\sys\socket.h"\ + "..\..\..\emacs-19.34\src\nt.h"\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ruserpass.c + +!IF "$(CFG)" == "ftp - Win32 Release" + +DEP_CPP_RUSER=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + + +"$(INTDIR)\ruserpass.obj" : $(SOURCE) $(DEP_CPP_RUSER) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ftp - Win32 Debug" + +DEP_CPP_RUSER=\ + ".\fake.h"\ + ".\ftp_var.h"\ + ".\prototypes.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + + +"$(INTDIR)\ruserpass.obj" : $(SOURCE) $(DEP_CPP_RUSER) "$(INTDIR)" + + +!ENDIF + + +!ENDIF diff --git a/reactos/apps/utils/net/ftp/ftp.rc b/reactos/apps/utils/net/ftp/ftp.rc new file mode 100644 index 00000000000..505a9fe9d25 --- /dev/null +++ b/reactos/apps/utils/net/ftp/ftp.rc @@ -0,0 +1,6 @@ +/* $Id: route.rc 11816 2004-11-26 06:51:47Z arty $ */ + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 FTP Client\0" +#define REACTOS_STR_INTERNAL_NAME "ftp\0" +#define REACTOS_STR_ORIGINAL_FILENAME "ftp.exe\0" +#include diff --git a/reactos/apps/utils/net/ftp/ftp_var.h b/reactos/apps/utils/net/ftp/ftp_var.h new file mode 100644 index 00000000000..b5da7a7470d --- /dev/null +++ b/reactos/apps/utils/net/ftp/ftp_var.h @@ -0,0 +1,181 @@ +#include "fake.h" +#include +#include + +//typedef void (*Sig_t)(int); + +int fgetcSocket(int s); +char *fputsSocket(char *format, int s); + +char *fprintfSocket(int s, char *format, ...); + +int fputcSocket(int s, char putChar); +int fputSocket(int s, char *putChar, int len); +char *fgetsSocket(int s, char *string); + +/* The following defines are from ftp.h and telnet.h from bsd.h */ +/* All relevent copyrights below apply. */ + +#define IAC 255 +#define DONT 254 +#define DO 253 +#define WONT 252 +#define WILL 251 +#define SB 250 +#define GA 249 +#define EL 248 +#define EC 247 +#define AYT 246 +#define AO 245 +#define IP 244 +#define BREAK 243 +#define DM 242 +#define NOP 241 +#define SE 240 +#define EOR 239 +#define ABORT 238 +#define SUSP 237 +#define xEOF 236 + + +#define MAXPATHLEN 255 +#define TYPE_A 'A' +#define TYPE_I 'I' +#define TYPE_E 'E' +#define TYPE_L 'L' + +#define PRELIM 1 +#define COMPLETE 2 +#define CONTINUE 3 +#define TRANSIENT 4 + +#define MODE_S 1 +#define MODE_B 2 +#define MODE_C 3 + +#define STRU_F 1 +#define STRU_R 2 +#define STRU_P 3 + +#define SIGQUIT 1 +#define SIGPIPE 2 +#define SIGALRM 3 + + +#define FORM_N 1 +#define FORM_T 2 +#define FORM_C 3 + + +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ftp_var.h 5.5 (Berkeley) 6/29/88 + */ + +/* + * FTP global variables. + */ + +/* + * Options and other state info. + */ +extern int trace; /* trace packets exchanged */ +extern int hash; /* print # for each buffer transferred */ +extern int sendport; /* use PORT cmd for each data connection */ +extern int verbose; /* print messages coming back from server */ +extern int connected; /* connected to server */ +extern int fromatty; /* input is from a terminal */ +extern int interactive; /* interactively prompt on m* cmds */ +extern int debug; /* debugging level */ +extern int bell; /* ring bell on cmd completion */ +extern int doglob; /* glob local file names */ +extern int proxy; /* proxy server connection active */ +extern int proxflag; /* proxy connection exists */ +extern int sunique; /* store files on server with unique name */ +extern int runique; /* store local files with unique name */ +extern int mcase; /* map upper to lower case for mget names */ +extern int ntflag; /* use ntin ntout tables for name translation */ +extern int mapflag; /* use mapin mapout templates on file names */ +extern int code; /* return/reply code for ftp command */ +extern int crflag; /* if 1, strip car. rets. on ascii gets */ +extern char pasv[64]; /* passive port for proxy data connection */ +extern int passivemode; /* passive mode enabled */ +extern char *altarg; /* argv[1] with no shell-like preprocessing */ +extern char ntin[17]; /* input translation table */ +extern char ntout[17]; /* output translation table */ + +extern char mapin[MAXPATHLEN]; /* input map template */ +extern char mapout[MAXPATHLEN]; /* output map template */ +extern char typename[32]; /* name of file transfer type */ +extern int type; /* file transfer type */ +extern char structname[32]; /* name of file transfer structure */ +extern int stru; /* file transfer structure */ +extern char formname[32]; /* name of file transfer format */ +extern int form; /* file transfer format */ +extern char modename[32]; /* name of file transfer mode */ +extern int mode; /* file transfer mode */ +extern char bytename[32]; /* local byte size in ascii */ +extern int bytesize; /* local byte size in binary */ + +extern jmp_buf toplevel; /* non-local goto stuff for cmd scanner */ + +extern char line[200]; /* input line buffer */ +extern char *stringbase; /* current scan point in line buffer */ +extern char argbuf[200]; /* argument storage buffer */ +extern char *argbase; /* current storage point in arg buffer */ +extern int margc; /* count of arguments on input line */ +extern char *margv[20]; /* args parsed from input line */ +extern int cpend; /* flag: if != 0, then pending server reply */ +extern int mflag; /* flag: if != 0, then active multi command */ + +extern int options; /* used during socket creation */ + +/* + * Format of command table. + */ +struct cmd { + char *c_name; /* name of command */ + char *c_help; /* help string */ + char c_bell; /* give bell when command completes */ + char c_conn; /* must be connected to use command */ + char c_proxy; /* proxy server may execute */ + int (*c_handler)(); /* function to call */ +}; + +struct macel { + char mac_name[9]; /* macro name */ + char *mac_start; /* start of macro in macbuf */ + char *mac_end; /* end of macro in macbuf */ +}; + +int macnum; /* number of defined macros */ +struct macel macros[16]; +char macbuf[4096]; + +extern char *tail(); +extern char *remglob(); +extern int errno; +extern char *mktemp(); + +#if defined(__ANSI__) || defined(sparc) +typedef void sig_t; +#else +typedef int sig_t; +#endif + +typedef int uid_t; +int herror(char *s); diff --git a/reactos/apps/utils/net/ftp/main.c b/reactos/apps/utils/net/ftp/main.c new file mode 100644 index 00000000000..409c5c6d342 --- /dev/null +++ b/reactos/apps/utils/net/ftp/main.c @@ -0,0 +1,602 @@ +/* + * Copyright (c) 1985, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c based on 5.13 (Berkeley) 3/14/89"; +#endif /* not lint */ + +/* + * FTP User Program -- Command Interface. + */ +#if !defined(WIN32) +#include +#include +#include +#include +#include +#include +#endif +#include "ftp_var.h" +#include "prototypes.h" +#include + +#include +#include + +#include +#include +#include +#include + + +#if defined(sun) && !defined(FD_SET) +typedef int uid_t; +#endif + +uid_t getuid(); +void intr(); +void lostpeer(); +char *getlogin(); + +short portnum; + +char home[128]; +char *globerr; +int autologin; + + + +/* Lot's of options... */ +/* + * Options and other state info. + */ +int trace; /* trace packets exchanged */ +int hash; /* print # for each buffer transferred */ +int sendport; /* use PORT cmd for each data connection */ +int verbose; /* print messages coming back from server */ +int connected; /* connected to server */ +int fromatty; /* input is from a terminal */ +int interactive; /* interactively prompt on m* cmds */ +int debug; /* debugging level */ +int bell; /* ring bell on cmd completion */ +int doglob; /* glob local file names */ +int proxy; /* proxy server connection active */ +int passivemode; +int proxflag; /* proxy connection exists */ +int sunique; /* store files on server with unique name */ +int runique; /* store local files with unique name */ +int mcase; /* map upper to lower case for mget names */ +int ntflag; /* use ntin ntout tables for name translation */ +int mapflag; /* use mapin mapout templates on file names */ +int code; /* return/reply code for ftp command */ +int crflag; /* if 1, strip car. rets. on ascii gets */ +char pasv[64]; /* passive port for proxy data connection */ +char *altarg; /* argv[1] with no shell-like preprocessing */ +char ntin[17]; /* input translation table */ +char ntout[17]; /* output translation table */ +// #include +char mapin[MAXPATHLEN]; /* input map template */ +char mapout[MAXPATHLEN]; /* output map template */ +char typename[32]; /* name of file transfer type */ +int type; /* file transfer type */ +char structname[32]; /* name of file transfer structure */ +int stru; /* file transfer structure */ +char formname[32]; /* name of file transfer format */ +int form; /* file transfer format */ +char modename[32]; /* name of file transfer mode */ +int mode; /* file transfer mode */ +char bytename[32]; /* local byte size in ascii */ +int bytesize; /* local byte size in binary */ + +jmp_buf toplevel; /* non-local goto stuff for cmd scanner */ + +char line[200]; /* input line buffer */ +char *stringbase; /* current scan point in line buffer */ +char argbuf[200]; /* argument storage buffer */ +char *argbase; /* current storage point in arg buffer */ +int margc; /* count of arguments on input line */ +char *margv[20]; /* args parsed from input line */ +int cpend; /* flag: if != 0, then pending server reply */ +int mflag; /* flag: if != 0, then active multi command */ + +int options; /* used during socket creation */ + + + +int main(int argc, char *argv[]) +{ + register char *cp; + int top; + struct passwd *pw = NULL; +#if 0 + char homedir[MAXPATHLEN]; +#endif + + int err; + WORD wVerReq; + + WSADATA WSAData; + struct servent *sp; /* service spec for tcp/ftp */ + + /* Disable output buffering, for the benefit of Emacs. */ + //setbuf(stdout, NULL); + + _fmode = O_BINARY; // This causes an error somewhere. + + wVerReq = MAKEWORD(1,1); + + err = WSAStartup(wVerReq, &WSAData); + if (err != 0) + { + fprintf(stderr, "Could not initialize Windows socket interface."); + exit(1); + } + + sp = getservbyname("ftp", "tcp"); + if (sp == 0) { + fprintf(stderr, "ftp: ftp/tcp: unknown service\n"); + exit(1); + } + + portnum = sp->s_port; + + + doglob = 1; + interactive = 1; + autologin = 1; + argc--, argv++; + while (argc > 0 && **argv == '-') { + for (cp = *argv + 1; *cp; cp++) + switch (*cp) { + + case 'd': + options |= SO_DEBUG; + debug++; + break; + + case 'v': + verbose++; + break; + + case 't': + trace++; + break; + + case 'i': + interactive = 0; + break; + + case 'n': + autologin = 0; + break; + + case 'g': + doglob = 0; + break; + + default: + fprintf(stdout, + "ftp: %c: unknown option\n", *cp); + exit(1); + } + argc--, argv++; + } +// fromatty = isatty(fileno(stdin)); + fromatty = 1; // Strengthen this test + /* + * Set up defaults for FTP. + */ + (void) strcpy(typename, "ascii"), type = TYPE_A; + (void) strcpy(formname, "non-print"), form = FORM_N; + (void) strcpy(modename, "stream"), mode = MODE_S; + (void) strcpy(structname, "file"), stru = STRU_F; + (void) strcpy(bytename, "8"), bytesize = 8; + if (fromatty) + verbose++; + cpend = 0; /* no pending replies */ + proxy = 0; /* proxy not active */ + passivemode = 1; /* passive mode *is* active */ + crflag = 1; /* strip c.r. on ascii gets */ + /* + * Set up the home directory in case we're globbing. + */ +#if 0 + cp = getlogin(); + if (cp != NULL) { + pw = getpwnam(cp); + } + if (pw == NULL) + pw = getpwuid(getuid()); + if (pw != NULL) { + home = homedir; + (void) strcpy(home, pw->pw_dir); + } +#endif + strcpy(home, "C:/"); + if (argc > 0) { + if (setjmp(toplevel)) + exit(0); +// (void) signal(SIGINT, intr); +// (void) signal(SIGPIPE, lostpeer); + setpeer(argc + 1, argv - 1); + } + top = setjmp(toplevel) == 0; + if (top) { +// (void) signal(SIGINT, intr); +// (void) signal(SIGPIPE, lostpeer); + } + for (;;) { + cmdscanner(top); + top = 1; + } +} + +void +intr() +{ + + longjmp(toplevel, 1); +} + +void lostpeer(void) +{ + extern int cout; + extern int data; + + if (connected) { + if (cout != (int) NULL) { + closesocket(cout); + cout = (int) NULL; + } + if (data >= 0) { + (void) shutdown(data, 1+1); + (void) close(data); + data = -1; + } + connected = 0; + } + pswitch(1); + if (connected) { + if (cout != (int)NULL) { + closesocket(cout); + cout = (int) NULL; + } + connected = 0; + } + proxflag = 0; + pswitch(0); +} + +/*char * +tail(filename) + char *filename; +{ + register char *s; + + while (*filename) { + s = rindex(filename, '/'); + if (s == NULL) + break; + if (s[1]) + return (s + 1); + *s = '\0'; + } + return (filename); +} +*/ +/* + * Command parser. + */ +void cmdscanner(top) + int top; +{ + register struct cmd *c; + struct cmd *getcmd(); + extern int help(); + + if (!top) + (void) putchar('\n'); + for (;;) { + (void) fflush(stdout); + if (fromatty) { + printf("ftp> "); + (void) fflush(stdout); + } + if (gets(line) == 0) { + if (feof(stdin) || ferror(stdin)) + quit(); + break; + } + if (line[0] == 0) + break; + makeargv(); + if (margc == 0) { + continue; + } + c = getcmd(margv[0]); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + continue; + } + if (c == 0) { + printf("?Invalid command\n"); + continue; + } + if (c->c_conn && !connected) { + printf ("Not connected.\n"); + continue; + } + (*c->c_handler)(margc, margv); + if (bell && c->c_bell) + (void) putchar('\007'); + if (c->c_handler != help) + break; + } + (void) fflush(stdout); +// (void) signal(SIGINT, intr); +// (void) signal(SIGPIPE, lostpeer); +} + +struct cmd * +getcmd(name) + register char *name; +{ + extern struct cmd cmdtab[]; + register char *p, *q; + register struct cmd *c, *found; + register int nmatches, longest; + + longest = 0; + nmatches = 0; + found = 0; + for (c = cmdtab; p = c->c_name; c++) { + for (q = name; *q == *p++; q++) + if (*q == 0) /* exact match? */ + return (c); + if (!*q) { /* the name was a prefix */ + if (q - name > longest) { + longest = q - name; + nmatches = 1; + found = c; + } else if (q - name == longest) + nmatches++; + } + } + if (nmatches > 1) + return ((struct cmd *)-1); + return (found); +} + +/* + * Slice a string up into argc/argv. + */ + +int slrflag; + +void makeargv() +{ + char **argp; + char *slurpstring(); + + margc = 0; + argp = margv; + stringbase = line; /* scan from first of buffer */ + argbase = argbuf; /* store from first of buffer */ + slrflag = 0; + while (*argp++ = slurpstring()) + margc++; +} + +/* + * Parse string into argbuf; + * implemented with FSM to + * handle quoting and strings + */ +char * +slurpstring() +{ + int got_one = 0; + register char *sb = stringbase; + register char *ap = argbase; + char *tmp = argbase; /* will return this if token found */ + + if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */ + switch (slrflag) { /* and $ as token for macro invoke */ + case 0: + slrflag++; + stringbase++; + return ((*sb == '!') ? "!" : "$"); + /* NOTREACHED */ + case 1: + slrflag++; + altarg = stringbase; + break; + default: + break; + } + } + +S0: + switch (*sb) { + + case '\0': + goto OUT1; + + case ' ': + case '\t': + sb++; goto S0; + + default: + switch (slrflag) { + case 0: + slrflag++; + break; + case 1: + slrflag++; + altarg = sb; + break; + default: + break; + } + goto S1; + } + +S1: + switch (*sb) { + + case ' ': + case '\t': + case '\0': + goto OUT1; /* end of token */ + + case '\\': + sb++; goto S2; /* slurp next character */ + + case '"': + sb++; goto S3; /* slurp quoted string */ + + default: + *ap++ = *sb++; /* add character to token */ + got_one = 1; + goto S1; + } + +S2: + switch (*sb) { + + case '\0': + goto OUT1; + + default: + *ap++ = *sb++; + got_one = 1; + goto S1; + } + +S3: + switch (*sb) { + + case '\0': + goto OUT1; + + case '"': + sb++; goto S1; + + default: + *ap++ = *sb++; + got_one = 1; + goto S3; + } + +OUT1: + if (got_one) + *ap++ = '\0'; + argbase = ap; /* update storage pointer */ + stringbase = sb; /* update scan pointer */ + if (got_one) { + return(tmp); + } + switch (slrflag) { + case 0: + slrflag++; + break; + case 1: + slrflag++; + altarg = (char *) 0; + break; + default: + break; + } + return((char *)0); +} + +#define HELPINDENT (sizeof ("directory")) + +/* + * Help command. + * Call each command handler with argc == 0 and argv[0] == name. + */ +int help(argc, argv) + int argc; + char *argv[]; +{ + extern struct cmd cmdtab[]; + register struct cmd *c; + + if (argc == 1) { + register int i, j, w, k; + int columns, width = 0, lines; + extern int NCMDS; + + printf("Commands may be abbreviated. Commands are:\n\n"); + for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { + int len = strlen(c->c_name); + + if (len > width) + width = len; + } + width = (width + 8) &~ 7; + columns = 80 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + for (j = 0; j < columns; j++) { + c = cmdtab + j * lines + i; + if (c->c_name && (!proxy || c->c_proxy)) { + printf("%s", c->c_name); + } + else if (c->c_name) { + for (k=0; k < (int) strlen(c->c_name); k++) { + (void) putchar(' '); + } + } + if (c + lines >= &cmdtab[NCMDS]) { + printf("\n"); + break; + } + w = strlen(c->c_name); + while (w < width) { + w = (w + 8) &~ 7; + (void) putchar('\t'); + } + } + } + (void) fflush(stdout); + return 0; + } + while (--argc > 0) { + register char *arg; + arg = *++argv; + c = getcmd(arg); + if (c == (struct cmd *)-1) + printf("?Ambiguous help command %s\n", arg); + else if (c == (struct cmd *)0) + printf("?Invalid help command %s\n", arg); + else + printf("%-*s\t%s\n", HELPINDENT, + c->c_name, c->c_help); + } + (void) fflush(stdout); + return 0; +} diff --git a/reactos/apps/utils/net/ftp/makefile b/reactos/apps/utils/net/ftp/makefile new file mode 100644 index 00000000000..703bb2b0170 --- /dev/null +++ b/reactos/apps/utils/net/ftp/makefile @@ -0,0 +1,26 @@ +PATH_TO_TOP = ../../../.. + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = ftp + +TARGET_INSTALLDIR = system32 + +TARGET_SDKLIBS = ws2_32.a iphlpapi.a ntdll.a + +TARGET_OBJECTS = \ + cmds.o \ + cmdtab.o \ + domacro.o \ + fake.o \ + ftp.o \ + main.o \ + ruserpass.o + +TARGET_GCCLIBS = + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/reactos/apps/utils/net/ftp/pathnames.h b/reactos/apps/utils/net/ftp/pathnames.h new file mode 100644 index 00000000000..676aa507daf --- /dev/null +++ b/reactos/apps/utils/net/ftp/pathnames.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * %W% (Berkeley) %G% + */ + +#define _PATH_TMP "/tmp/ftpXXXXXX" +#define _PATH_BSHELL "/bin/sh" diff --git a/reactos/apps/utils/net/ftp/prototypes.h b/reactos/apps/utils/net/ftp/prototypes.h new file mode 100644 index 00000000000..9bc9509fa6b --- /dev/null +++ b/reactos/apps/utils/net/ftp/prototypes.h @@ -0,0 +1,79 @@ + +int getreply(int expecteof); +int ruserpass(char *host, char **aname, char **apass, char **aacct); +char *getpass(const char *prompt); +void makeargv(void); +void domacro(int argc, char *argv[]); +void proxtrans(char *cmd, char *local, char *remote); +int null(void); +int initconn(void); +void disconnect(void); +void ptransfer(char *direction, long bytes, struct timeval *t0, struct timeval *t1); +void setascii(void); +void setbinary(void); +void setebcdic(void); +void settenex(void); +void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +void setpassive(int argc, char *argv[]); +void setpeer(int argc, char *argv[]); +void cmdscanner(int top); +void pswitch(int flag); +void quit(void); +int login(char *host); +int command(char *fmt, ...); +int globulize(char **cpp); +void sendrequest(char *cmd, char *local, char *remote, int printnames); +void recvrequest(char *cmd, char *local, char *remote, char *mode, + int printnames); +int confirm(char *cmd, char *file); +void blkfree(char **av0); +int getit(int argc, char *argv[], int restartit, char *mode); +static int token(void); +int sleep(int time); + +#include +#include + +#ifndef __GNUC__ +#define EPOCHFILETIME (116444736000000000i64) +#else +#define EPOCHFILETIME (116444736000000000LL) +#endif + +struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +__inline int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + static int tzflag; + + if (tv) + { + GetSystemTimeAsFileTime(&ft); + //li.LowPart = ft.dwLowDateTime; + //li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + tv->tv_sec = (long)(t / 1000000); + tv->tv_usec = (long)(t % 1000000); + } + + if (tz) + { + if (!tzflag) + { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} diff --git a/reactos/apps/utils/net/ftp/ruserpass.c b/reactos/apps/utils/net/ftp/ruserpass.c new file mode 100644 index 00000000000..e8fec046175 --- /dev/null +++ b/reactos/apps/utils/net/ftp/ruserpass.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char sccsid[] = "@(#)ruserpass.c 5.1 (Berkeley) 3/1/89"; +#endif /* not lint */ + +#include +#include +//#include +#include +#include +#include +#include "ftp_var.h" +#include "prototypes.h" +#include + +char *renvlook(), *index(), *getenv(), *getpass(), *getlogin(); +void *malloc(); +char *strcpy(); +struct utmp *getutmp(); +static FILE *cfile; + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#define DEFAULT 1 +#define LOGIN 2 +#define PASSWD 3 +#define ACCOUNT 4 +#define MACDEF 5 +#define ID 10 +#define MACH 11 + +static char tokval[100]; + +static struct toktab { + char *tokstr; + int tval; +} toktab[]= { + "default", DEFAULT, + "login", LOGIN, + "password", PASSWD, + "passwd", PASSWD, + "account", ACCOUNT, + "machine", MACH, + "macdef", MACDEF, + 0, 0 +}; + +extern char *hostname; + +int ruserpass(char *host, char **aname, char **apass, char **aacct) +{ + char *hdir, buf[BUFSIZ], *tmp; + char myname[MAXHOSTNAMELEN], *mydomain; + int t, i, c, usedefault = 0; + struct stat stb; + extern int errno; + + hdir = getenv("HOME"); + if (hdir == NULL) + hdir = "."; + (void) sprintf(buf, "%s/.netrc", hdir); + cfile = fopen(buf, "r"); + if (cfile == NULL) { + if (errno != ENOENT) + perror(buf); + return(0); + } + + + if (gethostname(myname, sizeof(myname)) < 0) + myname[0] = '\0'; + if ((mydomain = index(myname, '.')) == NULL) + mydomain = ""; +next: + while ((t = token())) switch(t) { + + case DEFAULT: + usedefault = 1; + /* FALL THROUGH */ + + case MACH: + if (!usedefault) { + if (token() != ID) + continue; + /* + * Allow match either for user's input host name + * or official hostname. Also allow match of + * incompletely-specified host in local domain. + */ + if (strcasecmp(host, tokval) == 0) + goto match; + if (strcasecmp(hostname, tokval) == 0) + goto match; + if ((tmp = index(hostname, '.')) != NULL && + strcasecmp(tmp, mydomain) == 0 && + strncasecmp(hostname, tokval, tmp - hostname) == 0 && + tokval[tmp - hostname] == '\0') + goto match; + if ((tmp = index(host, '.')) != NULL && + strcasecmp(tmp, mydomain) == 0 && + strncasecmp(host, tokval, tmp - host) == 0 && + tokval[tmp - host] == '\0') + goto match; + continue; + } + match: + while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { + + case LOGIN: + if (token()) + if (*aname == 0) { + *aname = malloc((unsigned) strlen(tokval) + 1); + (void) strcpy(*aname, tokval); + } else { + if (strcmp(*aname, tokval)) + goto next; + } + break; + case PASSWD: + if (strcmp(*aname, "anonymous") && + fstat(fileno(cfile), &stb) >= 0 && + (stb.st_mode & 077) != 0) { + fprintf(stderr, "Error - .netrc file not correct mode.\n"); + fprintf(stderr, "Remove password or correct mode.\n"); + goto bad; + } + if (token() && *apass == 0) { + *apass = malloc((unsigned) strlen(tokval) + 1); + (void) strcpy(*apass, tokval); + } + break; + case ACCOUNT: + if (fstat(fileno(cfile), &stb) >= 0 + && (stb.st_mode & 077) != 0) { + fprintf(stderr, "Error - .netrc file not correct mode.\n"); + fprintf(stderr, "Remove account or correct mode.\n"); + goto bad; + } + if (token() && *aacct == 0) { + *aacct = malloc((unsigned) strlen(tokval) + 1); + (void) strcpy(*aacct, tokval); + } + break; + case MACDEF: + if (proxy) { + (void) fclose(cfile); + return(0); + } + while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t'); + if (c == EOF || c == '\n') { + printf("Missing macdef name argument.\n"); + goto bad; + } + if (macnum == 16) { + printf("Limit of 16 macros have already been defined\n"); + goto bad; + } + tmp = macros[macnum].mac_name; + *tmp++ = c; + for (i=0; i < 8 && (c=getc(cfile)) != EOF && + !isspace(c); ++i) { + *tmp++ = c; + } + if (c == EOF) { + printf("Macro definition missing null line terminator.\n"); + goto bad; + } + *tmp = '\0'; + if (c != '\n') { + while ((c=getc(cfile)) != EOF && c != '\n'); + } + if (c == EOF) { + printf("Macro definition missing null line terminator.\n"); + goto bad; + } + if (macnum == 0) { + macros[macnum].mac_start = macbuf; + } + else { + macros[macnum].mac_start = macros[macnum-1].mac_end + 1; + } + tmp = macros[macnum].mac_start; + while (tmp != macbuf + 4096) { + if ((c=getc(cfile)) == EOF) { + printf("Macro definition missing null line terminator.\n"); + goto bad; + } + *tmp = c; + if (*tmp == '\n') { + if (*(tmp-1) == '\0') { + macros[macnum++].mac_end = tmp - 1; + break; + } + *tmp = '\0'; + } + tmp++; + } + if (tmp == macbuf + 4096) { + printf("4K macro buffer exceeded\n"); + goto bad; + } + break; + default: + fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); + break; + } + goto done; + } +done: + (void) fclose(cfile); + return(0); +bad: + (void) fclose(cfile); + return(-1); +} + +static int token(void) +{ + char *cp; + int c; + struct toktab *t; + + if (feof(cfile)) + return (0); + while ((c = getc(cfile)) != EOF && + (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ',')) + continue; + if (c == EOF) + return (0); + cp = tokval; + if (c == '"') { + while ((c = getc(cfile)) != EOF && c != '"') { + if (c == '\\') + c = getc(cfile); + *cp++ = c; + } + } else { + *cp++ = c; + while ((c = getc(cfile)) != EOF + && c != '\n' && c != '\t' && c != ' ' && c != ',' && c != '\r') { + if (c == '\\') + c = getc(cfile); + *cp++ = c; + } + } + *cp = 0; + if (tokval[0] == 0) + return (0); + for (t = toktab; t->tokstr; t++) + if (!strcmp(t->tokstr, tokval)) + return (t->tval); + return (ID); +}