/* * cu: talks to the telephone */ #include #include #include #include #include #if MSDOS #include #endif extern char systyp[]; extern char *getenv(); extern int (*cdf)(); extern int getopt(); extern int optopt, opterr, optind; extern char *optarg; char program[] = "cu"; int Debug=0; int modem; char *home=(char*)0, *shell=(char*)0; /* * docommand() executes a command, sending its input and/or output to * the tty device. */ docommand(mode) { char text[200]; int hold[2]; if (mode != '!') printf("%cLocal command: ", mode); else putchar('!'); fflush(stdout); gets(text); if (strlen(text) == 0) if (mode == '!' && shell) strcpy(text, shell); else { fprintf(stderr, "incomplete shell escape\n"); return 0; } if (strlen(text)) { if (mode == '|' || mode == 'C') { hold[0] = dup(0); close(0); dup2(modem, 0); } if (mode == '$' || mode == 'C') { hold[1] = dup(1); close(1); dup2(modem, 1); } allowintr(); system(text); nointr(); if (mode == '|' || mode == 'C') { close(0); dup2(hold[0], 0); } if (mode == '$' || mode == 'C') { close(1); dup2(hold[1], 1); } printf("%c\n", mode); } } /* docommand */ /* * nointr() disables interrupt handling */ nointr() { extern void _cdecl _interrupt _far ignore_ctrlc(); _dos_setvect(0x23, ignore_ctrlc); } /* nointr */ /* have ^C do what it usually does */ allowintr() { extern void _cdecl _interrupt _far intr_on_ctrlc(); _dos_setvect(0x23, intr_on_ctrlc); } /* allowintr */ /* * ^C handling for dialing */ dial_intr(sig) { disable(); /* disable the modem */ unlock(tty); /* release our lock on it */ exit(-sig); /* then run for it */ } /* dial_intr */ /* * CU proper */ main(argc, argv) char **argv; { register char *p; char *speed = (char *)0; int direct=0; register c, lc=0; register mask; char text[200]; /* * snarf options */ mask = 0x7f; opterr = 1; while (getopt(argc, argv, "s:m78") != EOF) { switch (optopt) { case 's': speed = optarg; break; case 'm': break; /* "m"odem switch on UN*X */ case '7': mask = 0x7f; break; case '8': mask = 0xff; break; default: goto badboy; } } if (optind >= argc) { badboy: fprintf(stderr, "usage: cu [-m] [-s speed] [-7|-8] |DIR\n"); exit(255); } if (getcfg() == 0) exit(1); home = getenv("HOME"); shell = getenv("SHELL"); if (stricmp(argv[optind], "dir") == 0) { if (speed == (char *)0) { fprintf(stderr, "cu: no speed specified\n"); exit(2); } callspeed = atol(speed); calltype = DIR; strcpy(systyp, "dir"); direct=1; } else if (oksys(argv[optind])) { if (speed) callspeed = atol(speed); } else { fprintf(stderr, "cu: no system %s\n", *argv); exit(4); } signal(SIGINT, dial_intr); if (!findtty()) { fprintf(stderr, "cu: can't find device at %d bps\n", callspeed); exit(3); } modem = open(tty, O_RDWR); if (modem < -3) { fprintf(stderr, "cu: can't open %s\n", modem); unlock(tty); exit(5); } if (direct) ttyspeed(ttycspeed); else if (dial(callphone, 0) != 0) { puts("No answer"); disable(); unlock(tty); exit(6); } nointr(); puts("Connected"); c = '\r'; while (1) { if (ttystat()) { putchar(ttyin() & mask); fflush(stdout); } else if (kbhit()) { lc=c; c=crawcin(); if (c == '~' && lc == '\r') { fflush(stdout); putchar('~'); fflush(stdout); switch (c = crawcin()) { case '.': puts("EOT"); if (!direct) disable(); unlock(tty); exit(0); case '~': ttyout('~'); continue; case 'C': case '$': case '|': case '!': docommand(c); break; case '#': puts("BRK"); dobreak(1); nap(500L); dobreak(0); break; case 'c': if (home) printf("cd [%s]: ", home); else printf("cd: "); fflush(stdout); gets(text); if (strlen(text) == 0 && home) strcpy(text, home); if (strlen(text) > 0 && chdir(text) != 0) fprintf(stderr, "no directory %s\n", text); break; default: puts("Bad ~ escape!"); case '?': puts("valid ~ escapes are:"); puts("~. - exit cu/hang up the phone"); puts("~! - execute command locally"); puts("~$ - execute command locally, send output to remote"); puts("~| - execute command locally, input from remote"); puts("~C - execute command locally, input and output from remote"); puts("~c - set working directory"); puts("~# - send a break"); puts("~? - get this text"); puts("~~ - send a line beginning with ~"); break; } c = '\r'; } else ttyout(c); } else if (direct == 0 && (*cdf)() == 0) { puts("Connection Closed"); disable(); unlock(tty); exit(0); } } } /* main */