# 2.11BSD#431 - /usr/src/ucb/ftp/main.c

##### Functions

    cmdscanner        X
    getcmd            X
    help              X
    intr              X
    lostpeer          X
    main              X
    makeargv          X
    slurpstring       X

##### Variables

    copyright         X
    slrflag           X

##### Macros

    HELPINDENT        X

       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 are permitted
       6:  * provided that the above copyright notice and this paragraph are
       7:  * duplicated in all such forms and that any documentation,
       8:  * advertising materials, and other materials related to such
       9:  * distribution and use acknowledge that the software was developed
      10:  * by the University of California, Berkeley.  The name of the
      11:  * University may not be used to endorse or promote products derived
      12:  * from this software without specific prior written permission.
      13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
      14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      15:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      16:  */
      17:
      18: #if !defined(lint) && defined(DOSCCS)
      19: char copyright[] =
      20: "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
      21:  All rights reserved.\n";
      22:
      23: static char sccsid[] = "@(#)main.c	based on 5.13.1 (2.11BSD) 1997/10/2";
      24: #endif
      25:
      26: /*
      27:  * FTP User Program -- Command Interface.
      28:  */
      29: #include "ftp_var.h"
      30: #include <sys/socket.h>
      31: #include <sys/ioctl.h>
      32: #include <sys/types.h>
      33:
      34: #include <arpa/ftp.h>
      35:
      36: #include <signal.h>
      37: #include <stdio.h>
      38: #include <errno.h>
      39: #include <ctype.h>
      40: #include <netdb.h>
      41: #include <pwd.h>
      42: #include <stdlib.h>
      43: #include <unistd.h>
      44:
      45: int intr();
      46: int lostpeer();
      47: extern  char *home;
      48:
      49: main(argc, argv)
      50:     char *argv[];
      51: {
      52:     register char *cp;
      53:     int top;
      54:     struct passwd *pw = NULL;
      55:     char homedir[MAXPATHLEN];
      56:
      57:     sp = getservbyname("ftp", "tcp");
      58:     if (sp == 0) {
      59:         fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
      60:         exit(1);
      61:     }
      62:     doglob = 1;
      63:     interactive = 1;
      64:     autologin = 1;
      65:     argc--, argv++;
      66:     while (argc > 0 && **argv == '-') {
      67:         for (cp = *argv + 1; *cp; cp++)
      68:             switch (*cp) {
      69:
      70:             case 'd':
      71:                 options |= SO_DEBUG;
      72:                 debug++;
      73:                 break;
      74:
      75:             case 'v':
      76:                 verbose++;
      77:                 break;
      78:
      79:             case 't':
      80:                 trace++;
      81:                 break;
      82:
      83:             case 'i':
      84:                 interactive = 0;
      85:                 break;
      86:
      87:             case 'n':
      88:                 autologin = 0;
      89:                 break;
      90:
      91:             case 'g':
      92:                 doglob = 0;
      93:                 break;
      94:
      95:             default:
      96:                 fprintf(stdout,
      97:                   "ftp: %c: unknown option\n", *cp);
      98:                 exit(1);
      99:             }
     100:         argc--, argv++;
     101:     }
     102:     fromatty = isatty(fileno(stdin));
     103:     /*
     104: 	 * Set up defaults for FTP.
     105: 	 */
     106:     (void) strcpy(typename, "ascii"), type = TYPE_A;
     107:     (void) strcpy(formname, "non-print"), form = FORM_N;
     108:     (void) strcpy(modename, "stream"), mode = MODE_S;
     109:     (void) strcpy(structname, "file"), stru = STRU_F;
     110:     (void) strcpy(bytename, "8"), bytesize = 8;
     111:     if (fromatty)
     112:         verbose++;
     113:     cpend = 0;           /* no pending replies */
     114:     proxy = 0;  /* proxy not active */
     115:     crflag = 1;    /* strip c.r. on ascii gets */
     116:     /*
     117: 	 * Set up the home directory in case we're globbing.
     118: 	 */
     119:     cp = getlogin();
     120:     if (cp != NULL) {
     121:         pw = getpwnam(cp);
     122:     }
     123:     if (pw == NULL)
     124:         pw = getpwuid(getuid());
     125:     if (pw != NULL) {
     126:         home = homedir;
     127:         (void) strcpy(home, pw->pw_dir);
     128:     }
     129:     if (argc > 0) {
     130:         if (setjmp(toplevel))
     131:             exit(0);
     132:         (void) signal(SIGINT, intr);
     133:         (void) signal(SIGPIPE, lostpeer);
     134:         setpeer(argc + 1, argv - 1);
     135:     }
     136:     top = setjmp(toplevel) == 0;
     137:     if (top) {
     138:         (void) signal(SIGINT, intr);
     139:         (void) signal(SIGPIPE, lostpeer);
     140:     }
     141:     for (;;) {
     142:         cmdscanner(top);
     143:         top = 1;
     144:     }
     145: }
     146:
     147: intr()
     148: {
     149:
     150:     longjmp(toplevel, 1);
     151: }
     152:
     153: lostpeer()
     154: {
     155:     extern FILE *cout;
     156:     extern int data;
     157:
     158:     if (connected) {
     159:         if (cout != NULL) {
     160:             (void) shutdown(fileno(cout), 1+1);
     161:             (void) fclose(cout);
     162:             cout = NULL;
     163:         }
     164:         if (data >= 0) {
     165:             (void) shutdown(data, 1+1);
     166:             (void) close(data);
     167:             data = -1;
     168:         }
     169:         connected = 0;
     170:     }
     171:     pswitch(1);
     172:     if (connected) {
     173:         if (cout != NULL) {
     174:             (void) shutdown(fileno(cout), 1+1);
     175:             (void) fclose(cout);
     176:             cout = NULL;
     177:         }
     178:         connected = 0;
     179:     }
     180:     proxflag = 0;
     181:     pswitch(0);
     182: }
     183:
     184: /*char *
     185: tail(filename)
     186: 	char *filename;
     187: {
     188: 	register char *s;
     189:
     190: 	while (*filename) {
     191: 		s = rindex(filename, '/');
     192: 		if (s == NULL)
     193: 			break;
     194: 		if (s[1])
     195: 			return (s + 1);
     196: 		*s = '\0';
     197: 	}
     198: 	return (filename);
     199: }
     200: */
     201: /*
     202:  * Command parser.
     203:  */
     204: cmdscanner(top)
     205:     int top;
     206: {
     207:     register struct cmd *c;
     208:     struct cmd *getcmd();
     209:     extern int help();
     210:
     211:     if (!top)
     212:         (void) putchar('\n');
     213:     for (;;) {
     214:         if (fromatty) {
     215:             printf("ftp> ");
     216:             (void) fflush(stdout);
     217:         }
     218:         if (gets(line) == 0) {
     219:             if (feof(stdin) || ferror(stdin))
     220:                 quit();
     221:             break;
     222:         }
     223:         if (line[0] == 0)
     224:             break;
     225:         makeargv();
     226:         if (margc == 0) {
     227:             continue;
     228:         }
     229:         c = getcmd(margv[0]);
     230:         if (c == (struct cmd *)-1) {
     231:             printf("?Ambiguous command\n");
     232:             continue;
     233:         }
     234:         if (c == 0) {
     235:             printf("?Invalid command\n");
     236:             continue;
     237:         }
     238:         if (c->c_conn && !connected) {
     239:             printf ("Not connected.\n");
     240:             continue;
     241:         }
     242:         (*c->c_handler)(margc, margv);
     243:         if (bell && c->c_bell)
     244:             (void) putchar('\007');
     245:         if (c->c_handler != help)
     246:             break;
     247:     }
     248:     (void) signal(SIGINT, intr);
     249:     (void) signal(SIGPIPE, lostpeer);
     250: }
     251:
     252: struct cmd *
     253: getcmd(name)
     254:     register char *name;
     255: {
     256:     extern struct cmd cmdtab[];
     257:     register char *p, *q;
     258:     register struct cmd *c, *found;
     259:     register int nmatches, longest;
     260:
     261:     longest = 0;
     262:     nmatches = 0;
     263:     found = 0;
     264:     for (c = cmdtab; p = c->c_name; c++) {
     265:         for (q = name; *q == *p++; q++)
     266:             if (*q == 0)        /* exact match? */
     267:                 return (c);
     268:         if (!*q) {          /* the name was a prefix */
     269:             if (q - name > longest) {
     270:                 longest = q - name;
     271:                 nmatches = 1;
     272:                 found = c;
     273:             } else if (q - name == longest)
     274:                 nmatches++;
     275:         }
     276:     }
     277:     if (nmatches > 1)
     278:         return ((struct cmd *)-1);
     279:     return (found);
     280: }
     281:
     282: /*
     283:  * Slice a string up into argc/argv.
     284:  */
     285:
     286: int slrflag;
     287:
     288: makeargv()
     289: {
     290:     char **argp;
     291:     char *slurpstring();
     292:
     293:     margc = 0;
     294:     argp = margv;
     295:     stringbase = line;      /* scan from first of buffer */
     296:     argbase = argbuf;       /* store from first of buffer */
     297:     slrflag = 0;
     298:     while (*argp++ = slurpstring())
     299:         margc++;
     300: }
     301:
     302: /*
     303:  * Parse string into argbuf;
     304:  * implemented with FSM to
     305:  * handle quoting and strings
     306:  */
     307: char *
     308: slurpstring()
     309: {
     310:     int got_one = 0;
     311:     register char *sb = stringbase;
     312:     register char *ap = argbase;
     313:     char *tmp = argbase;        /* will return this if token found */
     314:
     315:     if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
     316:         switch (slrflag) {  /* and $ as token for macro invoke */
     317:             case 0:
     318:                 slrflag++;
     319:                 stringbase++;
     320:                 return ((*sb == '!') ? "!" : "$");
     321:                 /* NOTREACHED */
     322:             case 1:
     323:                 slrflag++;
     324:                 altarg = stringbase;
     325:                 break;
     326:             default:
     327:                 break;
     328:         }
     329:     }
     330:
     331: S0:
     332:     switch (*sb) {
     333:
     334:     case '\0':
     335:         goto OUT;
     336:
     337:     case ' ':
     338:     case '\t':
     339:         sb++; goto S0;
     340:
     341:     default:
     342:         switch (slrflag) {
     343:             case 0:
     344:                 slrflag++;
     345:                 break;
     346:             case 1:
     347:                 slrflag++;
     348:                 altarg = sb;
     349:                 break;
     350:             default:
     351:                 break;
     352:         }
     353:         goto S1;
     354:     }
     355:
     356: S1:
     357:     switch (*sb) {
     358:
     359:     case ' ':
     360:     case '\t':
     361:     case '\0':
     362:         goto OUT;   /* end of token */
     363:
     364:     case '\\':
     365:         sb++; goto S2;  /* slurp next character */
     366:
     367:     case '"':
     368:         sb++; goto S3;  /* slurp quoted string */
     369:
     370:     default:
     371:         *ap++ = *sb++;  /* add character to token */
     372:         got_one = 1;
     373:         goto S1;
     374:     }
     375:
     376: S2:
     377:     switch (*sb) {
     378:
     379:     case '\0':
     380:         goto OUT;
     381:
     382:     default:
     383:         *ap++ = *sb++;
     384:         got_one = 1;
     385:         goto S1;
     386:     }
     387:
     388: S3:
     389:     switch (*sb) {
     390:
     391:     case '\0':
     392:         goto OUT;
     393:
     394:     case '"':
     395:         sb++; goto S1;
     396:
     397:     default:
     398:         *ap++ = *sb++;
     399:         got_one = 1;
     400:         goto S3;
     401:     }
     402:
     403: OUT:
     404:     if (got_one)
     405:         *ap++ = '\0';
     406:     argbase = ap;           /* update storage pointer */
     407:     stringbase = sb;        /* update scan pointer */
     408:     if (got_one) {
     409:         return(tmp);
     410:     }
     411:     switch (slrflag) {
     412:         case 0:
     413:             slrflag++;
     414:             break;
     415:         case 1:
     416:             slrflag++;
     417:             altarg = (char *) 0;
     418:             break;
     419:         default:
     420:             break;
     421:     }
     422:     return((char *)0);
     423: }
     424:
     425: #define HELPINDENT (sizeof ("directory"))
     426:
     427: /*
     428:  * Help command.
     429:  * Call each command handler with argc == 0 and argv[0] == name.
     430:  */
     431: help(argc, argv)
     432:     int argc;
     433:     char *argv[];
     434: {
     435:     extern struct cmd cmdtab[];
     436:     register struct cmd *c;
     437:
     438:     if (argc == 1) {
     439:         register int i, j, w, k;
     440:         int columns, width = 0, lines;
     441:         extern int NCMDS;
     442:
     443:         printf("Commands may be abbreviated.  Commands are:\n\n");
     444:         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
     445:             int len = strlen(c->c_name);
     446:
     447:             if (len > width)
     448:                 width = len;
     449:         }
     450:         width = (width + 8) &~ 7;
     451:         columns = 80 / width;
     452:         if (columns == 0)
     453:             columns = 1;
     454:         lines = (NCMDS + columns - 1) / columns;
     455:         for (i = 0; i < lines; i++) {
     456:             for (j = 0; j < columns; j++) {
     457:                 c = cmdtab + j * lines + i;
     458:                 if (c->c_name && (!proxy || c->c_proxy)) {
     459:                     printf("%s", c->c_name);
     460:                 }
     461:                 else if (c->c_name) {
     462:                     for (k=0; k < strlen(c->c_name); k++) {
     463:                         (void) putchar(' ');
     464:                     }
     465:                 }
     466:                 if (c + lines >= &cmdtab[NCMDS]) {
     467:                     printf("\n");
     468:                     break;
     469:                 }
     470:                 w = strlen(c->c_name);
     471:                 while (w < width) {
     472:                     w = (w + 8) &~ 7;
     473:                     (void) putchar('\t');
     474:                 }
     475:             }
     476:         }
     477:         return;
     478:     }
     479:     while (--argc > 0) {
     480:         register char *arg;
     481:         arg = *++argv;
     482:         c = getcmd(arg);
     483:         if (c == (struct cmd *)-1)
     484:             printf("?Ambiguous help command %s\n", arg);
     485:         else if (c == (struct cmd *)0)
     486:             printf("?Invalid help command %s\n", arg);
     487:         else
     488:             printf("%-*s\t%s\n", HELPINDENT,
     489:                 c->c_name, c->c_help);
     490:     }
     491: }

