main.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:10k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1985, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #ifndef lint
  34. char copyright[] = 
  35. "@(#) Copyright (c) 1985, 1989 Regents of the University of California.n
  36.  All rights reserved.n";
  37. #endif /* not lint */
  38. /*
  39.  * FTP User Program -- Command Interface.
  40.  */
  41. #include "ftp_var.h"
  42. #define DONT_NEED_SIGBLOCK
  43. #define DONT_NEED_SIGPAUSE
  44. #define DONT_NEED_SIGUNBLOCK
  45. #define DONT_NEED_SIGPENDING
  46. #include "sigfix.h"
  47. #include <arpa/ftp.h>
  48. #include <errno.h>
  49. #include <ctype.h>
  50. #include <pwd.h>
  51. uid_t getuid();
  52. void intr(), lostpeer();
  53. extern char *home;
  54. char *getlogin();
  55. #define HELPINDENT (sizeof ("directory"))
  56. struct cmd *getcmd(register char *name) {
  57.     extern struct cmd cmdtab[];
  58.     register char *p, *q;
  59.     register struct cmd *c, *found;
  60.     register int nmatches, longest;
  61.     
  62.     longest = 0;
  63.     nmatches = 0;
  64.     found = 0;
  65.     for (c = cmdtab; (p = c->c_name); c++) {
  66. for (q = name; *q == *p++; q++)
  67.     if (*q == 0) /* exact match? */
  68. return (c);
  69. if (!*q) { /* the name was a prefix */
  70.     if (q - name > longest) {
  71. longest = q - name;
  72. nmatches = 1;
  73. found = c;
  74.     } else if (q - name == longest)
  75. nmatches++;
  76. }
  77.     }
  78.     
  79.     if (nmatches > 1) return ((struct cmd *)-1);
  80.     return (found);
  81. }
  82. /*
  83.  * Help command.
  84.  * Call each command handler with argc == 0 and argv[0] == name.
  85.  */
  86. void help(int argc, char *argv[]) {
  87.     extern struct cmd cmdtab[];
  88.     register struct cmd *c;
  89.     
  90.     if (argc == 1) {
  91. register int i, j, w, k;
  92. int columns, width = 0, lines;
  93. extern int NCMDS;
  94. printf("Commands may be abbreviated.  Commands are:nn");
  95. for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  96.     int len = strlen(c->c_name);
  97.     
  98.     if (len > width)
  99. width = len;
  100. }
  101. width = (width + 8) &~ 7;
  102. columns = 80 / width;
  103. if (columns == 0)
  104.     columns = 1;
  105. lines = (NCMDS + columns - 1) / columns;
  106. for (i = 0; i < lines; i++) {
  107.     for (j = 0; j < columns; j++) {
  108. c = cmdtab + j * lines + i;
  109. if (c->c_name && (!proxy || c->c_proxy)) 
  110.     printf("%s", c->c_name);
  111. else if (c->c_name) 
  112.     for (k=0; k < strlen(c->c_name); k++)
  113. putchar(' ');
  114. if (c + lines >= &cmdtab[NCMDS]) {
  115.     printf("n");
  116.     break;
  117. }
  118. w = strlen(c->c_name);
  119. while (w < width) {
  120.     w = (w + 8) &~ 7;
  121.     putchar('t');
  122. }
  123.     }
  124. }
  125. return;
  126.     }
  127.     while (--argc > 0) {
  128. register char *arg;
  129. arg = *++argv;
  130. c = getcmd(arg);
  131. if (c == (struct cmd *)-1)
  132.     printf("?Ambiguous help command %sn", arg);
  133. else if (c == (struct cmd *)0)
  134.     printf("?Invalid help command %sn", arg);
  135. else
  136.     printf("%-*st%sn", HELPINDENT,
  137.    c->c_name, c->c_help);
  138.     }
  139. }
  140. /*
  141.  * Command parser.
  142.  */
  143. void cmdscanner(int top) {
  144.     register struct cmd *c;
  145.     register int l;
  146.     
  147.     if (!top)
  148. putchar('n');
  149.     for (;;) {
  150. if (fromatty) {
  151.     printf("ftp> ");
  152.     fflush(stdout);
  153. }
  154. if (fgets(line, sizeof line, stdin) == NULL)
  155.     quit();
  156. l = strlen(line);
  157. if (l == 0)
  158.     break;
  159. if (line[--l] == 'n') {
  160.     if (l == 0)
  161. break;
  162.     line[l] = '';
  163. } else if (l == sizeof(line) - 2) {
  164.     printf("sorry, input line too longn");
  165.     while ((l = getchar()) != 'n' && l != EOF)
  166. /* void */;
  167.     break;
  168. } /* else it was a line without a newline */
  169. makeargv();
  170. if (margc == 0) {
  171.     continue;
  172. }
  173. c = getcmd(margv[0]);
  174. if (c == (struct cmd *)-1) {
  175.     printf("?Ambiguous commandn");
  176.     continue;
  177. }
  178. if (c == 0) {
  179.     printf("?Invalid commandn");
  180.     continue;
  181. }
  182. if (c->c_conn && !connected) {
  183.     printf("Not connected.n");
  184.     continue;
  185. }
  186. (*c->c_handler)(margc, margv);
  187. if (bell && c->c_bell)
  188.     putchar('07');
  189. if (c->c_handler != (int (*)())help)
  190.     break;
  191.     }
  192.     Signal(SIGINT,  intr);
  193.     Signal(SIGPIPE, lostpeer);
  194. }
  195. void intr() {
  196.     longjmp(toplevel, 1);
  197. }
  198. void lostpeer() {
  199.     extern FILE *cout;
  200.     extern int data;
  201.     if (connected) {
  202. if (cout != NULL) {
  203.     shutdown(fileno(cout), 1+1);
  204.     fclose(cout);
  205.     cout = NULL;
  206. }
  207. if (data >= 0) {
  208.     shutdown(data, 1+1);
  209.     close(data);
  210.     data = -1;
  211. }
  212. connected = 0;
  213.     }
  214.     pswitch(1);
  215.     if (connected) {
  216. if (cout != NULL) {
  217.     shutdown(fileno(cout), 1+1);
  218.     fclose(cout);
  219.     cout = NULL;
  220. }
  221. connected = 0;
  222.     }
  223.     proxflag = 0;
  224.     pswitch(0);
  225. }
  226. /*
  227.  * Slice a string up into argc/argv.
  228.  */
  229. int slrflag;
  230. /*
  231.  * Parse string into argbuf;
  232.  * implemented with FSM to
  233.  * handle quoting and strings
  234.  */
  235. char *slurpstring() {
  236.     int got_one = 0;
  237.     register char *sb = stringbase;
  238.     register char *ap = argbase;
  239.     char *tmp = argbase; /* will return this if token found */
  240.     
  241.     if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
  242. switch (slrflag) {          /* and $ as token for macro invoke */
  243.     case 0:
  244. slrflag++;
  245. stringbase++;
  246. return ((*sb == '!') ? "!" : "$");
  247. /* NOTREACHED */
  248.     case 1:
  249. slrflag++;
  250. altarg = stringbase;
  251. break;
  252.     default:
  253. break;
  254. }
  255.     }
  256.     
  257.   S0:
  258.     switch (*sb) {
  259. case '':
  260.     goto OUT;
  261.     
  262. case ' ':
  263. case 't':
  264.     sb++; goto S0;
  265. default:
  266.     switch (slrflag) {
  267. case 0:
  268.     slrflag++;
  269.     break;
  270. case 1:
  271.     slrflag++;
  272.     altarg = sb;
  273.     break;
  274. default:
  275.     break;
  276.     }
  277.     goto S1;
  278.     }
  279.     
  280.   S1:
  281.     switch (*sb) {
  282. case ' ':
  283. case 't':
  284. case '':
  285.     goto OUT; /* end of token */
  286.     
  287. case '\':
  288.     sb++; goto S2; /* slurp next character */
  289.     
  290. case '"':
  291.     sb++; goto S3; /* slurp quoted string */
  292.     
  293. default:
  294.     *ap++ = *sb++; /* add character to token */
  295.     got_one = 1;
  296.     goto S1;
  297.     }
  298.     
  299.   S2:
  300.     switch (*sb) {
  301. case '':
  302.     goto OUT;
  303.     
  304. default:
  305.     *ap++ = *sb++;
  306.     got_one = 1;
  307.     goto S1;
  308.     }
  309.     
  310.   S3:
  311.     switch (*sb) {
  312. case '':
  313.     goto OUT;
  314.     
  315. case '"':
  316.     sb++; goto S1;
  317.     
  318. default:
  319.     *ap++ = *sb++;
  320.     got_one = 1;
  321.     goto S3;
  322. }
  323.   OUT:
  324.     if (got_one) {
  325. *ap++ = '';
  326.     }
  327.     argbase = ap; /* update storage pointer */
  328.     stringbase = sb;         /* update scan pointer */
  329.     if (got_one) {
  330. return(tmp);
  331.     }
  332.     switch (slrflag) {
  333. case 0:
  334.     slrflag++;
  335.     break;
  336. case 1:
  337.     slrflag++;
  338.     altarg = (char *) 0;
  339.     break;
  340. default:
  341.     break;
  342.     }
  343.     return((char *)0);
  344. }
  345. void makeargv() {
  346.     char **argp;
  347.     
  348.     margc = 0;
  349.     argp = margv;
  350.     stringbase = line; /* scan from first of buffer */
  351.     argbase = argbuf; /* store from first of buffer */
  352.     slrflag = 0;
  353.     while ((*argp++ = slurpstring())) margc++;
  354. }
  355. int main(int argc, char *argv[]) {
  356.     register char *cp;
  357.     struct passwd *pw = NULL;
  358.     char homedir[MAXPATHLEN];
  359.     int top;
  360.     
  361. #ifdef SOCKS
  362.     LIBPREFIX2(init)(argv[0]);
  363. #endif
  364.     
  365. #ifdef FASCIST
  366.     fprintf(stderr,"***NOTE: Names of all files transferred will be recorded! n");
  367. #endif
  368.     
  369.     if ((sp = getservbyname("ftp", "tcp")) == 0) {
  370. fprintf(stderr, "ftp: ftp/tcp: unknown servicen");
  371. exit(1);
  372.     }
  373.     /* save ftp's s_port value so it won't be clobbered by by another call   */
  374.     /* to getserbyname()                                                     */
  375.     ftp_s_port = sp->s_port;
  376.     doglob = 1;
  377.     interactive = 1;
  378.     autologin = 1;
  379.     argc--, argv++;
  380.     while (argc > 0 && **argv == '-') {
  381. for (cp = *argv + 1; *cp; cp++)
  382.     switch (*cp) {
  383. case 'd':
  384.     options |= SO_DEBUG;
  385.     debug++;
  386.     break;
  387. case 'v':
  388.     verbose++;
  389.     break;
  390.     
  391. case 't':
  392.     trace++;
  393.     break;
  394.     
  395. case 'i':
  396.     interactive = 0;
  397.     break;
  398.     
  399. case 'n':
  400.     autologin = 0;
  401.     break;
  402.     
  403. case 'g':
  404.     doglob = 0;
  405.     break;
  406.     
  407. default:
  408.     fprintf(stdout, "ftp: %c: unknown optionn", *cp);
  409.     exit(1);
  410.     }
  411. argc--, argv++;
  412.     }
  413.     fromatty = isatty(fileno(stdin));
  414.     if (fromatty) verbose++;
  415.     cpend = 0; /* no pending replies */
  416.     proxy = 0; /* proxy not active */
  417.     crflag = 1; /* strip c.r. on ascii gets */
  418.     sendport = -1; /* not using ports */
  419.     /*  Set up the home directory in case we're globbing.                    */
  420.     if ((cp = getlogin()) != NULL) {
  421. pw = getpwnam(cp);
  422.     }
  423.     if (pw == NULL) {
  424. pw = getpwuid(getuid());
  425.     }
  426.     if (pw != NULL) {
  427. home = homedir;
  428. strcpy(home, pw->pw_dir);
  429.     }
  430.     if (argc > 0) {
  431. if (setjmp(toplevel)) exit(0);
  432. Signal(SIGINT, intr);
  433. Signal(SIGPIPE, lostpeer);
  434. setpeer(argc + 1, argv - 1);
  435.     }
  436.     top = setjmp(toplevel) == 0;
  437.     if (top) {
  438. Signal(SIGINT, intr);
  439. Signal(SIGPIPE, lostpeer);
  440.     }
  441.     for (;;) {
  442. cmdscanner(top);
  443. top = 1;
  444.     }
  445. }