ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

main.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1985, 1989 Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms are permitted
00006  * provided that the above copyright notice and this paragraph are
00007  * duplicated in all such forms and that any documentation,
00008  * advertising materials, and other materials related to such
00009  * distribution and use acknowledge that the software was developed
00010  * by the University of California, Berkeley.  The name of the
00011  * University may not be used to endorse or promote products derived
00012  * from this software without specific prior written permission.
00013  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00014  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00015  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00016  */
00017 
00018 #ifndef lint
00019 char copyright[] =
00020 "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
00021  All rights reserved.\n";
00022 #endif /* not lint */
00023 
00024 #ifndef lint
00025 static char sccsid[] = "@(#)main.c  based on 5.13 (Berkeley) 3/14/89";
00026 #endif /* not lint */
00027 
00028 /*
00029  * FTP User Program -- Command Interface.
00030  */
00031 #include "precomp.h"
00032 
00033 #if defined(sun) && !defined(FD_SET)
00034 typedef int uid_t;
00035 #endif
00036 
00037 uid_t   getuid(void);
00038 void    intr(void);
00039 void    lostpeer(void);
00040 char    *getlogin(void);
00041 
00042 short   portnum;
00043 
00044 char    home[128];
00045 char    *globerr;
00046 int autologin;
00047 
00048 
00049 
00050 /* Lot's of options... */
00051 /*
00052  * Options and other state info.
00053  */
00054 int trace;          /* trace packets exchanged */
00055 int hash;           /* print # for each buffer transferred */
00056 //int   sendport;       /* use PORT cmd for each data connection */
00057 int verbose;        /* print messages coming back from server */
00058 int connected;      /* connected to server */
00059 int fromatty;       /* input is from a terminal */
00060 int interactive;        /* interactively prompt on m* cmds */
00061 int debug;          /* debugging level */
00062 int bell;           /* ring bell on cmd completion */
00063 int doglob;         /* glob local file names */
00064 int proxy;          /* proxy server connection active */
00065 int passivemode;
00066 int proxflag;       /* proxy connection exists */
00067 int sunique;        /* store files on server with unique name */
00068 int runique;        /* store local files with unique name */
00069 int mcase;          /* map upper to lower case for mget names */
00070 int ntflag;         /* use ntin ntout tables for name translation */
00071 int mapflag;        /* use mapin mapout templates on file names */
00072 int code;           /* return/reply code for ftp command */
00073 int crflag;         /* if 1, strip car. rets. on ascii gets */
00074 char    pasv[64];       /* passive port for proxy data connection */
00075 char    *altarg;        /* argv[1] with no shell-like preprocessing  */
00076 char    ntin[17];       /* input translation table */
00077 char    ntout[17];      /* output translation table */
00078 // #include <sys/param.h>
00079 char    mapin[MAXPATHLEN];  /* input map template */
00080 char    mapout[MAXPATHLEN]; /* output map template */
00081 char    typename[32];       /* name of file transfer type */
00082 int type;           /* file transfer type */
00083 char    structname[32];     /* name of file transfer structure */
00084 int stru;           /* file transfer structure */
00085 char    formname[32];       /* name of file transfer format */
00086 int form;           /* file transfer format */
00087 char    modename[32];       /* name of file transfer mode */
00088 int mode;           /* file transfer mode */
00089 char    bytename[32];       /* local byte size in ascii */
00090 int bytesize;       /* local byte size in binary */
00091 
00092 jmp_buf toplevel;       /* non-local goto stuff for cmd scanner */
00093 
00094 char    line[200];      /* input line buffer */
00095 char    *stringbase;        /* current scan point in line buffer */
00096 char    argbuf[200];        /* argument storage buffer */
00097 char    *argbase;       /* current storage point in arg buffer */
00098 int margc;          /* count of arguments on input line */
00099 const char  *margv[20]; /* args parsed from input line */
00100 int cpend;          /* flag: if != 0, then pending server reply */
00101 int mflag;          /* flag: if != 0, then active multi command */
00102 
00103 int options;        /* used during socket creation */
00104 
00105 int macnum;         /* number of defined macros */
00106 struct  macel macros[16];
00107 char    macbuf[4096];
00108 
00109 /* 
00110  * Need to start a listen on the data channel 
00111  * before we send the command, otherwise the 
00112  * server's connect may fail. 
00113  */
00114 int sendport = -1;
00115 
00116 static const char *slurpstring();
00117 
00118 
00119 int main(int argc, const char *argv[])
00120 {
00121     const char *cp;
00122     int top;
00123 #if 0
00124     char homedir[MAXPATHLEN];
00125 #endif
00126 
00127         int err;
00128         WORD wVerReq;
00129 
00130         WSADATA WSAData;
00131         struct  servent *sp;        /* service spec for tcp/ftp */
00132 
00133     /* Disable output buffering, for the benefit of Emacs.  */
00134     //setbuf(stdout, NULL);
00135 
00136         _fmode = O_BINARY; // This causes an error somewhere.
00137 
00138         wVerReq = MAKEWORD(1,1);
00139 
00140         err = WSAStartup(wVerReq, &WSAData);
00141         if (err != 0)
00142         {
00143            fprintf(stderr, "Could not initialize Windows socket interface.");
00144            exit(1);
00145         }
00146 
00147     sp = getservbyname("ftp", "tcp");
00148     if (sp == 0) {
00149         fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
00150         exit(1);
00151     }
00152 
00153         portnum = sp->s_port;
00154 
00155 
00156     doglob = 1;
00157     interactive = 1;
00158     autologin = 1;
00159     argc--, argv++;
00160     while (argc > 0 && **argv == '-') {
00161         for (cp = *argv + 1; *cp; cp++)
00162             switch (*cp) {
00163 
00164             case 'd':
00165                 options |= SO_DEBUG;
00166                 debug++;
00167                 break;
00168 
00169             case 'v':
00170                 verbose++;
00171                 break;
00172 
00173             case 't':
00174                 trace++;
00175                 break;
00176 
00177             case 'i':
00178                 interactive = 0;
00179                 break;
00180 
00181             case 'n':
00182                 autologin = 0;
00183                 break;
00184 
00185             case 'g':
00186                 doglob = 0;
00187                 break;
00188 
00189             default:
00190                 fprintf(stdout,
00191                   "ftp: %c: unknown option\n", *cp);
00192                 exit(1);
00193             }
00194         argc--, argv++;
00195     }
00196 //  fromatty = isatty(fileno(stdin));
00197         fromatty = 1; // Strengthen this test
00198     /*
00199      * Set up defaults for FTP.
00200      */
00201     (void) strcpy(typename, "ascii"), type = TYPE_A;
00202     (void) strcpy(formname, "non-print"), form = FORM_N;
00203     (void) strcpy(modename, "stream"), mode = MODE_S;
00204     (void) strcpy(structname, "file"), stru = STRU_F;
00205     (void) strcpy(bytename, "8"), bytesize = 8;
00206     if (fromatty)
00207         verbose++;
00208     cpend = 0;           /* no pending replies */
00209     proxy = 0;  /* proxy not active */
00210     passivemode = 1; /* passive mode *is* active */
00211     crflag = 1;    /* strip c.r. on ascii gets */
00212     /*
00213      * Set up the home directory in case we're globbing.
00214      */
00215 #if 0
00216     cp = getlogin();
00217     if (cp != NULL) {
00218         pw = getpwnam(cp);
00219     }
00220     if (pw == NULL)
00221         pw = getpwuid(getuid());
00222     if (pw != NULL) {
00223         home = homedir;
00224         (void) strcpy(home, pw->pw_dir);
00225     }
00226 #endif
00227         strcpy(home, "C:/");
00228     if (argc > 0) {
00229         if (setjmp(toplevel))
00230             exit(0);
00231 //      (void) signal(SIGINT, intr);
00232 //      (void) signal(SIGPIPE, lostpeer);
00233         setpeer(argc + 1, argv - 1);
00234     }
00235     top = setjmp(toplevel) == 0;
00236     if (top) {
00237 //      (void) signal(SIGINT, intr);
00238 //      (void) signal(SIGPIPE, lostpeer);
00239     }
00240     for (;;) {
00241         cmdscanner(top);
00242         top = 1;
00243     }
00244 }
00245 
00246 void intr(void)
00247 {
00248     longjmp(toplevel, 1);
00249 }
00250 
00251 void lostpeer(void)
00252 {
00253    extern SOCKET cout;
00254    extern int data;
00255 
00256    if (connected) {
00257       if (cout) {
00258          closesocket(cout);
00259          cout = 0;
00260       }
00261       if (data >= 0) {
00262          (void) shutdown(data, 1+1);
00263          (void) close(data);
00264          data = -1;
00265       }
00266       connected = 0;
00267    }
00268    pswitch(1);
00269    if (connected) {
00270       if (cout) {
00271                         closesocket(cout);
00272          cout = 0;
00273       }
00274       connected = 0;
00275    }
00276    proxflag = 0;
00277    pswitch(0);
00278 }
00279 
00280 /*char *
00281 tail(char *filename)
00282 {
00283     register char *s;
00284 
00285     while (*filename) {
00286         s = rindex(filename, '/');
00287         if (s == NULL)
00288             break;
00289         if (s[1])
00290             return (s + 1);
00291         *s = '\0';
00292     }
00293     return (filename);
00294 }
00295 */
00296 /*
00297  * Command parser.
00298  */
00299 void cmdscanner(int top)
00300 {
00301     register struct cmd *c;
00302 
00303     if (!top)
00304         (void) putchar('\n');
00305     for (;;) {
00306         (void) fflush(stdout);
00307         if (fromatty) {
00308             printf("ftp> ");
00309             (void) fflush(stdout);
00310         }
00311         if (gets(line) == 0) {
00312             if (feof(stdin) || ferror(stdin))
00313                 quit(0, NULL);
00314             break;
00315         }
00316         if (line[0] == 0)
00317             break;
00318         makeargv();
00319         if (margc == 0) {
00320             continue;
00321         }
00322         c = getcmd(margv[0]);
00323         if (c == (struct cmd *)-1) {
00324             printf("?Ambiguous command\n");
00325             continue;
00326         }
00327         if (c == 0) {
00328             printf("?Invalid command\n");
00329             continue;
00330         }
00331         if (c->c_conn && !connected) {
00332             printf ("Not connected.\n");
00333             continue;
00334         }
00335         (*c->c_handler)(margc, margv);
00336         if (bell && c->c_bell)
00337             (void) putchar('\007');
00338         if (c->c_handler != help)
00339             break;
00340     }
00341     (void) fflush(stdout);
00342 //  (void) signal(SIGINT, intr);
00343 //  (void) signal(SIGPIPE, lostpeer);
00344 }
00345 
00346 struct cmd *
00347 getcmd(const char *name)
00348 {
00349     extern struct cmd cmdtab[];
00350     const char *p, *q;
00351     struct cmd *c, *found;
00352     int nmatches, longest;
00353 
00354     longest = 0;
00355     nmatches = 0;
00356     found = 0;
00357     for (c = cmdtab; (p = c->c_name); c++) {
00358         for (q = name; *q == *p++; q++)
00359             if (*q == 0)        /* exact match? */
00360                 return (c);
00361         if (!*q) {          /* the name was a prefix */
00362             if (q - name > longest) {
00363                 longest = q - name;
00364                 nmatches = 1;
00365                 found = c;
00366             } else if (q - name == longest)
00367                 nmatches++;
00368         }
00369     }
00370     if (nmatches > 1)
00371         return ((struct cmd *)-1);
00372     return (found);
00373 }
00374 
00375 /*
00376  * Slice a string up into argc/argv.
00377  */
00378 
00379 int slrflag;
00380 
00381 void makeargv(void)
00382 {
00383     const char **argp;
00384 
00385     margc = 0;
00386     argp = margv;
00387     stringbase = line;      /* scan from first of buffer */
00388     argbase = argbuf;       /* store from first of buffer */
00389     slrflag = 0;
00390     while ((*argp++ = slurpstring()))
00391         margc++;
00392 }
00393 
00394 /*
00395  * Parse string into argbuf;
00396  * implemented with FSM to
00397  * handle quoting and strings
00398  */
00399 static const char *
00400 slurpstring(void)
00401 {
00402     int got_one = 0;
00403     register char *sb = stringbase;
00404     register char *ap = argbase;
00405     char *tmp = argbase;        /* will return this if token found */
00406 
00407     if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
00408         switch (slrflag) {  /* and $ as token for macro invoke */
00409             case 0:
00410                 slrflag++;
00411                 stringbase++;
00412                 return ((*sb == '!') ? "!" : "$");
00413                 /* NOTREACHED */
00414             case 1:
00415                 slrflag++;
00416                 altarg = stringbase;
00417                 break;
00418             default:
00419                 break;
00420         }
00421     }
00422 
00423 S0:
00424     switch (*sb) {
00425 
00426     case '\0':
00427         goto OUT1;
00428 
00429     case ' ':
00430     case '\t':
00431         sb++; goto S0;
00432 
00433     default:
00434         switch (slrflag) {
00435             case 0:
00436                 slrflag++;
00437                 break;
00438             case 1:
00439                 slrflag++;
00440                 altarg = sb;
00441                 break;
00442             default:
00443                 break;
00444         }
00445         goto S1;
00446     }
00447 
00448 S1:
00449     switch (*sb) {
00450 
00451     case ' ':
00452     case '\t':
00453     case '\0':
00454         goto OUT1;  /* end of token */
00455 
00456     case '\\':
00457         sb++; goto S2;  /* slurp next character */
00458 
00459     case '"':
00460         sb++; goto S3;  /* slurp quoted string */
00461 
00462     default:
00463         *ap++ = *sb++;  /* add character to token */
00464         got_one = 1;
00465         goto S1;
00466     }
00467 
00468 S2:
00469     switch (*sb) {
00470 
00471     case '\0':
00472         goto OUT1;
00473 
00474     default:
00475         *ap++ = *sb++;
00476         got_one = 1;
00477         goto S1;
00478     }
00479 
00480 S3:
00481     switch (*sb) {
00482 
00483     case '\0':
00484         goto OUT1;
00485 
00486     case '"':
00487         sb++; goto S1;
00488 
00489     default:
00490         *ap++ = *sb++;
00491         got_one = 1;
00492         goto S3;
00493     }
00494 
00495 OUT1:
00496     if (got_one)
00497         *ap++ = '\0';
00498     argbase = ap;           /* update storage pointer */
00499     stringbase = sb;        /* update scan pointer */
00500     if (got_one) {
00501         return(tmp);
00502     }
00503     switch (slrflag) {
00504         case 0:
00505             slrflag++;
00506             break;
00507         case 1:
00508             slrflag++;
00509             altarg = (char *) 0;
00510             break;
00511         default:
00512             break;
00513     }
00514     return((char *)0);
00515 }
00516 
00517 #define HELPINDENT (sizeof ("directory"))
00518 
00519 /*
00520  * Help command.
00521  * Call each command handler with argc == 0 and argv[0] == name.
00522  */
00523 void help(int argc, const char *argv[])
00524 {
00525     extern struct cmd cmdtab[];
00526     struct cmd *c;
00527 
00528     if (argc == 1) {
00529         register int i, j, w, k;
00530         int columns, width = 0, lines;
00531         extern int NCMDS;
00532 
00533         printf("Commands may be abbreviated.  Commands are:\n\n");
00534         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
00535             int len = strlen(c->c_name);
00536 
00537             if (len > width)
00538                 width = len;
00539         }
00540         width = (width + 8) &~ 7;
00541         columns = 80 / width;
00542         if (columns == 0)
00543             columns = 1;
00544         lines = (NCMDS + columns - 1) / columns;
00545         for (i = 0; i < lines; i++) {
00546             for (j = 0; j < columns; j++) {
00547                 c = cmdtab + j * lines + i;
00548                 if (c->c_name && (!proxy || c->c_proxy)) {
00549                     printf("%s", c->c_name);
00550                 }
00551                 else if (c->c_name) {
00552                     for (k=0; k < (int) strlen(c->c_name); k++) {
00553                         (void) putchar(' ');
00554                     }
00555                 }
00556                 if (c + lines >= &cmdtab[NCMDS]) {
00557                     printf("\n");
00558                     break;
00559                 }
00560                 w = strlen(c->c_name);
00561                 while (w < width) {
00562                     w = (w + 8) &~ 7;
00563                     (void) putchar('\t');
00564                 }
00565             }
00566         }
00567         (void) fflush(stdout);
00568         return;
00569     }
00570     while (--argc > 0) {
00571         const char *arg;
00572         arg = *++argv;
00573         c = getcmd(arg);
00574         if (c == (struct cmd *)-1)
00575             printf("?Ambiguous help command %s\n", arg);
00576         else if (c == (struct cmd *)0)
00577             printf("?Invalid help command %s\n", arg);
00578         else
00579             printf("%-*s\t%s\n", (int)HELPINDENT,
00580                 c->c_name, c->c_help);
00581     }
00582     (void) fflush(stdout);
00583 }

Generated on Sun May 27 2012 04:16:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.