added a port of netkit ftp.exe Added: trunk/reactos/apps/utils/net/ftp/ Added: trunk/reactos/apps/utils/net/ftp/cmds.c Added: trunk/reactos/apps/utils/net/ftp/cmdtab.c Added: trunk/reactos/apps/utils/net/ftp/domacro.c Added: trunk/reactos/apps/utils/net/ftp/fake.c Added: trunk/reactos/apps/utils/net/ftp/fake.h Added: trunk/reactos/apps/utils/net/ftp/ftp.c Added: trunk/reactos/apps/utils/net/ftp/ftp.mak Added: trunk/reactos/apps/utils/net/ftp/ftp.mak.orig Added: trunk/reactos/apps/utils/net/ftp/ftp.rc Added: trunk/reactos/apps/utils/net/ftp/ftp_var.h Added: trunk/reactos/apps/utils/net/ftp/main.c Added: trunk/reactos/apps/utils/net/ftp/makefile Added: trunk/reactos/apps/utils/net/ftp/pathnames.h Added: trunk/reactos/apps/utils/net/ftp/prototypes.h Added: trunk/reactos/apps/utils/net/ftp/ruserpass.c _____
Added: trunk/reactos/apps/utils/net/ftp/cmds.c --- trunk/reactos/apps/utils/net/ftp/cmds.c 2005-01-04 03:10:07 UTC (rev 12775) +++ trunk/reactos/apps/utils/net/ftp/cmds.c 2005-01-04 04:03:57 UTC (rev 12776) @@ -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 <sys/param.h> +//#include <sys/wait.h> +#include <sys/stat.h> +#if !defined(WIN32) +#include <sys/socket.h> +#include <arpa/ftp.h> +#include <netinet/in.h> +#include <netdb.h> +#else +#include <winsock.h> +#endif + +#include <signal.h> +#include <direct.h> +#include <stdio.h> +#include <errno.h> +#include <ctype.h> +#include <time.h> + +#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<macnum; i++) { + printf("\t%s\n",macros[i].mac_name); + } + } + (void) fflush(stdout); + code = 0; +} + +/* + * Set beep on cmd completed mode. + */ +/*VARARGS*/ +void setbell() +{ + + bell = !bell; + printf("Bell mode %s.\n", onoff(bell)); + (void) fflush(stdout); + code = bell; +} + +/* + * Turn on packet tracing. + */ +/*VARARGS*/ +void settrace() +{ + + trace = !trace; + printf("Packet tracing %s.\n", onoff(trace)); + (void) fflush(stdout); + code = trace; +} + +/* + * Toggle hash mark printing during transfers. + */ +/*VARARGS*/ +void sethash() +{ + + hash = !hash; + printf("Hash mark printing %s", onoff(hash)); + code = hash; + if (hash) + printf(" (%d bytes/hash mark)", 1024); + printf(".\n"); + (void) fflush(stdout); +} + +/* + * Turn on printing of server echo's. + */ +/*VARARGS*/ +void setverbose() +{ + + verbose = !verbose; + printf("Verbose mode %s.\n", onoff(verbose)); + (void) fflush(stdout); + code = verbose; +} + +/* + * Toggle PORT cmd use before each data connection. + */ +/*VARARGS*/ +void setport() +{ + + sendport = !sendport; + printf("Use of PORT cmds %s.\n", onoff(sendport)); + (void) fflush(stdout); + code = sendport; +} + +/* + * Turn on interactive prompting + * during mget, mput, and mdelete. + */ +/*VARARGS*/ +void setprompt() +{ + + interactive = !interactive; + printf("Interactive mode %s.\n", onoff(interactive)); + (void) fflush(stdout); + code = interactive; +} + +/* + * Toggle metacharacter interpretation + * on local file names. + */ +/*VARARGS*/ +void setglob() +{ + + doglob = !doglob; + printf("Globbing %s.\n", onoff(doglob)); + (void) fflush(stdout); + code = doglob; +} + +/* + * Set debugging mode on/off and/or + * set level of debugging. + */ +/*VARARGS*/ +void setdebug(argc, argv) + char *argv[]; +{ + int val; + + if (argc > 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; [truncated at 1000 lines; 5858 more skipped]