#### Defined functions

cmdscanner defined in line 204; used 1 times

- in line 142

getcmd defined in line 252; used 7 times

- in line 208, 229, 482
- in /usr/src/ucb/ftp/cmds.c line 1658, 1675
- in /usr/src/ucb/ftp/domacro.c line 39, 111

help defined in line 431; used 5 times

- in line 209, 245
- in /usr/src/ucb/ftp/cmdtab.c line 33, 131, 179

intr defined in line 147; used 4 times

- in line 45, 132, 138, 248

lostpeer defined in line 153; used 13 times

- in line 46, 133, 139, 249
- in /usr/src/ucb/ftp/ftp.c line 367, 420, 1063, 1490, 1521, 1565, 1596, 1611, 1651

main defined in line 49; never used
makeargv defined in line 288; used 30 times

- in line 225
- in /usr/src/ucb/ftp/cmds.c line 79, 311, 325, 370, 517, 531, 660, 971, 1027, 1053, 1098, 1112, 1168, 1176, 1284, 1349, 1376, 1405, 1440, 1472, 1666, 1799, 2053, 2116, 2140
- in /usr/src/ucb/ftp/domacro.c line 46, 110, 133
- in /usr/src/ucb/ftp/ftp.c line 252

slurpstring defined in line 307; used 2 times

- in line 291, 298

#### Defined variables

copyright defined in line 19; never used
sccsid defined in line 23; never used
slrflag defined in line 286; used 10 times

- in line 297, 316-323(3), 342-347(3), 411-416(3)

#### Defined macros

HELPINDENT defined in line 425; used 1 times

- in line 488

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1965 |