1: #ifndef lint
   2: static char RCSid[] = "$Header: main.c,v 2.0 85/11/21 07:22:49 jqj Exp $";
   3: #endif
   4: 
   5: /*
   6:  * FTP User Program -- Command Interface.
   7:  */
   8: /* $Log:	main.c,v $
   9:  * Revision 2.0  85/11/21  07:22:49  jqj
  10:  * 4.3BSD standard release
  11:  *
  12:  * Revision 1.1  85/05/27  06:31:05  jqj
  13:  * Initial revision
  14:  *
  15:  * Revision 1.1  85/05/27  06:31:05  jqj
  16:  * Initial revision
  17:  *
  18:  * Based on Berkeley tcp/ftp
  19:  */
  20: #include <sys/param.h>
  21: #include <sys/socket.h>
  22: #include <sys/ioctl.h>
  23: 
  24: #include <xnscourier/except.h>
  25: #include <stdio.h>
  26: #include <errno.h>
  27: #include <ctype.h>
  28: #include <pwd.h>
  29: 
  30: #include "ftp_var.h"
  31: 
  32: int intr();
  33: int lostpeer();
  34: extern  char *home;
  35: 
  36: main(argc, argv)
  37:     char *argv[];
  38: {
  39:     register char *cp;
  40:     int top;
  41:     struct passwd *pw;
  42:     char homedir[MAXPATHLEN];
  43: 
  44:     doglob = 1;
  45:     interactive = 1;
  46:     autologin = 1;
  47:     argc--, argv++;
  48:     while (argc > 0 && **argv == '-') {
  49:         for (cp = *argv + 1; *cp; cp++)
  50:             switch (*cp) {
  51: 
  52:             case 'd':
  53:                 debug++;
  54:                 break;
  55: 
  56:             case 'v':
  57:                 verbose++;
  58:                 break;
  59: 
  60:             case 't':
  61:                 trace++;
  62:                 break;
  63: 
  64:             case 'i':
  65:                 interactive = 0;
  66:                 break;
  67: 
  68:             case 'n':
  69:                 autologin = 0;
  70:                 break;
  71: 
  72:             case 'g':
  73:                 doglob = 0;
  74:                 break;
  75: 
  76:             default:
  77:                 fprintf(stderr,
  78:                   "ftp: %c: unknown option\n", *cp);
  79:                 exit(1);
  80:             }
  81:         argc--, argv++;
  82:     }
  83:     fromatty = isatty(fileno(stdin));
  84:     /*
  85: 	 * Set up defaults for FTP.
  86: 	 */
  87:     strcpy(typename, "ascii"), typevalue = TYPE_A;
  88:     strcpy(formname, "non-print"), form = FORM_N;
  89:     strcpy(modename, "stream"), mode = MODE_S;
  90:     strcpy(structname, "file"), stru = STRU_F;
  91:     strcpy(bytename, "8"), bytesize = 8;
  92:     if (fromatty)
  93:         verbose++;
  94:     /*
  95: 	 * Set up the home directory in case we're globbing.
  96: 	 */
  97:     pw = getpwnam(getlogin());
  98:     if (pw == NULL)
  99:         pw = getpwuid(getuid());
 100:     if (pw != NULL) {
 101:         home = homedir;
 102:         strcpy(home, pw->pw_dir);
 103:     }
 104:     signal(SIGINT, intr);
 105:     signal(SIGPIPE, lostpeer);
 106:     DURING {
 107:         if (argc > 0)
 108:           setpeer(argc + 1, argv - 1);
 109:     } HANDLER {
 110:         FilingErrMsg(Exception.Code, Exception.Message);
 111:         exit(0);
 112:     } END_HANDLER;
 113:     for (;;) {
 114:         DURING {
 115:             for (;;)
 116:               cmdscanner();
 117:         } HANDLER {
 118:             FilingErrMsg(Exception.Code, Exception.Message);
 119:             if (connected != (CourierConnection*)0) {
 120:                 DURING
 121:                   probe();  /* reset alarm */
 122:                 HANDLER {   /* can't?  Lost peer */
 123:                   connected = (CourierConnection*) 0;
 124:                 } END_HANDLER;
 125:             }
 126:         } END_HANDLER;
 127:     }
 128: }
 129: 
 130: intr()
 131: {
 132:     extern probe();
 133: 
 134:     printf("\n");
 135:     raise(0, (char *)0);
 136: }
 137: 
 138: lostpeer()
 139: {
 140:     if (connected != (CourierConnection*)0) {
 141:         /* CourierClose(connected); */  /* probably won't work */
 142:         connected = (CourierConnection*) 0;
 143:     }
 144:     raise(EPIPE, "lost peer");
 145: }
 146: 
 147: char *
 148: tail(filename)
 149:     char *filename;
 150: {
 151:     register char *s;
 152: 
 153:     while (*filename) {
 154:         s = rindex(filename, '/');
 155:         if (s == NULL)
 156:             break;
 157:         if (s[1])
 158:             return (s + 1);
 159:         *s = '\0';
 160:     }
 161:     return (filename);
 162: }
 163: 
 164: /*
 165:  * Command parser.
 166:  */
 167: cmdscanner()
 168: {
 169:     register struct cmd *c;
 170:     struct cmd *getcmd();
 171:     extern struct cmd cmdtab[];
 172:     extern int help();
 173: 
 174:     for (;;) {
 175:         if (fromatty) {
 176:             printf("xnsftp> ");
 177:             fflush(stdout);
 178:         }
 179:         if (gets(line) == 0) {
 180:             if (feof(stdin)) {
 181:                 clearerr(stdin);
 182:                 putchar('\n');
 183:             }
 184:             break;
 185:         }
 186:         if (line[0] == 0)
 187:             break;
 188:         makeargv();
 189:         c = getcmd(margv[0]);
 190:         if (c == (struct cmd *)-1) {
 191:             printf("?Ambiguous command\n");
 192:             continue;
 193:         }
 194:         if (c == 0) {
 195:             printf("?Invalid command\n");
 196:             continue;
 197:         }
 198:         if (c->c_conn && !connected) {
 199:             printf ("Not connected.\n");
 200:             continue;
 201:         }
 202:         (*c->c_handler)(margc, margv);
 203:         if (bell && c->c_bell)
 204:             putchar(CTRL(g));
 205:         if (c->c_handler != help)
 206:             break;
 207:     }
 208: }
 209: 
 210: struct cmd *
 211: getcmd(name)
 212:     register char *name;
 213: {
 214:     register char *p, *q;
 215:     register struct cmd *c, *found;
 216:     register int nmatches, longest;
 217: 
 218:     longest = 0;
 219:     nmatches = 0;
 220:     found = 0;
 221:     for (c = cmdtab; p = c->c_name; c++) {
 222:         for (q = name; *q == *p++; q++)
 223:             if (*q == 0)        /* exact match? */
 224:                 return (c);
 225:         if (!*q) {          /* the name was a prefix */
 226:             if (q - name > longest) {
 227:                 longest = q - name;
 228:                 nmatches = 1;
 229:                 found = c;
 230:             } else if (q - name == longest)
 231:                 nmatches++;
 232:         }
 233:     }
 234:     if (nmatches > 1)
 235:         return ((struct cmd *)-1);
 236:     return (found);
 237: }
 238: 
 239: /*
 240:  * Slice a string up into argc/argv.
 241:  */
 242: makeargv()
 243: {
 244:     char **argp;
 245:     char *slurpstring();
 246: 
 247:     margc = 0;
 248:     argp = margv;
 249:     stringbase = line;      /* scan from first of buffer */
 250:     argbase = argbuf;       /* store from first of buffer */
 251:     while (*argp++ = slurpstring())
 252:         margc++;
 253: }
 254: 
 255: /*
 256:  * Parse string into argbuf;
 257:  * implemented with FSM to
 258:  * handle quoting and strings
 259:  */
 260: char *
 261: slurpstring()
 262: {
 263:     int got_one = 0;
 264:     register char *sb = stringbase;
 265:     register char *ap = argbase;
 266:     char *tmp = argbase;        /* will return this if token found */
 267: 
 268:     if (*sb == '!') {       /* recognize ! as a token for shell */
 269:         stringbase++;
 270:         return ("!");
 271:     }
 272: S0:
 273:     switch (*sb) {
 274: 
 275:     case '\0':
 276:         goto OUT;
 277: 
 278:     case ' ':
 279:     case '\t':
 280:         sb++; goto S0;
 281: 
 282:     default:
 283:         goto S1;
 284:     }
 285: 
 286: S1:
 287:     switch (*sb) {
 288: 
 289:     case ' ':
 290:     case '\t':
 291:     case '\0':
 292:         goto OUT;   /* end of token */
 293: 
 294:     case '\\':
 295:         sb++; goto S2;  /* slurp next character */
 296: 
 297:     case '"':
 298:         sb++; goto S3;  /* slurp quoted string */
 299: 
 300:     default:
 301:         *ap++ = *sb++;  /* add character to token */
 302:         got_one = 1;
 303:         goto S1;
 304:     }
 305: 
 306: S2:
 307:     switch (*sb) {
 308: 
 309:     case '\0':
 310:         goto OUT;
 311: 
 312:     default:
 313:         *ap++ = *sb++;
 314:         got_one = 1;
 315:         goto S1;
 316:     }
 317: 
 318: S3:
 319:     switch (*sb) {
 320: 
 321:     case '\0':
 322:         goto OUT;
 323: 
 324:     case '"':
 325:         sb++; goto S1;
 326: 
 327:     default:
 328:         *ap++ = *sb++;
 329:         got_one = 1;
 330:         goto S3;
 331:     }
 332: 
 333: OUT:
 334:     if (got_one)
 335:         *ap++ = '\0';
 336:     argbase = ap;           /* update storage pointer */
 337:     stringbase = sb;        /* update scan pointer */
 338:     if (got_one)
 339:         return(tmp);
 340:     return((char *)0);
 341: }
 342: 
 343: #define HELPINDENT (sizeof ("directory"))
 344: 
 345: /*
 346:  * Help command.
 347:  * Call each command handler with argc == 0 and argv[0] == name.
 348:  */
 349: help(argc, argv)
 350:     int argc;
 351:     char *argv[];
 352: {
 353:     register struct cmd *c;
 354: 
 355:     if (argc == 1) {
 356:         register int i, j, w;
 357:         int columns, width = 0, lines;
 358:         extern int NCMDS;
 359: 
 360:         printf("Commands may be abbreviated.  Commands are:\n\n");
 361:         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
 362:             int len = strlen(c->c_name);
 363: 
 364:             if (len > width)
 365:                 width = len;
 366:         }
 367:         width = (width + 8) &~ 7;
 368:         columns = 80 / width;
 369:         if (columns == 0)
 370:             columns = 1;
 371:         lines = (NCMDS + columns - 1) / columns;
 372:         for (i = 0; i < lines; i++) {
 373:             for (j = 0; j < columns; j++) {
 374:                 c = cmdtab + j * lines + i;
 375:                 printf("%s", c->c_name);
 376:                 if (c + lines >= &cmdtab[NCMDS]) {
 377:                     printf("\n");
 378:                     break;
 379:                 }
 380:                 w = strlen(c->c_name);
 381:                 while (w < width) {
 382:                     w = (w + 8) &~ 7;
 383:                     putchar('\t');
 384:                 }
 385:             }
 386:         }
 387:         return;
 388:     }
 389:     while (--argc > 0) {
 390:         register char *arg;
 391:         arg = *++argv;
 392:         c = getcmd(arg);
 393:         if (c == (struct cmd *)-1)
 394:             printf("?Ambiguous help command %s\n", arg);
 395:         else if (c == (struct cmd *)0)
 396:             printf("?Invalid help command %s\n", arg);
 397:         else
 398:             printf("%-*s\t%s\n", HELPINDENT,
 399:                 c->c_name, c->c_help);
 400:     }
 401: }
 402: 
 403: /*
 404:  * Call routine with argc, argv set from args (terminated by 0).
 405:  */
 406: /* VARARGS2 */
 407: call(routine, args)
 408:     int (*routine)();
 409:     int args;
 410: {
 411:     register int *argp;
 412:     register int argc;
 413: 
 414:     for (argc = 0, argp = &args; *argp++ != 0; argc++)
 415:         ;
 416:     (*routine)(argc, &args);
 417: }

Defined functions

call defined in line 407; used 4 times
cmdscanner defined in line 167; used 1 times
getcmd defined in line 210; used 3 times
help defined in line 349; used 5 times
intr defined in line 130; used 2 times
lostpeer defined in line 138; used 2 times
main defined in line 36; never used
makeargv defined in line 242; used 18 times
slurpstring defined in line 260; used 2 times
tail defined in line 147; used 1 times

Defined variables

RCSid defined in line 2; never used

Defined macros

HELPINDENT defined in line 343; used 1 times
Last modified: 1986-03-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1912
Valid CSS Valid XHTML 1.0 Strict