rsalz@uunet.uu.net (Rich Salz) (09/13/88)
Submitted-by: Emmet P Gray <fthood!egray> Posting-number: Volume 16, Issue 9 Archive-name: pcomm2/part04 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # di_win.c # dial.c # expand.c # getcwd.c # getopt.c # help.c # info.c # init.c # input.c # line_set.c # list_dir.c # ls_menu.c export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'di_win.c'" '(9165 characters)' if test -f 'di_win.c' then echo shar: "will not over-write existing file 'di_win.c'" else sed 's/^X//' << \SHAR_EOF > 'di_win.c' X/* X * The dialing window routines. X */ X X#define MAX_PASS 25 X X#include <stdio.h> X#include <curses.h> X#include "config.h" X#include "dial_dir.h" X#include "misc.h" X#include "modem.h" X#include "param.h" X X/* X * The dialing window. Its job is to kill the input routine, get a port, X * cycle thru the entries in the queue, while interpreting both the X * user's requests and the modem's responses. A return code of 1 means X * we're ready to fire up the input routine. X */ X Xint Xdial_win() X{ X extern int rc_index, fd; X WINDOW *di_win, *newwin(); X int i, j, key, want_out, pass, tic, baud; X long now, time(); X char *tbuf, *ctime(), *str, cr=13, *read_codes(); X void disp_queue(), send_str(), dial_it(), delay_times(), input_off(); X void error_win(), line_set(), hang_up(), zap_vs(), log_calls(); X void st_line(); X unsigned int sleep(); X /* are we already talking? */ X input_off(); X hang_up(1); X X touchwin(stdscr); X refresh(); X X if (get_port()) X return(0); X /* X * If the phone number is a NULL, then either we are on a X * direct line, or you want to do the dialing yourself. X */ X if (*dir->number[dir->q_num[0]] == NULL) { X /* check LD permission */ X if (limit_ld(0)) X return(0); X /* can't talk directly to OBM */ X if (!strcmp(modem->mname[modem->m_cur], "OBM")) { X error_win(0, "Can't access the On Board Modem directly", X "You must use the automatic dialing feature"); X return(0); X } X X zap_vs(); X touchwin(stdscr); X clear(); X printw("Connected to /dev/%s at %d baud...\n", modem->tty[modem->t_cur], dir->baud[dir->d_cur]); X refresh(); X return(1); X } X X di_win = newwin(17, 70, 3, 5); X /* the basic window */ X mvwattrstr(di_win, 1, 20, A_BOLD, "D I A L I N G W I N D O W"); X horizontal(di_win, 2, 0, 70); X mvwaddstr(di_win, 4, 23, "System name:"); X mvwaddstr(di_win, 5, 23, "Pass number:"); X mvwaddstr(di_win, 6, 14, "Elapse time this try:"); X mvwaddstr(di_win, 7, 13, "Time at start of dial:"); X mvwaddstr(di_win, 8, 9, "Time at start of this try:"); X mvwaddstr(di_win, 9, 16, "Connect delay time:"); X mvwaddstr(di_win, 10, 17, "Redial delay time:"); X mvwaddstr(di_win, 11, 25, "Index/TTY:"); X mvwaddstr(di_win, 12, 16, "Result of last try:"); X X mvwaddstr(di_win, 14, 3, "<SPACE>: Recycle"); X mvwaddstr(di_win, 14, 22, "<DEL>: Remove from queue"); X mvwaddstr(di_win, 14, 49, "E: Change delays"); X X /* the start time */ X time(&now); X tbuf = ctime(&now); X tbuf[19] = NULL; X mvwaddstr(di_win, 7, 36, &tbuf[11]); X X mvwprintw(di_win, 9, 36, "%-4d", param->c_delay); X mvwprintw(di_win, 10, 36, "%-4d", param->r_delay); X X box(di_win, VERT, HORZ); X mvwaddstr(di_win, 16, 24, " Press <ESC> to abort "); X X pass = 0; X i = 0; X want_out = 0; X while (!want_out && pass <= MAX_PASS) { X key = -1; X pass++; X /* update the d_cur variable */ X dir->d_cur = dir->q_num[i]; X /* check LD permission */ X if (limit_ld(i)) { X want_out++; X break; X } X /* get a port */ X if (get_port()) { X want_out++; X break; X } X /* fill in the window */ X disp_queue(di_win, dir->d_cur, pass); X X /* X * The actual dial routine. The "i" is the index into the X * queue, not the entry number. Returns immediately without X * waiting for a carrier. X */ X dial_it(i); X ioctl(fd, TCFLSH, 0); X X /* X * Here we do a time-slice between reading the result codes X * from the modem and reading the keyboard. The one second X * granularity won't be too accurate, but who cares? X */ X tic = 0; X rc_index = 0; X while (tic < param->c_delay) { X if ((str = read_codes()) == NULL) { X mvwprintw(di_win, 6, 36, "%-4d", ++tic); X wrefresh(di_win); X } X else { X /* X * A return code that converts to an number X * that is less than 300 is probably an error X * message. X */ X baud = atoi(str); X if (baud < 300) { X mvwprintw(di_win, 12, 36, "%-20.20s", str); X wmove(di_win, 12, 36); X wrefresh(di_win); X break; X } X /* we're connected */ X beep(); X clear_line(di_win, 12, 36, 1); X wattrstr(di_win, A_BLINK, "CONNECTED"); X wmove(di_win, 12, 36); X wrefresh(di_win); X wait_key(di_win, 2); X delwin(di_win); X X /* X * Did the modem sync at a different baud X * rate than what we expected? X */ X if (dir->baud[dir->d_cur] != baud) { X if (can_sync(baud)) { X dir->baud[dir->d_cur] = baud; X line_set(); X } X } X X zap_vs(); X touchwin(stdscr); X clear(); X printw("Connected to %s at %d baud...\n", X dir->name[dir->d_cur], dir->baud[dir->d_cur]); X refresh(); X X /* log the call */ X log_calls(i); X return(1); X } X if (tic == param->c_delay) X break; X /* ok... try the keyboard */ X if ((key = wait_key(di_win, 1)) != -1) X break; X X mvwprintw(di_win, 6, 36, "%-4d", ++tic); X wrefresh(di_win); X } X /* X * If the modem did not return a code, then we need to X * stop it. Sending a CR will stop most modems cold, X * except of course for the OBM... X */ X if (str == NULL) { X if (!strcmp(modem->mname[modem->m_cur], "OBM")) X hang_up(0); X else X write(fd, &cr, 1); X sleep(1); X } X /* if we get here, no key was pressed */ X if (key == -1) { X clear_line(di_win, 6, 14, 1); X mvwaddstr(di_win, 6, 27, "Pausing:"); X /* no return code? */ X if (str == NULL) { X clear_line(di_win, 12, 36, 1); X waddstr(di_win, "TIMED OUT"); X wmove(di_win, 12, 36); X } X /* do the pause */ X tic = 0; X while (tic < param->r_delay) { X if ((key = wait_key(di_win, 1)) != -1) X break; X mvwprintw(di_win, 6, 36, "%-4d", ++tic); X wrefresh(di_win); X } X clear_line(di_win, 6, 14, 1); X waddstr(di_win, "Elapse time this try:"); X } X mvwaddstr(di_win, 6, 36, "0 "); X /* Process the keystroke */ X switch (key) { X case ' ': /* next in the queue */ X clear_line(di_win, 12, 36, 1); X waddstr(di_win, "RECYCLED"); X wmove(di_win, 12, 36); X wrefresh(di_win); X /* fall thru... */ X case -1: /* no key was pressed */ X i++; X if (i > NUM_QUEUE) X i = 0; X if (dir->q_num[i] == -1) X i = 0; X break; X case DEL: /* <DEL> key, remove from queue */ X if (dir->q_num[1] == -1) { X beep(); X clear_line(di_win, 12, 36, 1); X waddstr(di_win, "NO MORE ENTRIES"); X wmove(di_win, 12, 36); X wrefresh(di_win); X wait_key(di_win, 3); X break; X } X clear_line(di_win, 12, 36, 1); X waddstr(di_win, "ENTRY DELETED"); X wmove(di_win, 12, 36); X wrefresh(di_win); X wait_key(di_win, 3); X X /* compact the queue */ X for (j=i; j<NUM_QUEUE-1; j++) X dir->q_num[j] = dir->q_num[j+1]; X dir->q_num[NUM_QUEUE-1] = -1; X break; X case 'e': X case 'E': /* change delay time */ X delay_times(); X touchwin(di_win); X mvwprintw(di_win, 9, 36, "%-4d", param->c_delay); X mvwprintw(di_win, 10, 36, "%-4d", param->r_delay); X break; X case ESC: /* <ESC> key */ X beep(); X clear_line(di_win, 12, 36, 1); X wattrstr(di_win, A_BLINK, "DIAL ABORTED"); X wmove(di_win, 12, 36); X wrefresh(di_win); X wait_key(di_win, 3); X want_out++; X break; X default: X beep(); X break; X } X } X /* clean up and go home */ X werase(di_win); X wrefresh(di_win); X delwin(di_win); X if (!want_out) X error_win(0, "Exceeded the maximum number number of dialing attempts", ""); X return(0); X} X X/* X * Display what info we know at this time. X */ X Xstatic void Xdisp_queue(win, entry, pass) XWINDOW *win; Xint entry, pass; X{ X long now, time(); X char *tbuf, *ctime(); X void st_line(); X /* redo the status line */ X st_line(""); X /* system name */ X clear_line(win, 4, 36, 1); X waddstr(win, dir->name[entry]); X /* pass number */ X mvwprintw(win, 5, 36, "%-4d", pass); X /* time of this call */ X time(&now); X tbuf = ctime(&now); X tbuf[19] = NULL; X mvwaddstr(win, 8, 36, &tbuf[11]); X /* the index field */ X clear_line(win, 11, 36, 1); X waddstr(win, dir->index[entry]); X X wmove(win, 12, 36); X wrefresh(win); X return; X} X X/* X * Determine if the modem can detect the synchronization of the connected X * baud rate. We check the modem database and see if the connect string X * is unique. A return code of 1 means the modem can sync. X */ X Xstatic int Xcan_sync(baud) Xint baud; X{ X int i; X char *str; X /* feature disabled? */ X if (modem->auto_baud[modem->m_cur] != 'Y') X return(0); X /* re-construct the string */ X switch (baud) { X case 300: X str = modem->con_3[modem->m_cur]; X break; X case 1200: X str = modem->con_12[modem->m_cur]; X break; X case 2400: X str = modem->con_24[modem->m_cur]; X break; X case 4800: X str = modem->con_48[modem->m_cur]; X break; X case 9600: X str = modem->con_96[modem->m_cur]; X break; X case 19200: X str = modem->con_192[modem->m_cur]; X break; X default: X return(0); X } X X if (*str == NULL) X return(0); X /* test "str" against all others */ X i = 0; X if (!strcmp(str, modem->con_3[modem->m_cur])) X i++; X if (!strcmp(str, modem->con_12[modem->m_cur])) X i++; X if (!strcmp(str, modem->con_24[modem->m_cur])) X i++; X if (!strcmp(str, modem->con_48[modem->m_cur])) X i++; X if (!strcmp(str, modem->con_96[modem->m_cur])) X i++; X if (!strcmp(str, modem->con_192[modem->m_cur])) X i++; X /* should match only itself */ X if (i == 1) X return(1); X return(0); X} SHAR_EOF if test 9165 -ne "`wc -c < 'di_win.c'`" then echo shar: "error transmitting 'di_win.c'" '(should have been 9165 characters)' fi fi echo shar: "extracting 'dial.c'" '(7336 characters)' if test -f 'dial.c' then echo shar: "will not over-write existing file 'dial.c'" else sed 's/^X//' << \SHAR_EOF > 'dial.c' X/* X * The routines that dial the modem and listen for the return codes. X */ X X#include <stdio.h> X#include <termio.h> X#include "config.h" X#ifdef UNIXPC X#include <sys/phone.h> X#endif /* UNIXPC */ X#include "dial_dir.h" X#include "misc.h" X#include "modem.h" X#include "param.h" X X/* X * Get the dial string ready, send it to the modem. The parameter is not X * the actual entry number, it is an index into the queue. X */ X Xvoid Xdial_it(num) Xint num; X{ X extern int fd; X int i, skip; X char s[100], number[40], *strcpy(), *strcat(), *n, *strchr(); X void send_str(); X#ifdef UNIXPC X struct updata pbuf; X unsigned int sleep(); X#endif /* UNIXPC */ X X /* X * Create the string to be sent to the modem. The long distance X * codes are added if they are requested. X */ X s[0] = NULL; X strcpy(s, modem->dial[modem->m_cur]); X X switch (dir->q_ld[num]) { X case 0: /* no ld code requested */ X break; X case '+': X strcat(s, param->ld_plus); X break; X case '-': X strcat(s, param->ld_minus); X break; X case '@': X strcat(s, param->ld_at); X break; X case '#': X strcat(s, param->ld_pound); X break; X } X /* X * Purify the phone number by removing all the pretty characters X * that don't need to be sent to the modem. Typically the "-", X * "(", ")", and space characters are just for looks. To prevent X * this action, prepend a "\" to the character. X */ X i = 0; X skip = 0; X n = dir->number[dir->q_num[num]]; X while (*n) { X if (*n == '\\' && !skip) { X skip++; X n++; X continue; X } X if (!strchr("-() ", *n) || skip) X number[i++] = *n; X n++; X skip = 0; X } X number[i] = NULL; X /* add it to the string */ X strcat(s, number); X strcat(s, modem->suffix[modem->m_cur]); X#ifdef DEBUG X fprintf(stderr, "raw dial string: '%s'\n", s); X#endif /* DEBUG */ X X#ifdef UNIXPC X /* special case for OBM */ X if (!strcmp(modem->mname[modem->m_cur], "OBM")) { X /* prepare the modem */ X pbuf.c_lineparam = DATA|DTMF; X pbuf.c_waitdialtone = 5; X pbuf.c_linestatus = 0; X pbuf.c_feedback = SPEAKERON|NORMSPK; X pbuf.c_waitflash = 500; X ioctl(fd, PIOCSETP, &pbuf); X sleep(1); X /* connect the dialer */ X ioctl(fd, PIOCRECONN); X sleep(1); X /* dial each digit */ X n = s; X while (*n) { X /* switch tone/pulse dialing? */ X switch (*n) { X case '^': X pbuf.c_lineparam = DATA|PULSE; X ioctl(fd, PIOCSETP, &pbuf); X break; X case '%': X pbuf.c_lineparam = DATA|DTMF; X ioctl(fd, PIOCSETP, &pbuf); X break; X default: X ioctl(fd, PIOCDIAL, n); X break; X } X n++; X } X return; X } X#endif /* UNIXPC */ X X send_str(s); X return; X} X X/* X * Send a string to the modem. Performs all the character synonym X * translations. No sanity checking on the "m_cur" value. X */ X Xvoid Xsend_str(s) Xchar *s; X{ X extern int fd; X int skip; X unsigned int sleep(); X /* empty string? */ X if (s == NULL || *s == NULL) X return; X X ioctl(fd, TCFLSH, 1); X /* X * Change the character synonyms to their real values. Writes X * the characters to the modem. To remove the special meaning X * of one of the characters, prepend a "\" to it. X */ X skip = 0; X while (*s) { X /* send the literal character */ X if (skip) { X skip = 0; X write(fd, s, 1); X ioctl(fd, TCSBRK, 1); X#ifdef DEBUG X fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s); X#endif /* DEBUG */ X s++; X continue; X } X /* turn off the special meaning */ X if (*s == '\\') { X skip++; X s++; X continue; X } X /* pause synonym */ X if (*s == param->pause_char) { X sleep(1); X s++; X continue; X } X /* carriage return synonym */ X if (*s == param->cr_char) X *s = '\r'; X /* 2 character control sequence */ X if (*s == param->ctrl_char) { X s++; X /* premature EOF? */ X if (*s == NULL) X break; X /* upper and lower case */ X if (*s > '_') X *s -= 96; X else X *s -= 64; X } X /* escape synonym */ X if (*s == param->esc_char) X *s = ESC; X /* modem break synonym */ X if (*s == param->brk_char) { X ioctl(fd, TCSBRK, 0); X sleep(1); X s++; X continue; X } X X write(fd, s, 1); X#ifdef DEBUG X fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s); X#endif /* DEBUG */ X /* X * Because the pause char makes the timing critical, we X * wait until the buffer is clear before we continue. X */ X ioctl(fd, TCSBRK, 1); X s++; X } X return; X} X X/* X * Read the result codes coming back from the modem. Test for the 6 X * "connect" strings and the 4 "no connect" strings. Return the connected X * baud rate (as a string) or the error message. X */ X Xchar rc_buf[512]; Xint rc_index; X Xchar * Xread_codes() X{ X extern int fd; X char c; X#ifdef UNIXPC X unsigned int sleep(); X struct updata pbuf; X /* special case for OBM */ X if (!strcmp(modem->mname[modem->m_cur], "OBM")) { X ioctl(fd, PIOCGETP, &pbuf); X X /* X * The OBM doesn't use a return message to announce the X * connection to a remote, so we fake one. The 1200 X * is quite arbitrary... it is not an indicator of the X * connected baud rate. X */ X if (pbuf.c_linestatus & MODEMCONNECTED) X return("1200"); X X sleep(1); X return(NULL); X } X#endif /* UNIXPC */ X /* search for key words */ X for (; rc_index<511; rc_index++) { X if ((int) (c = getc_line(1)) <= 0) X return(NULL); X#ifdef DEBUG X fprintf(stderr, "read_codes: '%c', %02x, %03o, %d\n", c, c, c, c); X#endif /* DEBUG */ X X rc_buf[rc_index] = c; X rc_buf[rc_index+1] = NULL; X /* the connect strings */ X if (match(rc_buf, modem->con_3[modem->m_cur])) X return("300"); X X if (match(rc_buf, modem->con_12[modem->m_cur])) X return("1200"); X X if (match(rc_buf, modem->con_24[modem->m_cur])) X return("2400"); X X if (match(rc_buf, modem->con_48[modem->m_cur])) X return("4800"); X X if (match(rc_buf, modem->con_96[modem->m_cur])) X return("9600"); X X if (match(rc_buf, modem->con_192[modem->m_cur])) X return("19200"); X X /* the no connect strings */ X if (match(rc_buf, modem->no_con1[modem->m_cur])) X return(modem->no_con1[modem->m_cur]); X X if (match(rc_buf, modem->no_con2[modem->m_cur])) X return(modem->no_con2[modem->m_cur]); X X if (match(rc_buf, modem->no_con3[modem->m_cur])) X return(modem->no_con3[modem->m_cur]); X X if (match(rc_buf, modem->no_con4[modem->m_cur])) X return(modem->no_con4[modem->m_cur]); X } X /* ran out of buffer? */ X return("ERROR"); X} X X/* X * Test for a match between two character strings. A return code of 1 X * means that s2 was found at the end of s1. X */ X Xstatic int Xmatch(s1, s2) Xchar *s1, *s2; X{ X register int i; X int skip, diff; X char new[40]; X /* if no string to match */ X if (*s2 == NULL) X return(0); X /* translate synonyms */ X i = 0; X skip = 0; X while (*s2) { X /* literal character */ X if (skip) { X skip = 0; X new[i++] = *s2; X s2++; X continue; X } X /* turn off the special meaning */ X if (*s2 == '\\') { X skip++; X s2++; X continue; X } X /* carriage return synonym */ X if (*s2 == param->cr_char) X *s2 = '\r'; X X /* 2 character control sequence */ X if (*s2 == param->ctrl_char) { X s2++; X if (*s2 == NULL) X break; X if (*s2 > '_') X *s2 -= 96; X else X *s2 -= 64; X } X /* escape synonym */ X if (*s2 == param->esc_char) X *s2 = ESC; X X new[i++] = *s2; X s2++; X } X new[i] = NULL; X X diff = strlen(s1) - strlen(new); X /* is it possible? */ X if (diff < 0) X return(0); X /* test it out */ X if (!strcmp(&s1[diff], new)) X return(1); X return(0); X} SHAR_EOF if test 7336 -ne "`wc -c < 'dial.c'`" then echo shar: "error transmitting 'dial.c'" '(should have been 7336 characters)' fi fi echo shar: "extracting 'expand.c'" '(2683 characters)' if test -f 'expand.c' then echo shar: "will not over-write existing file 'expand.c'" else sed 's/^X//' << \SHAR_EOF > 'expand.c' X/* X * Do file name expansion with "native" shell. Using the native shell X * (as described in the SHELL environmental variable) allows for csh or X * ksh abbreviations that sh doesn't recognize. X */ X X#include <stdio.h> X#include <signal.h> X#include <fcntl.h> X#include "config.h" X Xchar * Xexpand(input) Xchar *input; X{ X extern char *null_ptr; X FILE *pfp, *n_popen(); X int last; X char *ans, buf[1024], *strpbrk(), *strdup(); X void free_ptr(); X X /* same rules as strdup() */ X if (input == NULL) X return(NULL); X if (*input == NULL) X return(null_ptr); X /* any thing to expand? */ X ans = strdup(input); X if (!strpbrk(input, "$*{}[]\\?~")) X return(ans); X /* popen an echo */ X sprintf(buf, "echo %s", input); X X pfp = n_popen(buf, "r"); X fgets(buf, 1024, pfp); X n_pclose(pfp); X X if (!strlen(buf)) X return(ans); X /* X * A horrible kludge... if the last character is not a line X * feed, then the csh has returned an error message. Otherwise X * zap the line feed. X */ X last = strlen(buf) -1; X if (buf[last] != '\n') X return(ans); X else X buf[last] = NULL; X X free_ptr(ans); X ans = strdup(buf); X return(ans); X} X X#define tst(a,b) (*mode == 'r'? (b) : (a)) X#define RDR 0 X#define WTR 1 Xstatic int popen_pid[20]; X XFILE * Xn_popen(cmd, mode) Xchar *cmd, *mode; X{ X int myside, hisside, ppid, p[2]; X char *shellpath, *shell, *flags, *getenv(), *strrchr(); X void _exit(); X X if (pipe(p) < 0) X return NULL; X X myside = tst(p[WTR], p[RDR]); X hisside = tst(p[RDR], p[WTR]); X /* get the environmental variable */ X shellpath = getenv("SHELL"); X if (shellpath == NULL || *shellpath == NULL) X shellpath = "/bin/sh"; X X shell = strrchr(shellpath, '/') + 1; X /* fix up the flags */ X if (!strcmp(shell, "csh")) X flags = "-fc"; X else X flags = "-c"; /* Korn shell too */ X X if (!(ppid = fork())) { X int stdio; X /* no error messages please */ X close(2); X open("/dev/null", O_WRONLY); X#ifdef SETUGID X setgid(getgid()); X setuid(getuid()); X#endif /* SETUGID */ X stdio = tst(0, 1); X close(myside); X close(stdio); X fcntl(hisside, F_DUPFD, stdio); X close(hisside); X execl(shellpath, shell, flags, cmd, (char *) 0); X _exit(1); X } X if (ppid == -1) { X close(myside); X close(hisside); X return NULL; X } X X popen_pid[myside] = ppid; X X close(hisside); X return(fdopen(myside, mode)); X} X Xn_pclose(ptr) XFILE *ptr; X{ X int f, r, (*hstat)(), (*istat)(), (*qstat)(), status; X X f = fileno(ptr); X fclose(ptr); X istat = signal(SIGINT, SIG_IGN); X qstat = signal(SIGQUIT, SIG_IGN); X hstat = signal(SIGHUP, SIG_IGN); X X while ((r = wait(&status)) != popen_pid[f] && r != -1) X ; X X if (r == -1) X status = -1; X X signal(SIGINT, istat); X signal(SIGQUIT, qstat); X signal(SIGHUP, hstat); X return(status); X} SHAR_EOF if test 2683 -ne "`wc -c < 'expand.c'`" then echo shar: "error transmitting 'expand.c'" '(should have been 2683 characters)' fi fi echo shar: "extracting 'getcwd.c'" '(387 characters)' if test -f 'getcwd.c' then echo shar: "will not over-write existing file 'getcwd.c'" else sed 's/^X//' << \SHAR_EOF > 'getcwd.c' X/* X * Can you believe it??? Masscomps don't have a function to return the X * current working directory while in the AT&T universe! X */ X X#include <stdio.h> X Xchar * Xgetcwd(buf, size) Xchar *buf; Xint size; X{ X FILE *pfp, *popen(); X X if (!(pfp = popen("pwd", "r"))) X return("."); X X fgets(buf, size, pfp); X pclose(pfp); X /* zap the new line */ X buf[strlen(buf)-1] = NULL; X return(buf); X} SHAR_EOF if test 387 -ne "`wc -c < 'getcwd.c'`" then echo shar: "error transmitting 'getcwd.c'" '(should have been 387 characters)' fi fi echo shar: "extracting 'getopt.c'" '(1034 characters)' if test -f 'getopt.c' then echo shar: "will not over-write existing file 'getopt.c'" else sed 's/^X//' << \SHAR_EOF > 'getopt.c' X/* X * Parse the command line and return option flags and arguments X */ X X#include <stdio.h> X Xint optind = 1; Xchar *optarg; X Xint Xgetopt(argc, argv, opts) Xint argc; Xchar *argv[]; Xchar *opts; X{ X static int sp = 1; X int c, strcmp(); X char *cp, *strchr(); X X if (sp == 1) { X if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') X return(EOF); X else if (strcmp(argv[optind], "--") == NULL) { X optind++; X return(EOF); X } X } X c = argv[optind][sp]; X if (c == ':' || (cp=strchr(opts, c)) == NULL) { X fprintf(stderr, "%s: illegal option '%c'\n", argv[0], c); X if (argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return('?'); X } X if (*++cp == ':') { X if (argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if (++optind >= argc) { X fprintf(stderr, "%s: option '%c' requires an argument\n", argv[0], c); X sp = 1; X return('?'); X } else X optarg = argv[optind++]; X sp = 1; X } else { X if (argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = NULL; X } X return(c); X} SHAR_EOF if test 1034 -ne "`wc -c < 'getopt.c'`" then echo shar: "error transmitting 'getopt.c'" '(should have been 1034 characters)' fi fi echo shar: "extracting 'help.c'" '(1802 characters)' if test -f 'help.c' then echo shar: "will not over-write existing file 'help.c'" else sed 's/^X//' << \SHAR_EOF > 'help.c' X/* X * Display the help screen. Press any key to continue. If the ascii_hot X * string is more than 4 characters wide, this screen will look silly. X * Maybe one day, this will also contain page-full descriptions of each X * command. X */ X X#include <stdio.h> X#include <curses.h> X#include "config.h" X#include "misc.h" X Xvoid Xhelp_screen(hot) Xchar *hot; X{ X extern int fd; X WINDOW *h_win, *newwin(); X X h_win = newwin(17, 80, 0, 0); X X mvwattrstr(h_win, 1, 29, A_BOLD, "P C O M M H E L P\n"); X horizontal(h_win, 2, 0, 80); X mvwattrstr(h_win, 4, 0, A_BOLD, " Major Functions Utility Functions File Functions\n\n"); X mvwprintw(h_win, 6, 2, "Dialing Directory.%4.4s-D Program Info ....%4.4s-I Send Files ....%4.4s-<up>", hot, hot, hot); X mvwprintw(h_win, 7, 2, "Auto Redial ......%4.4s-R Setup Screen ....%4.4s-S Receive Files .%4.4s-<down>", hot, hot, hot); X mvwprintw(h_win, 8, 2, "Keyboard Macros ..%4.4s-M Change Directory.%4.4s-B Pass Thru Mode.%4.4s-T", hot, hot, hot); X mvwprintw(h_win, 9, 2, "Line Settings ....%4.4s-P Clear Screen ....%4.4s-C Directory .....%4.4s-F", hot, hot, hot); X mvwprintw(h_win, 10, 2, "Exit Pcomm .......%4.4s-X Toggle Duplex ...%4.4s-E Screen Dump ...%4.4s-G", hot, hot, hot); X mvwprintw(h_win, 11, 2, "Unix Gateway .....%4.4s-4 Hang Up Phone ...%4.4s-H Start Data Log.%4.4s-1", hot, hot, hot); X mvwprintw(h_win, 12, 28, "Printer On/Off ..%4.4s-L Toggle Log ....%4.4s-2", hot, hot); X mvwprintw(h_win, 13, 28, "Toggle CR-CR/LF .%4.4s-3", hot); X mvwprintw(h_win, 14, 28, "Break Key .......%4.4s-7", hot); X X box(h_win, VERT, HORZ); X mvwaddstr(h_win, 16, 26, " Press any key to continue "); X wmove(h_win, 16, 79); X wrefresh(h_win); X X wgetch(h_win); X if (fd == -1) { X werase(h_win); X wrefresh(h_win); X } X delwin(h_win); X return; X} SHAR_EOF if test 1802 -ne "`wc -c < 'help.c'`" then echo shar: "error transmitting 'help.c'" '(should have been 1802 characters)' fi fi echo shar: "extracting 'info.c'" '(1532 characters)' if test -f 'info.c' then echo shar: "will not over-write existing file 'info.c'" else sed 's/^X//' << \SHAR_EOF > 'info.c' X/* X * Display the initial welcome screen (to include all of the proper X * acknowledgements). Press any key to continue. X */ X X#define VERSION "1.1" X#define DATE "21 Aug 88" X X#include <stdio.h> X#include <curses.h> X Xvoid Xinfo(delay) Xint delay; X{ X extern int fd; X WINDOW *w_win, *newwin(); X char buf[80]; X /* display the welcome screen */ X w_win = newwin(23, 80, 0, 0); X mvwaddstr(w_win, 3, 18, "PPPPPP CCCC OOOO MM MM MM MM"); X mvwaddstr(w_win, 4, 18, "P P C O O M M M M M M M M"); X mvwaddstr(w_win, 5, 18, "PPPPPP C O O M M M M M M"); X mvwaddstr(w_win, 6, 18, "P C O O M M M M"); X mvwaddstr(w_win, 7, 18, "P CCCC OOOO M M M M"); X X sprintf(buf, ">>> Pcomm Version %s <<<", VERSION); X mvwaddstr(w_win, 10, (80-strlen(buf))/2, buf); X sprintf(buf, "Release date: %s", DATE); X mvwaddstr(w_win, 11, (80-strlen(buf))/2, buf); X X mvwaddstr(w_win, 13, 8, "Pcomm is a public domain telecommunication program for Unix that"); X mvwaddstr(w_win, 14, 8, "is designed to operate similar to the MSDOS program, ProComm."); X mvwaddstr(w_win, 15, 8, "ProComm (TM) is copyrighted by Datastorm Technologies, Inc."); X mvwaddstr(w_win, 19, 45, "Emmet P. Gray"); X mvwaddstr(w_win, 20, 45, "...!uunet!uiucuxc!fthood!egray"); X wmove(w_win, 22, 79); X wrefresh(w_win); X /* Delay so you can read the herald */ X if (delay) X wait_key(w_win, 5); X else X wgetch(w_win); X X if (fd == -1) { X werase(w_win); X wrefresh(w_win); X } X delwin(w_win); X return; X} SHAR_EOF if test 1532 -ne "`wc -c < 'info.c'`" then echo shar: "error transmitting 'info.c'" '(should have been 1532 characters)' fi fi echo shar: "extracting 'init.c'" '(2944 characters)' if test -f 'init.c' then echo shar: "will not over-write existing file 'init.c'" else sed 's/^X//' << \SHAR_EOF > 'init.c' X/* X * Display the welcome screen and find the Pcomm support files. Returns a X * pointer to the STATUS structure. All errors are fatal. X */ X X#include <stdio.h> X#include <curses.h> X#include "config.h" X#ifdef SHAREDMEM X#include <sys/types.h> X#include <sys/ipc.h> X#include <sys/shm.h> X#endif /* SHAREDMEM */ X#include "misc.h" X#include "status.h" X Xstruct STATUS * Xinit(short_cut) Xchar *short_cut; X{ X char *mktemp(), *strcpy(); X struct STATUS *s_ptr; X void info(); X#ifdef SHAREDMEM X int i, j, mode; X extern int shm_id; X char *shmat(); X void exit(); X X /* X * Since the "pcomm_input" program does not run set-user/group-id X * the mode must be set so the effective ID can read/write to the X * shared memory segment. Kinda strange... real ID's aren't used. X */ X#ifdef SETUGID X mode = 0666; X#else /* SETUGID */ X mode = 0600; X#endif /* SETUGID */ X /* create a shared memory segment */ X shm_id = shmget(IPC_PRIVATE, sizeof (struct STATUS), mode|IPC_CREAT|IPC_EXCL|IPC_NOWAIT); X if (shm_id < 0) { X endwin(); X perror("shmget"); X exit(1); X } X s_ptr = (struct STATUS *) shmat(shm_id, (char *) 0, 0); X if ((int) s_ptr == -1) { X endwin(); X perror("shmat"); X exit(1); X } X#else /* SHAREDMEM */ X static struct STATUS s; X s_ptr = &s; X#endif /* SHAREDMEM */ X /* some defaults */ X s_ptr->fd = -1; X s_ptr->add_lf = 0; X s_ptr->log = 0; X s_ptr->print = 0; X strcpy(s_ptr->log_path, "NOT_DEFINED"); X#ifdef SHAREDMEM X s_ptr->clr = 0; X s_ptr->row = 0; X s_ptr->col = 0; X for (i=0; i<LINES; i++) { X for (j=0; j<COLS; j++) X s_ptr->vs[i][j] = ' '; X s_ptr->vs[i][COLS] = NULL; X } X#else /* SHAREDMEM */ X strcpy(s_ptr->vs_path, mktemp("/tmp/pcommXXXXXX")); X#endif /* SHAREDMEM */ X /* display herald if no short-cut */ X if (short_cut == NULL) X info(1); X X erase(); X refresh(); X return(s_ptr); X} X X/* X * Search the extra directory (supplied on the command line), then the X * directory in the PCOMM environmental variable, then the current working X * directory, and lastly, the default directory. X */ X Xchar * Xfindfile(extra, name) Xchar *extra, *name; X{ X int i; X char *pcomm, *getenv(), *path, pbuf[200], *getcwd(), *strdup(); X char temp[200]; X X /* see if PCOMM variable is set */ X pcomm = getenv("PCOMM"); X if (pcomm == NULL || *pcomm == NULL) X pcomm = NULL; X else { X /* zap the trailing separator */ X if (pcomm[strlen(pcomm)-1] == '/') X pcomm[strlen(pcomm)-1] = NULL; X } X X for (i=0; i<4; i++) { X /* directory search order */ X switch (i) { X case 0: /* extra directory from command line */ X path = extra; X break; X case 1: /* PCOMM environmental variable */ X path = pcomm; X break; X case 2: /* current working directory */ X path = getcwd(pbuf, 200); X break; X case 3: /* Pcomm's default directory */ X path = DEFAULT_DIR; X break; X } X if (path == NULL) X continue; X X sprintf(temp, "%s/%s", path, name); X /* read permission checked */ X if (!access(temp, 4)) X return(strdup(temp)); X } X return(NULL); X} SHAR_EOF if test 2944 -ne "`wc -c < 'init.c'`" then echo shar: "error transmitting 'init.c'" '(should have been 2944 characters)' fi fi echo shar: "extracting 'input.c'" '(10147 characters)' if test -f 'input.c' then echo shar: "will not over-write existing file 'input.c'" else sed 's/^X//' << \SHAR_EOF > 'input.c' X/* X * The input routines. This program runs as a child process to the X * Pcomm program. X */ X X#define CLIST 64 X X#include <stdio.h> X#include <signal.h> X#include <setjmp.h> X#include "config.h" X#ifdef SHAREDMEM X#include <sys/types.h> X#include <sys/ipc.h> X#include <sys/shm.h> X#endif /* SHAREDMEM */ X#define MAIN X#include "misc.h" X#include "status.h" X#include "vcs.h" X Xjmp_buf i_jmp; Xint vcs_param[NUM_VCS][5]; /* positional parameters */ Xint vcs_opt[NUM_VCS][10]; /* options unique to each vcs */ Xint vcs_codes[NUM_VCS][VCS_SIZE]; /* the vcs codes */ Xint vcs_leadin[NUM_VCS]; /* unique list of lead-in characters */ Xint num_leadin; /* length of lead-in list */ Xint hold, max_row, max_col, skip_row; XFILE *logfp, *lprfp; Xstruct STATUS *status; X X#ifdef SHAREDMEM X#define VROW status->row X#define VCOL status->col X#define VS status->vs X#else /* SHAREDMEM */ Xint VROW, VCOL; Xchar VS[MAX_ROW][MAX_COL+2]; Xstruct STATUS s; X#endif /* SHAREDMEM */ X X/* X * Read the serial port and write the characters to the screen. Watch X * for signals from the parent process to toggle the fancy options. X * Writes the characters received to a virtual screen buffer. X */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X FILE *popen(); X int got_sig(); X char c, *strcpy(); X void _exit(), exit(), vcs_table(); X#ifdef SHAREDMEM X int shm_id; X char *shmat(); X#endif /* SHAREDMEM */ X /* set the trap for the signals */ X signal(SIGALRM, SIG_IGN); X signal(SIGHUP, SIG_IGN); X signal(SIGQUIT, SIG_IGN); X signal(SIGUSR1, got_sig); X signal(SIGUSR2, got_sig); X signal(SIGINT, got_sig); X signal(SIGTERM, got_sig); X /* unbuffered output */ X setbuf(stdout, (char *) NULL); X /* for the curious... */ X if (argc == 1) { X fprintf(stderr, "This is the input routine for the Pcomm program\n"); X fprintf(stderr, "It is not designed to be run as a separate program\n"); X exit(1); X } X#ifdef SHAREDMEM X shm_id = atoi(argv[1]); X status = (struct STATUS *) shmat(shm_id, (char *) 0, 0); X if ((int) status == -1) { X perror("shmat"); X _exit(1); X } X#else /* SHAREDMEM */ X status = &s; X#endif /* SHAREDMEM */ X /* load the VCS table */ X vcs_table(); X if (max_row > MAX_ROW) X max_row = MAX_ROW; X if (max_col > MAX_COL) X max_col = MAX_COL; X /* parse the command line */ X#ifndef SHAREDMEM X status->fd = atoi(argv[1]); X status->add_lf = atoi(argv[2]); X status->log = atoi(argv[3]); X status->print = atoi(argv[4]); X strcpy(status->log_path, argv[5]); X strcpy(status->vs_path, argv[6]); X#endif /* SHAREDMEM */ X X skip_row = 0; X#ifdef SHAREDMEM X if (status->clr) X skip_row = 1; X#else /* SHAREDMEM */ X /* read previous screen */ X if (!access(status->vs_path, 0)) X read_vs(); X else X skip_row = 1; X#endif /* SHAREDMEM */ X X hold = 0; X /* start up file pointers */ X lprfp = (FILE *) NULL; X logfp = (FILE *) NULL; X X switch (setjmp(i_jmp)) { X case 0: /* no signal */ X break; X case 1: /* toggle the data logging */ X status->log = status->log ? 0 : 1; X break; X case 2: /* toggle the printer */ X status->print = status->print ? 0 : 1; X break; X case 3: /* suspend the input */ X hold = hold ? 0 : 1; X#ifndef SHAREDMEM X if (hold) X write_vs(); X#endif /* SHAREDMEM */ X break; X case 4: /* clean up and go home */ X if (status->log) X fclose(logfp); X if (status->print) { X putc('\f', lprfp); X pclose(lprfp); X } X#ifdef SHAREDMEM X /* detach shared memory */ X shmdt((char *) status); X#endif /* SHAREDMEM */ X _exit(0); X break; X } X /* any signal will awaken pause() */ X if (hold) X pause(); X /* open or close the printer */ X if (status->print && lprfp == NULL) X lprfp = popen(LPR, "w"); X X if (!status->print && lprfp != NULL) { X putc('\f', lprfp); X pclose(lprfp); X lprfp = (FILE *) NULL; X } X /* open or close the log file */ X if (status->log && logfp == NULL) { X if (strcmp(status->log_path, "NOT_DEFINED")) { X if (!(logfp = fopen(status->log_path, "a"))) X status->log = 0; X } X else X status->log = 0; X } X if (!status->log && logfp != NULL) { X fclose(logfp); X logfp = (FILE *) NULL; X } X X#ifdef SHAREDMEM X if (status->clr) { X status->clr = 0; X vs_clear(); X } X#else /* SHAREDMEM */ X /* clear if vs_path doesn't exist */ X if (access(status->vs_path, 0)) X vs_clear(); X#endif /* SHAREDMEM */ X /* X * The very first screen we see after dialing has the "Connected to..." X * message at row 0, therefore we start our virtual screen at row 1. X */ X if (skip_row) { X skip_row = 0; X VROW = 1; X } X X while (1) { X if ((int) (c = readbyte()) <= 0) X continue; X /* send to logfile */ X if (status->log) { X if (c == '\r' && status->add_lf) X putc('\n', logfp); X /* no carriage returns in logfile */ X if (c != '\r') X putc(c, logfp); X } X /* send to printer too? */ X if (status->print) X putc(c, lprfp); X X /* put a char in virtual screen */ X vs_putchar(c); X X putchar(c); X /* add LF to CR? */ X if (c == '\r' && status->add_lf) X putchar('\n'); X } X} X X/* X * Figure out which signal we just received, and fix the return code of X * the setjmp function above to the proper value. X */ X Xint Xgot_sig(sig) Xint sig; X{ X void longjmp(); X switch (sig) { X case SIGUSR1: X signal(SIGUSR1, got_sig); X longjmp(i_jmp, 1); X case SIGUSR2: X signal(SIGUSR2, got_sig); X longjmp(i_jmp, 2); X case SIGINT: X signal(SIGINT, got_sig); X longjmp(i_jmp, 3); X case SIGTERM: X signal(SIGTERM, got_sig); X longjmp(i_jmp, 4); X } X} X X/* X * Put a character in the virtual screen. This routine saves incoming X * characters in a two dimensional buffer designed to mimic the real X * screen. X */ X Xint Xvs_putchar(c) Xchar c; X{ X register int j, i; X int tab_stop; X X switch (vcs_filter(c)) { X case MAYBE: /* wait and see... */ X break; X case 256+HOME: /* home virtual screen "cursor" */ X VROW = 0; X VCOL = 0; X break; X case 256+CLR_EOL: /* clear to end of line */ X for (i=VCOL; i<max_col; i++) X VS[VROW][i] = ' '; X break; X case 256+CLR_EOS: /* clear to end of screen */ X for (j=VCOL; j<max_col; j++) X VS[VROW][j] = ' '; X for (i=VROW+1; i<max_row; i++) { X for (j=0; j<max_col; j++) X VS[i][j] = ' '; X } X break; X case 256+CLEAR: /* clear all and home "cursor" */ X for (i=0; i<max_row; i++) { X for (j=0; j<max_col; j++) X VS[i][j] = ' '; X } X VROW = 0; X VCOL = 0; X break; X case 256+MV_UP: /* move "cursor" up */ X VROW--; X if (VROW < 0) X VROW = 0; X break; X case 256+MV_DOWN: /* move "cursor" down */ X VROW++; X if (VROW >= max_row) X VROW = max_row -1; X break; X case 256+MV_RIGHT: /* move "cursor" right */ X VCOL++; X if (VCOL >= max_col) X VCOL = max_col -1; X break; X case 256+MV_LEFT: /* move "cursor" left */ X case BS: /* non destructive back space */ X VCOL--; X if (VCOL < 0) X VCOL = 0; X break; X case 256+MV_DIRECT: /* direct cursor movement */ X VROW = vcs_param[MV_DIRECT][0]; X VCOL = vcs_param[MV_DIRECT][1]; X X /* if "add one" and "decimal" */ X if (vcs_opt[MV_DIRECT][0] && vcs_opt[MV_DIRECT][1]) { X VROW--; X VCOL--; X } X /* if "character" */ X if (vcs_opt[MV_DIRECT][2]) { X /* if "add offset" */ X if (vcs_opt[MV_DIRECT][3]) { X VROW -= vcs_opt[MV_DIRECT][5]; X VCOL -= vcs_opt[MV_DIRECT][5]; X } X /* if "subtract offset" */ X if (vcs_opt[MV_DIRECT][4]) { X VROW += vcs_opt[MV_DIRECT][5]; X VCOL += vcs_opt[MV_DIRECT][5]; X } X VROW--; X VCOL--; X } X break; X case '\t': /* tab character */ X tab_stop = VCOL + 8 - (VCOL % 8); X /* if wrap around */ X if (tab_stop >= max_col) { X /* spaces up to eol */ X for (; VCOL<max_col; VCOL++) X VS[VROW][VCOL] = ' '; X VROW++; X if (VROW >= max_row) X vs_scroll(); X X /* the remainder of the tab */ X VCOL = tab_stop - max_col; X } X else { X for (; VCOL<tab_stop; VCOL++) X VS[VROW][VCOL] = ' '; X } X break; X case '\r': /* carriage return */ X VCOL = 0; X if (!status->add_lf) X break; X /* fall thru...*/ X case '\n': /* line feed */ X VROW++; X if (VROW >= max_row) X vs_scroll(); X break; X default: /* a normal character */ X VS[VROW][VCOL] = c; X VCOL++; X /* wrap around */ X if (VCOL >= max_col) { X VCOL = 0; X VROW++; X if (VROW >= max_row) X vs_scroll(); X } X break; X } X return(0); X} X X#ifndef SHAREDMEM X/* X * Save the virtual screen to a file. X */ X Xint Xwrite_vs() X{ X FILE *fp; X register int i; X X if (!(fp = fopen(status->vs_path, "w"))) X return(1); X /* current x y coordinates */ X fprintf(fp, "%d,%d\n", VROW, VCOL); X X for (i=0; i<max_row; i++) { X VS[i][max_col] = NULL; X fprintf(fp, "%s\n", VS[i]); X } X fclose(fp); X return(0); X} X X/* X * Get the virtual screen image from the file. Since input() gets X * killed from time to time, the vs_path file is the only way to retain X * the screen image. X */ X Xint Xread_vs() X{ X FILE *fp; X register int i; X char buf[10]; X /* in case the fopen fails... */ X VROW = 0; X VCOL = 0; X /* not guaranteed to exist yet */ X if (!(fp = fopen(status->vs_path, "r"))) X return(1); X /* get the x, y coordinates */ X fgets(buf, 10, fp); X scanf(buf, "%d,%d\n", VROW, VCOL); X X /* read the file into the vs array */ X for (i=0; i<max_row; i++) { X fgets(VS[i], MAX_COL+2, fp); X VS[i][max_col] = NULL; X } X fclose(fp); X return(0); X} X#endif /* SHAREDMEM */ X X/* X * If the user clears the screen with the ^A-C command, the input X * has to be in sync. X */ X Xint Xvs_clear() X{ X register int j, i; X X for (i=0; i<max_row; i++) { X VS[i][max_col] = NULL; X for (j=0; j<max_col; j++) X VS[i][j] = ' '; X } X /* home the "cursor" */ X VROW = 0; X VCOL = 0; X return(0); X} X X/* X * Do a software scroll on the virtual screen. Does not alter the X * "col" variable. X */ X Xint Xvs_scroll() X{ X register int i; X char *strcpy(); X /* move 'em up 1 line */ X for (i=0; i<max_row-1; i++) X strcpy(VS[i], VS[i+1]); X /* clear the bottom line */ X for (i=0; i<max_col; i++) X VS[max_row-1][i] = ' '; X X VROW = max_row -1; X return(0); X} X X/* X * Do a buffered read from the serial port. X */ X Xint Xreadbyte() X{ X static char buf[CLIST]; X static char *bufp = buf; X static int n = 0; X X if (n <= 0) { X if ((n = read(status->fd, buf, CLIST)) <= 0) X return(-1); X bufp = buf; X } X while (--n >= 0) X return(*bufp++ & 0xff); X return(-1); X} SHAR_EOF if test 10147 -ne "`wc -c < 'input.c'`" then echo shar: "error transmitting 'input.c'" '(should have been 10147 characters)' fi fi echo shar: "extracting 'line_set.c'" '(1944 characters)' if test -f 'line_set.c' then echo shar: "will not over-write existing file 'line_set.c'" else sed 's/^X//' << \SHAR_EOF > 'line_set.c' X/* X * Change the communication line settings to the new values. X */ X X#include <stdio.h> X#include <termio.h> X#include "dial_dir.h" X#include "param.h" X Xvoid Xline_set() X{ X extern int fd; X struct termio tbuf; X X /* X * The manual dial entry also serves to store the previous X * line settings. How else would the manual dial entry X * know what line setting to use? X */ X if (dir->d_cur != 0) { X dir->baud[0] = dir->baud[dir->d_cur]; X dir->parity[0] = dir->parity[dir->d_cur]; X dir->dbits[0] = dir->dbits[dir->d_cur]; X dir->sbits[0] = dir->sbits[dir->d_cur]; X } X /* nothing to do! */ X if (fd == -1) X return; X /* get the current settings */ X ioctl(fd, TCGETA, &tbuf); X /* set some beginning values */ X tbuf.c_cc[4] = 1; /* VMIN */ X tbuf.c_cc[5] = 0; /* VTIME */ X tbuf.c_oflag = 0; X tbuf.c_iflag = 0; X tbuf.c_cflag = (CREAD|HUPCL|CLOCAL); X tbuf.c_lflag = 0; X X if (*param->flow == 'X') X tbuf.c_iflag |= IXON|IXOFF; X /* strip high bit? */ X if (*param->strip == 'Y') X tbuf.c_iflag |= ISTRIP; X /* the baud rate */ X switch (dir->baud[dir->d_cur]) { X case 300: X tbuf.c_cflag |= B300; X break; X case 1200: X tbuf.c_cflag |= B1200; X break; X case 2400: X tbuf.c_cflag |= B2400; X break; X case 4800: X tbuf.c_cflag |= B4800; X break; X case 9600: X tbuf.c_cflag |= B9600; X break; X case 19200: X#ifdef B19200 X tbuf.c_cflag |= B19200; X#else /* B19200 */ X#ifdef EXTA X tbuf.c_cflag |= EXTA; X#endif /* EXTA */ X#endif /* B19200 */ X break; X } X /* the parity */ X switch (dir->parity[dir->d_cur]) { X case 'N': X break; X case 'O': X tbuf.c_cflag |= (PARENB|PARODD); X break; X case 'E': X tbuf.c_cflag |= PARENB; X break; X } X /* the data bits */ X if (dir->dbits[dir->d_cur] == 8) X tbuf.c_cflag |= CS8; X else X tbuf.c_cflag |= CS7; X /* the stop bits */ X if (dir->sbits[dir->d_cur] == 2) X tbuf.c_cflag |= CSTOPB; X X /* now set 'em! */ X ioctl(fd, TCSETA, &tbuf); X ioctl(fd, TCFLSH, 2); X return; X} SHAR_EOF if test 1944 -ne "`wc -c < 'line_set.c'`" then echo shar: "error transmitting 'line_set.c'" '(should have been 1944 characters)' fi fi echo shar: "extracting 'list_dir.c'" '(1508 characters)' if test -f 'list_dir.c' then echo shar: "will not over-write existing file 'list_dir.c'" else sed 's/^X//' << \SHAR_EOF > 'list_dir.c' X/* X * Do a shell escape with an "ls" command X */ X X#include <stdio.h> X#include <curses.h> X#include "config.h" X#include "misc.h" X Xvoid Xlist_dir() X{ X extern int fd; X WINDOW *ls_win, *newwin(); X FILE *pfp, *n_popen(); X int lines, oops; X char *ans, *cwd, *getcwd(), buf[200], *get_str(); X X ls_win = newwin(6, 70, 8, 5); X X cwd = getcwd(buf, 200); X X mvwprintw(ls_win, 2, 4, "Current directory: %s", cwd); X mvwaddstr(ls_win, 3, 4, "File spec (wildcards allowed): "); X box(ls_win, VERT, HORZ); X X mvwattrstr(ls_win, 0, 3, A_BOLD, " List Directory "); X wmove(ls_win, 3, 35); X wrefresh(ls_win); X X if ((ans = get_str(ls_win, 60, "", "")) == NULL) { X if (fd == -1) { X werase(ls_win); X wrefresh(ls_win); X } X delwin(ls_win); X return; X } X /* popen() an ls */ X sprintf(buf, "ls -aC %s", ans); X pfp = n_popen(buf, "r"); X /* make a bigger window */ X werase(ls_win); X wrefresh(ls_win); X delwin(ls_win); X ls_win = newwin(LINES-1, COLS, 0, 0); X touchwin(ls_win); X X oops = 0; X lines = 0; X while (fgets(buf, BUFSIZ, pfp) != NULL) { X waddstr(ls_win, buf); X lines++; X if (lines == LINES-2) { X lines = 0; X mvwaddstr(ls_win, LINES-2, 28, "Press any key for more"); X wrefresh(ls_win); X if (wgetch(ls_win) == ESC) { X oops++; X break; X } X werase(ls_win); X wrefresh(ls_win); X } X } X n_pclose(pfp); X X if (!oops) { X mvwaddstr(ls_win, LINES-2, 25, "Press any key to continue"); X wrefresh(ls_win); X wgetch(ls_win); X } X if (fd == -1) { X werase(ls_win); X wrefresh(ls_win); X } X delwin(ls_win); X return; X} SHAR_EOF if test 1508 -ne "`wc -c < 'list_dir.c'`" then echo shar: "error transmitting 'list_dir.c'" '(should have been 1508 characters)' fi fi echo shar: "extracting 'ls_menu.c'" '(4809 characters)' if test -f 'ls_menu.c' then echo shar: "will not over-write existing file 'ls_menu.c'" else sed 's/^X//' << \SHAR_EOF > 'ls_menu.c' X/* X * Routines for displaying current line settings and prompting for changes. X */ X X#include <stdio.h> X#include <curses.h> X#include "config.h" X#include "dial_dir.h" X#include "misc.h" X#include "param.h" X X/* X * Display the current line settings and prompt for changes. A return X * code of 1 means settings were changed. X */ X Xint Xls_menu() X{ X extern int fd; X WINDOW *l_win, *newwin(); X int num, ret_code; X void disp_settings(); X X l_win = newwin(20, 47, 0, 16); X X mvwattrstr(l_win, 1, 16, A_BOLD, "Line Settings"); X horizontal(l_win, 2, 0, 47); X mvwaddstr(l_win, 6, 5, "1) 300,E,7,1 7) 300,N,8,1"); X mvwaddstr(l_win, 7, 5, "2) 1200,E,7,1 8) 1200,N,8,1"); X mvwaddstr(l_win, 8, 5, "3) 2400,E,7,1 9) 2400,N,8,1"); X mvwaddstr(l_win, 9, 5, "4) 4800,E,7,1 10) 4800,N,8,1"); X mvwaddstr(l_win, 10, 5, "5) 9600,E,7,1 11) 9600,N,8,1"); X mvwaddstr(l_win, 11, 5, "6) 19200,E,7,1 12) 19200,N,8,1"); X mvwaddstr(l_win, 13, 4, "Parity Data Bits Stop Bits"); X mvwaddstr(l_win, 14, 4, "13) Odd 14) 7 bits 16) 1 bit"); X mvwaddstr(l_win, 15, 18, "15) 8 bits 17) 2 bits"); X mvwaddstr(l_win, 17, 4, "18) Save Changes"); X mvwattrstr(l_win, 17, 28, A_BOLD, "YOUR CHOICE:"); X wmove(l_win, 17, 41); X box(l_win, VERT, HORZ); X X mvwaddstr(l_win, 19, 13, " Press <ESC> to return "); X /* display current settings */ X disp_settings(l_win); X wmove(l_win, 17, 41); X wrefresh(l_win); X /* get the options */ X ret_code = 0; X while ((num = get_num(l_win, 2)) != -1) { X switch (num) { X case 1: X dir->baud[dir->d_cur] = 300; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 2: X dir->baud[dir->d_cur] = 1200; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 3: X dir->baud[dir->d_cur] = 2400; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 4: X dir->baud[dir->d_cur] = 4800; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 5: X dir->baud[dir->d_cur] = 9600; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 6: X dir->baud[dir->d_cur] = 19200; X dir->parity[dir->d_cur] = 'E'; X dir->dbits[dir->d_cur] = 7; X dir->sbits[dir->d_cur] = 1; X break; X case 7: X dir->baud[dir->d_cur] = 300; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 8: X dir->baud[dir->d_cur] = 1200; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 9: X dir->baud[dir->d_cur] = 2400; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 10: X dir->baud[dir->d_cur] = 4800; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 11: X dir->baud[dir->d_cur] = 9600; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 12: X dir->baud[dir->d_cur] = 19200; X dir->parity[dir->d_cur] = 'N'; X dir->dbits[dir->d_cur] = 8; X dir->sbits[dir->d_cur] = 1; X break; X case 13: X dir->parity[dir->d_cur] = 'O'; X break; X case 14: X dir->dbits[dir->d_cur] = 7; X break; X case 15: X dir->dbits[dir->d_cur] = 8; X break; X case 16: X dir->sbits[dir->d_cur] = 1; X break; X case 17: X dir->sbits[dir->d_cur] = 2; X break; X case 18: X /* copy the current settings */ X param->d_baud = dir->baud[dir->d_cur]; X param->d_parity = dir->parity[dir->d_cur]; X param->d_dbits = dir->dbits[dir->d_cur]; X param->d_sbits = dir->sbits[dir->d_cur]; X /* X * We've changed the values in memory even X * if the update fails. X */ X if (up_param()) { X touchwin(l_win); X wrefresh(l_win); X } X break; X default: X beep(); X } X ret_code++; X disp_settings(l_win); X mvwaddstr(l_win, 17, 41, " "); X wmove(l_win, 17, 41); X wrefresh(l_win); X } X if (fd == -1) { X werase(l_win); X wrefresh(l_win); X } X delwin(l_win); X return(ret_code); X} X X/* X * Display the current settings. Formats the entire string at one X * time, in case you've got a magic cookie terminal. X */ X Xstatic void Xdisp_settings(win) XWINDOW *win; X{ X extern int xmc; X char buf[40]; X X sprintf(buf, "Current Settings: %5d,%c,%d,%d", dir->baud[dir->d_cur], X dir->parity[dir->d_cur], dir->dbits[dir->d_cur], X dir->sbits[dir->d_cur]); X X if (xmc > 0) { X touchwin(win); X clear_line(win, 4, 8, 1); X wrefresh(win); X } X mvwattrstr(win, 4, 8, A_BOLD, buf); X return; X} SHAR_EOF if test 4809 -ne "`wc -c < 'ls_menu.c'`" then echo shar: "error transmitting 'ls_menu.c'" '(should have been 4809 characters)' fi fi exit 0 # End of shell archive -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.