Subject: v14i103: Dial out and terminal emulator, Part05/06 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: fthood!egray Posting-number: Volume 14, Issue 103 Archive-name: pcomm/part05 #! /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: # s_axfer.c # s_gen.c # s_menu.c # s_modem.c # s_prompt.c # s_term.c # s_tty.c # screen.c # st_line.c # strings.c # terminal.c # x_ascii.c export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 's_axfer.c'" '(3885 characters)' if test -f 's_axfer.c' then echo shar: "will not over-write existing file 's_axfer.c'" else sed 's/^X//' << \SHAR_EOF > 's_axfer.c' X/* X * Display the ASCII transfer setup, query for changes. A return code X * of 1 means something was changed. X */ X X#include X#include X#include "misc.h" X#include "param.h" X Xint Xascii_xfer_setup() X{ X WINDOW *x_win, *newwin(); X int i, ret_code, num; X char *ans, *str_prompt(), *menu_prompt(), *strdup(); X void free_ptr(); X extern char *v_yes[], *v_cr[], *v_lf[], *v_delay[]; X X x_win = newwin(23, 80, 0, 0); X X waddstr(x_win, "----------------------------- "); X wattrstr(x_win, A_BOLD, "ASCII Transfer Setup"); X waddstr(x_win, " -----------------------------"); X mvwaddstr(x_win, 3, 34, "ASCII UPLOAD"); X mvwprintw(x_win, 5, 22, "1) Echo locally ........... %s", param->lecho); X mvwprintw(x_win, 6, 22, "2) Expand blank lines ..... %s", param->expand); X mvwprintw(x_win, 7, 22, "3) CR delay (ms) .......... %d", param->cr_delay); X mvwprintw(x_win, 8, 22, "4) Pace the output ........ %s", param->pace); X mvwprintw(x_win, 9, 22, "5) CR translation ......... %s", param->cr_up); X mvwprintw(x_win, 10, 22, "6) LF translation ......... %s", param->lf_up); X mvwaddstr(x_win, 12, 32, "ASCII DOWNLOAD"); X mvwprintw(x_win, 14, 22, "7) Transfer timeout ....... %d", param->timer); X mvwprintw(x_win, 15, 22, "8) CR translation ......... %s", param->cr_dn); X mvwprintw(x_win, 16, 22, "9) LF translation ......... %s", param->lf_dn); X mvwprintw(x_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(x_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(x_win, 20, 60, "Press ESC to return"); X wmove(x_win, 20, 12); X touchwin(x_win); X wrefresh(x_win); X /* get the option number */ X ret_code = 0; X while ((i = get_num(x_win, 1)) != -1) { X switch(i) { X case 1: X if ((ans = menu_prompt(x_win, 5, 50, "Echo locally", v_yes)) != NULL) { X free_ptr(param->lecho); X param->lecho = strdup(ans); X ret_code++; X } X break; X case 2: X if ((ans = menu_prompt(x_win, 6, 50, "Expand blank lines", v_yes)) != NULL) { X free_ptr(param->expand); X param->expand = strdup(ans); X ret_code++; X } X break; X case 3: X if ((ans = menu_prompt(x_win, 7, 50, "CR delay (ms)", v_delay)) != NULL) { X param->cr_delay = atoi(ans); X ret_code++; X } X break; X case 4: X if ((ans = menu_prompt(x_win, 8, 50, "Pace the output", v_yes)) != NULL) { X free_ptr(param->pace); X param->pace = strdup(ans); X ret_code++; X } X break; X case 5: X if ((ans = menu_prompt(x_win, 9, 50, "CR translation (upload)", v_cr)) != NULL) { X free_ptr(param->cr_up); X param->cr_up = strdup(ans); X ret_code++; X } X break; X case 6: X if ((ans = menu_prompt(x_win, 10, 50, "LF translation (upload)", v_lf)) != NULL) { X free_ptr(param->lf_up); X param->lf_up = strdup(ans); X ret_code++; X } X break; X case 7: X if ((num = num_prompt(x_win, 14, 50, "Transfer timeout", NULL)) != -1) { X if (num > MAX_TIMER || num < MIN_TIMER) { X beep(); X /* some reasonable range of values */ X if (num < MIN_TIMER) X num = MIN_TIMER; X else X num = MAX_TIMER; X mvwaddstr(x_win, 14, 50, " "); X wrefresh(x_win); X mvwattrnum(x_win, 14, 50, A_BOLD, num); X wrefresh(x_win); X } X param->timer = num; X ret_code++; X } X break; X case 8: X if ((ans = menu_prompt(x_win, 15, 50, "CR translation (download)", v_cr)) != NULL) { X free_ptr(param->cr_dn); X param->cr_dn = strdup(ans); X ret_code++; X } X break; X case 9: X if ((ans = menu_prompt(x_win, 16, 50, "LF translation (download)", v_lf)) != NULL) { X free_ptr(param->lf_dn); X param->lf_dn = strdup(ans); X ret_code++; X } X break; X default: X beep(); X } X mvwaddch(x_win, 20, 12, ' '); X clear_line(x_win, 21, 0, 0); X clear_line(x_win, 22, 0, 0); X wmove(x_win, 20, 12); X wrefresh(x_win); X } X delwin(x_win); X return(ret_code); X} SHAR_EOF if test 3885 -ne "`wc -c < 's_axfer.c'`" then echo shar: "error transmitting 's_axfer.c'" '(should have been 3885 characters)' fi fi echo shar: "extracting 's_gen.c'" '(4267 characters)' if test -f 's_gen.c' then echo shar: "will not over-write existing file 's_gen.c'" else sed 's/^X//' << \SHAR_EOF > 's_gen.c' X/* X * Display the general setup, query for changes. A return code of 1 X * means something was changed. X */ X X#include X#include X#include "misc.h" X#include "param.h" X Xint Xgen_setup() X{ X WINDOW *g_win, *newwin(); X int i, num, ret_code; X char c, *ans, *str_prompt(), *menu_prompt(), chr_prompt(); X char *strdup(); X void free_ptr(); X extern char *v_yes[], *v_abort[]; X X g_win = newwin(23, 80, 0, 0); X X waddstr(g_win, "--------------------------------- "); X wattrstr(g_win, A_BOLD, "General Setup"); X waddstr(g_win, " --------------------------------"); X mvwprintw(g_win, 3, 22, "1) Default log file ....... %s", param->logfile); X mvwprintw(g_win, 4, 22, "2) Screen dump file ....... %s", param->dumpfile); X mvwprintw(g_win, 6, 22, "3) Strip high bit ........ %s", param->strip); X mvwprintw(g_win, 8, 22, "4) Pause character ........ %c", param->pause_char); X mvwprintw(g_win, 9, 22, "5) CR character ........... %c", param->cr_char); X mvwprintw(g_win, 10, 22, "6) CTRL character ......... %c", param->ctrl_char); X mvwprintw(g_win, 11, 22, "7) ESC character .......... %c", param->esc_char); X mvwprintw(g_win, 13, 22, "8) Aborted downloads ...... %s", param->abort); X mvwprintw(g_win, 15, 22, "9) Connect delay time ..... %d", param->cdelay); X mvwprintw(g_win, 16, 21, "10) Pause between redials .. %d", param->pause); X mvwprintw(g_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(g_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(g_win, 20, 60, "Press ESC to return"); X wmove(g_win, 20, 12); X touchwin(g_win); X wrefresh(g_win); X /* get the option number */ X ret_code = 0; X while ((i = get_num(g_win, 2)) != -1) { X switch(i) { X case 1: X if ((ans = str_prompt(g_win, 3, 50, "Default log file", NULL)) != NULL) { X free_ptr(param->logfile); X param->logfile = strdup(ans); X ret_code++; X } X break; X case 2: X if ((ans = str_prompt(g_win, 4, 50, "Default screen dump file", NULL)) != NULL) { X free_ptr(param->dumpfile); X param->dumpfile = strdup(ans); X ret_code++; X } X break; X case 3: X if ((ans = menu_prompt(g_win, 6, 50, "Strip high bit ?", v_yes)) != NULL) { X free_ptr(param->strip); X param->strip = strdup(ans); X ret_code++; X } X break; X case 4: X if ((c = chr_prompt(g_win, 8, 50, "Pause character", "1 second")) != NULL) { X param->pause_char = c; X ret_code++; X } X break; X case 5: X if ((c = chr_prompt(g_win, 9, 50, "CR character", "(carriage return)")) != NULL) { X param->cr_char = c; X ret_code++; X } X break; X case 6: X if ((c = chr_prompt(g_win, 10, 50, "CTRL character", "(control)")) != NULL) { X param->ctrl_char = c; X ret_code++; X } X break; X case 7: X if ((c = chr_prompt(g_win, 11, 50, "ESC character", "(escape)")) != NULL) { X param->esc_char = c; X ret_code++; X } X break; X case 8: X if ((ans = menu_prompt(g_win, 13, 50, "Aborted downloads", v_abort)) != NULL) { X free_ptr(param->abort); X param->abort = strdup(ans); X ret_code++; X } X break; X case 9: X if ((num = num_prompt(g_win, 15, 50, "Connect delay time", "in seconds")) != -1) { X if (num > MAX_CDELAY || num < MIN_CDELAY) { X beep(); X /* some reasonable range of values */ X if (num < MIN_CDELAY) X num = MIN_CDELAY; X else X num = MAX_CDELAY; X mvwaddstr(g_win, 15, 50, " "); X wrefresh(g_win); X mvwattrnum(g_win, 15, 50, A_BOLD, num); X wrefresh(g_win); X } X param->cdelay = num; X ret_code++; X } X break; X case 10: X if ((num = num_prompt(g_win, 16, 50, "Pause between redials", "in seconds")) != -1) { X if (num > MAX_PAUSE || num < MIN_PAUSE) { X beep(); X /* some reasonable range */ X if (num < MIN_PAUSE) X num = MIN_PAUSE; X else X num = MAX_PAUSE; X mvwaddstr(g_win, 16, 50, " "); X wrefresh(g_win); X mvwattrnum(g_win, 16, 50, A_BOLD, num); X wrefresh(g_win); X } X param->pause = num; X ret_code++; X } X break; X default: X beep(); X } X mvwaddstr(g_win, 20, 12, " "); X clear_line(g_win, 21, 0, 0); X clear_line(g_win, 22, 0, 0); X wmove(g_win, 20, 12); X wrefresh(g_win); X } X delwin(g_win); X return(ret_code); X} SHAR_EOF if test 4267 -ne "`wc -c < 's_gen.c'`" then echo shar: "error transmitting 's_gen.c'" '(should have been 4267 characters)' fi fi echo shar: "extracting 's_menu.c'" '(2698 characters)' if test -f 's_menu.c' then echo shar: "will not over-write existing file 's_menu.c'" else sed 's/^X//' << \SHAR_EOF > 's_menu.c' X/* X * Display the setup menu, prompts for a bunch of other menus. X */ X X#include X#include X#include "misc.h" X Xvoid Xsetup_menu(fd) Xint fd; X{ X WINDOW *s_win, *newwin(); X char *ans, *get_str(); X int param_flag, modem_flag; X void top_line(); X extern int xmc; X X s_win = newwin(23, 80, 0, 0); X X top_line(s_win); X mvwaddstr(s_win, 4, 30, "1) TTY Setup"); X mvwaddstr(s_win, 6, 30, "2) Modem Setup"); X mvwaddstr(s_win, 8, 30, "3) Terminal Setup"); X mvwaddstr(s_win, 10, 30, "4) General Setup"); X mvwaddstr(s_win, 12, 30, "5) ASCII Transfer Setup"); X mvwaddstr(s_win, 14, 30, "S) Save setup to disk"); X mvwaddstr(s_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(s_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(s_win, 20, 60, " Press ESC to exit"); X wmove(s_win, 20, 12); X wrefresh(s_win); X X param_flag = 0; X modem_flag = 0; X /* get the options */ X while ((ans = get_str(s_win, 1, "12345Ss", NULL)) != NULL) { X if (xmc > 0) { X clear_line(s_win, 0, 0, 0); X wrefresh(s_win); X } X switch(*ans) { X case '1': X if (tty_setup()) X modem_flag = 1; X break; X case '2': X if (modem_setup()) X modem_flag = 1; X break; X case '3': X if (term_setup()) X param_flag = 1; X break; X case '4': X if (gen_setup()) X param_flag = 1; X break; X case '5': X if (ascii_xfer_setup()) X param_flag = 1; X break; X case 's': X case 'S': X if (xmc > 0) X top_line(s_win); X if (param_flag || modem_flag) { X wmove(s_win, 22, 27); X /* X * Writes to disk are not critical, X * the changes are made in memory. X */ X if (param_flag) { X wattrstr(s_win, A_BLINK, "Updating Parameter File"); X wrefresh(s_win); X wait_key(s_win, 3); X if (update_param()) { X touchwin(s_win); X wrefresh(s_win); X } X } X if (modem_flag) { X wattrstr(s_win, A_BLINK, "Updating Modem Database"); X wrefresh(s_win); X wait_key(s_win, 3); X if (update_modem()) { X touchwin(s_win); X wrefresh(s_win); X } X } X clear_line(s_win, 22, 27, 0); X wrefresh(s_win); X } X break; X default: X beep(); X } X touchwin(s_win); X if (xmc > 0) X top_line(s_win); X X mvwaddch(s_win, 20, 12, ' '); X wmove(s_win, 20, 12); X wrefresh(s_win); X } X if (fd == -1) { X werase(s_win); X wrefresh(s_win); X } X delwin(s_win); X return; X} X X/* X * Put the top line on the window. X */ X Xvoid Xtop_line(win) XWINDOW *win; X{ X clear_line(win, 0, 0, 0); X wrefresh(win); X waddstr(win, "---------------------------------- "); X wattrstr(win, A_BOLD, "Setup Menu"); X waddstr(win, " ----------------------------------"); X wrefresh(win); X return; X} SHAR_EOF if test 2698 -ne "`wc -c < 's_menu.c'`" then echo shar: "error transmitting 's_menu.c'" '(should have been 2698 characters)' fi fi echo shar: "extracting 's_modem.c'" '(6556 characters)' if test -f 's_modem.c' then echo shar: "will not over-write existing file 's_modem.c'" else sed 's/^X//' << \SHAR_EOF > 's_modem.c' X/* X * Display the modem setup, query for changes. A return code of 1 means X * something was changed. X */ X X#include X#include X#include "misc.h" X#include "modem.h" X Xint Xmodem_setup() X{ X WINDOW *mo_win, *newwin(); X int i, j, ret_code, modem_prompt(); X char *ans, *strdup(), *str_prompt(); X void disp_modem(), free_ptr(); X /* the current modem */ X j = 0; X if (modem->m_cur != -1) X j = modem->m_cur; X X mo_win = newwin(23, 80, 0, 0); X X waddstr(mo_win, "---------------------------------- "); X wattrstr(mo_win, A_BOLD, "Modem Setup"); X waddstr(mo_win, " ---------------------------------"); X /* display the current settings */ X disp_modem(mo_win, j); X mvwprintw(mo_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(mo_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(mo_win, 20, 60, "Press ESC to return"); X wmove(mo_win, 20, 12); X touchwin(mo_win); X wrefresh(mo_win); X /* get the option number */ X ret_code = 0; X while ((i = get_num(mo_win, 2)) != -1) { X switch(i) { X case 1: X j = modem_prompt(mo_win); X break; X case 2: X if ((ans = str_prompt(mo_win, 4, 40, "Modem init string", "sent to the modem once")) != NULL) { X free_ptr(modem->init[j]); X modem->init[j] = strdup(ans); X ret_code++; X } X break; X case 3: X if ((ans = str_prompt(mo_win, 5, 40, "Dialing command", NULL)) != NULL) { X free_ptr(modem->dial[j]); X modem->dial[j] = strdup(ans); X ret_code++; X } X break; X case 4: X if ((ans = str_prompt(mo_win, 6, 40, "Dialing cmd suffix", "typically the CR character")) != NULL) { X free_ptr(modem->suffix[j]); X modem->suffix[j] = strdup(ans); X ret_code++; X } X break; X case 5: X if ((ans = str_prompt(mo_win, 7, 40, "Hangup string", NULL)) != NULL) { X free_ptr(modem->hangup[j]); X modem->hangup[j] = strdup(ans); X ret_code++; X } X break; X case 6: X if ((ans = str_prompt(mo_win, 8, 40, "300 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_3[j]); X modem->con_3[j] = strdup(ans); X ret_code++; X } X break; X case 7: X if ((ans = str_prompt(mo_win, 9, 40, "1200 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_12[j]); X modem->con_12[j] = strdup(ans); X ret_code++; X } X break; X case 8: X if ((ans = str_prompt(mo_win, 10, 40, "2400 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_24[j]); X modem->con_24[j] = strdup(ans); X ret_code++; X } X break; X case 9: X if ((ans = str_prompt(mo_win, 11, 40, "4800 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_48[j]); X modem->con_48[j] = strdup(ans); X ret_code++; X } X break; X case 10: X if ((ans = str_prompt(mo_win, 12, 40, "9600 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_96[j]); X modem->con_96[j] = strdup(ans); X ret_code++; X } X break; X case 11: X if ((ans = str_prompt(mo_win, 13, 40, "19200 baud connect string", NULL)) != NULL) { X free_ptr(modem->con_192[j]); X modem->con_192[j] = strdup(ans); X ret_code++; X } X break; X case 12: X if ((ans = str_prompt(mo_win, 14, 40, "No connect string 1", NULL)) != NULL) { X free_ptr(modem->no_con1[j]); X modem->no_con1[j] = strdup(ans); X ret_code++; X } X break; X case 13: X if ((ans = str_prompt(mo_win, 15, 40, "No connect string 2", NULL)) != NULL) { X free_ptr(modem->no_con2[j]); X modem->no_con2[j] = strdup(ans); X ret_code++; X } X break; X case 14: X if ((ans = str_prompt(mo_win, 16, 40, "No connect string 3", NULL)) != NULL) { X free_ptr(modem->no_con3[j]); X modem->no_con3[j] = strdup(ans); X ret_code++; X } X break; X case 15: X if ((ans = str_prompt(mo_win, 17, 40, "No connect string 4", NULL)) != NULL) { X free_ptr(modem->no_con4[j]); X modem->no_con4[j] = strdup(ans); X ret_code++; X } X break; X default: X beep(); X } X /* clear the previous prompts */ X mvwaddstr(mo_win, 20, 12, " "); X clear_line(mo_win, 21, 0, 0); X clear_line(mo_win, 22, 0, 0); X wmove(mo_win, 20, 12); X wrefresh(mo_win); X } X delwin(mo_win); X return(ret_code); X} X X/* X * Prompts for the modem name. The user selects the currently showing X * choice by hitting a carriage return. Returns the modem entry number. X * DOES NOT change the value of modem->m_cur. X */ X Xint Xmodem_prompt(win) XWINDOW *win; X{ X char ans; X int i; X /* print prompt lines */ X mvwaddstr(win, 22, 0, "Press any key to change, or to accept"); X mvwaddstr(win, 21, 0, "Modem name: "); X /* show current choice */ X i = 0; X if (modem->m_cur != -1) X i = modem->m_cur; X mvwprintw(win, 21, 12, "%-30.30s", modem->mname[i]); X wmove(win, 21, 12); X wrefresh(win); X /* show the choices one at a time */ X while ((ans = wgetch(win)) != '\r') { X i++; X if (*modem->mname[i] == NULL) X i = 0; X if (ans == 27) X return(0); X mvwprintw(win, 21, 12, "%-30.30s", modem->mname[i]); X wmove(win, 21, 12); X wrefresh(win); X } X /* display the new values */ X disp_modem(win, i); X /* display the name in bold */ X clear_line(win, 2, 40, 0); X wrefresh(win); X mvwattrstr(win, 2, 40, A_BOLD, modem->mname[i]); X X return(i); X} X X/* X * Show the current settings for the given modem entry number. X */ X Xvoid Xdisp_modem(w, i) XWINDOW *w; Xint i; X{ X mvwprintw(w, 2, 12, "1) Modem name ............. %-39.39s", modem->mname[i]); X mvwprintw(w, 4, 12, "2) Modem init string ...... %-39.39s", modem->init[i]); X mvwprintw(w, 5, 12, "3) Dialing command ........ %-39.39s", modem->dial[i]); X mvwprintw(w, 6, 12, "4) Dialing cmd suffix ..... %-39.39s", modem->suffix[i]); X mvwprintw(w, 7, 12, "5) Hangup string .......... %-39.39s", modem->hangup[i]); X mvwprintw(w, 8, 12, "6) 300 baud connect ....... %-39.39s", modem->con_3[i]); X mvwprintw(w, 9, 12, "7) 1200 baud connect ...... %-39.39s", modem->con_12[i]); X mvwprintw(w, 10, 12, "8) 2400 baud connect ...... %-39.39s", modem->con_24[i]); X mvwprintw(w, 11, 12, "9) 4800 baud connect ...... %-39.39s", modem->con_48[i]); X mvwprintw(w, 12, 11, "10) 9600 baud connect ...... %-39.39s", modem->con_96[i]); X mvwprintw(w, 13, 11, "11) 19200 baud connect ..... %-39.39s", modem->con_192[i]); X mvwprintw(w, 14, 11, "12) No connect string 1 .... %-39.39s", modem->no_con1[i]); X mvwprintw(w, 15, 11, "13) No connect string 2 .... %-39.39s", modem->no_con2[i]); X mvwprintw(w, 16, 11, "14) No connect string 3 .... %-39.39s", modem->no_con3[i]); X mvwprintw(w, 17, 11, "15) No connect string 4 .... %-39.39s", modem->no_con4[i]); X return; X} SHAR_EOF if test 6556 -ne "`wc -c < 's_modem.c'`" then echo shar: "error transmitting 's_modem.c'" '(should have been 6556 characters)' fi fi echo shar: "extracting 's_prompt.c'" '(3369 characters)' if test -f 's_prompt.c' then echo shar: "will not over-write existing file 's_prompt.c'" else sed 's/^X//' << \SHAR_EOF > 's_prompt.c' X/* X * Prompting routines used in the setup menus. X */ X X#include X#include X#include "misc.h" X X/* X * Prompt for a string at line 21 (with optional line 22 for additional X * information). Display the new string in bold at its original location X * in the menu. Used in virtually all of the *_setup() routines. X */ X Xchar * Xstr_prompt(win, y, x, p1, p2) XWINDOW *win; Xint y, x; Xchar *p1, *p2; X{ X char *ans, *get_str(); X extern char *null_ptr; X /* print first prompt last */ X mvwaddstr(win, 22, 0, p2); X mvwaddstr(win, 21, 0, p1); X waddstr(win, ": "); X wrefresh(win); X X if ((ans = get_str(win, 39, NULL, NULL)) == NULL) X return(NULL); X /* check the value */ X if (!strcmp(ans, " ")) X ans = null_ptr; X /* display the value in bold */ X clear_line(win, y, x, 0); X wattrstr(win, A_BOLD, ans); X X return(ans); X} X X/* X * Same as above, except we return a single character. X */ X Xchar Xchr_prompt(win, y, x, p1, p2) XWINDOW *win; Xint y, x; Xchar *p1, *p2; X{ X char *ans, *get_str(); X /* print first prompt last */ X mvwaddstr(win, 22, 0, p2); X mvwaddstr(win, 21, 0, p1); X waddstr(win, ": "); X wrefresh(win); X X if ((ans = get_str(win, 1, NULL, NULL)) == NULL) X return(NULL); X /* display the value in bold */ X mvwaddstr(win, y, x, " "); X wrefresh(win); X mvwattrstr(win, y, x, A_BOLD, ans); X X return(*ans); X} X X/* X * Same as above, except that it prompts for a three digit number. X */ X Xint Xnum_prompt(win, y, x, p1, p2) XWINDOW *win; Xint y, x; Xchar *p1, *p2; X{ X int i, get_num(); X /* print first prompt last */ X mvwaddstr(win, 22, 0, p2); X mvwaddstr(win, 21, 0, p1); X waddstr(win, ": "); X wrefresh(win); X X if ((i = get_num(win, 3)) == -1) X return(-1); X /* display the value in bold */ X mvwaddstr(win, y, x, " "); X wrefresh(win); X mvwattrnum(win, y, x, A_BOLD, i); X /* return the number */ X return(i); X} X X/* X * Prompts for a selection from a menu. We display the prompt lines, X * and show the choices one at a time. The user selects the currently X * showing choice by hitting a carriage return. Unlike the similar X * routines in d_prompt(), the first choice shown is not necessarily X * the current. X */ X Xchar *v_yes[3] = {"YES", "NO", NULL}; Xchar *v_crio[3] = {"CR", "CR/LF", NULL}; Xchar *v_cr[4] = {"NONE", "STRIP", "ADD LF", NULL}; Xchar *v_lf[4] = {"NONE", "STRIP", "ADD CR", NULL}; Xchar *v_abort[3] = {"KEEP", "DELETE", NULL}; Xchar *v_duplex[3] = {"FULL", "HALF", NULL}; Xchar *v_flow[3] = {"NONE", "XON/XOFF", NULL}; Xchar *v_baud[7] = {"300", "1200", "2400", "4800", "9600", "19200", NULL}; Xchar *v_delay[4] = {"0", "100", "150", NULL}; X Xchar * Xmenu_prompt(win, y, x, p, menu) XWINDOW *win; Xint y, x; Xchar *p, *menu[]; X{ X char ans; X int i, cy, cx; X /* print first prompt last */ X mvwaddstr(win, 22, 0, "Press any key to change, or to accept"); X mvwaddstr(win, 21, 0, p); X waddstr(win, ": "); X /* show first choice */ X i = 0; X getyx(win, cy, cx); X mvwprintw(win, cy, cx, "%-30.30s", menu[i]); X wmove(win, cy, cx); X wrefresh(win); X /* show the choices one at a time */ X while ((ans = wgetch(win)) != '\r') { X i++; X if (*menu[i] == NULL) X i = 0; X if (ans == 27) X return(NULL); X mvwprintw(win, cy, cx, "%-30.30s", menu[i]); X wmove(win, cy, cx); X wrefresh(win); X } X /* display the value in bold */ X clear_line(win, y, x, 0); X wattrstr(win, A_BOLD, menu[i]); X /* return the value */ X return(menu[i]); X} SHAR_EOF if test 3369 -ne "`wc -c < 's_prompt.c'`" then echo shar: "error transmitting 's_prompt.c'" '(should have been 3369 characters)' fi fi echo shar: "extracting 's_term.c'" '(2743 characters)' if test -f 's_term.c' then echo shar: "will not over-write existing file 's_term.c'" else sed 's/^X//' << \SHAR_EOF > 's_term.c' X/* X * Display the terminal setup, query for changes. A return code of 1 X * means something was changed. X */ X X#include X#include X#include "misc.h" X#include "param.h" X Xint Xterm_setup() X{ X WINDOW *t_win, *newwin(); X int i, num, ret_code; X char *ans, *strdup(), *str_prompt(), *menu_prompt(); X void free_ptr(); X extern char *v_duplex[], *v_crio[], *v_flow[]; X X t_win = newwin(23, 80, 0, 0); X X waddstr(t_win, "-------------------------------- "); X wattrstr(t_win, A_BOLD, "Terminal Setup"); X waddstr(t_win, " --------------------------------"); X mvwprintw(t_win, 4, 22, "1) Hot key ................ %d", param->hot); X mvwprintw(t_win, 6, 22, "2) ASCII version of hot ... %s", param->ascii_hot); X mvwprintw(t_win, 9, 22, "3) Duplex ................. %s", param->d_duplex); X mvwprintw(t_win, 11, 22, "4) Flow control ........... %s", param->flow); X mvwprintw(t_win, 13, 22, "5) CR translation (in) .... %s", param->cr_in); X mvwprintw(t_win, 15, 22, "6) CR translation (out) ... %s", param->cr_out); X mvwprintw(t_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(t_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(t_win, 20, 60, "Press ESC to return"); X wmove(t_win, 20, 12); X touchwin(t_win); X wrefresh(t_win); X /* get the option number */ X ret_code = 0; X while ((i = get_num(t_win, 1)) != -1) { X switch(i) { X case 1: X if ((num = num_prompt(t_win, 4, 50, "Hot key", "decimal code for the hot key")) != -1) { X param->hot = num; X ret_code = 1; X } X break; X case 2: X if ((ans = str_prompt(t_win, 6, 50, "ASCII version of hot key", "(printable version)")) != NULL) { X free_ptr(param->ascii_hot); X param->ascii_hot = strdup(ans); X ret_code = 1; X } X break; X case 3: X if ((ans = menu_prompt(t_win, 9, 50, "Duplex", v_duplex)) != NULL ) { X free_ptr(param->d_duplex); X param->d_duplex = strdup(ans); X ret_code = 1; X } X break; X case 4: X if ((ans = menu_prompt(t_win, 11, 50, "Flow control", v_flow)) != NULL ) { X free_ptr(param->flow); X param->flow = strdup(ans); X ret_code = 1; X } X break; X case 5: X if ((ans = menu_prompt(t_win, 13, 50, "CR translation (in)", v_crio)) != NULL ) { X free_ptr(param->cr_in); X param->cr_in = strdup(ans); X ret_code = 1; X } X break; X case 6: X if ((ans = menu_prompt(t_win, 15, 50, "CR translation (out)", v_crio)) != NULL ) { X free_ptr(param->cr_out); X param->cr_out = strdup(ans); X ret_code = 1; X } X break; X default: X beep(); X } X mvwaddch(t_win, 20, 12, ' '); X clear_line(t_win, 21, 0, 0); X clear_line(t_win, 22, 0, 0); X wmove(t_win, 20, 12); X wrefresh(t_win); X } X delwin(t_win); X return(ret_code); X} SHAR_EOF if test 2743 -ne "`wc -c < 's_term.c'`" then echo shar: "error transmitting 's_term.c'" '(should have been 2743 characters)' fi fi echo shar: "extracting 's_tty.c'" '(4775 characters)' if test -f 's_tty.c' then echo shar: "will not over-write existing file 's_tty.c'" else sed 's/^X//' << \SHAR_EOF > 's_tty.c' X/* X * Display the tty setup, query for changes. A return code of 1 X * means something was changed. X */ X X#include X#include X#include "misc.h" X#include "modem.h" X#include "status.h" X Xint Xtty_setup() X{ X WINDOW *tt_win, *newwin(); X char *strdup(), buf[80]; X int num, i, j, ret_code; X void disp_tty(), create_modem(), delete_modem(), error_win(); X void delete_tty(); X extern char *null_ptr; X X tt_win = newwin(23, 80, 0, 0); X X waddstr(tt_win, "----------------------------------- "); X wattrstr(tt_win, A_BOLD, "TTY Setup"); X waddstr(tt_win, " ----------------------------------"); X mvwaddstr(tt_win, 2, 22, "TTY name"); X mvwaddstr(tt_win, 2, 37, "Modem name"); X mvwaddstr(tt_win, 2, 51, "Maximum baud"); X /* display the current tty list */ X disp_tty(tt_win); X /* prompt for options */ X mvwprintw(tt_win, 15, 20, "%d) Add a TTY entry", NUM_TTY+1); X mvwprintw(tt_win, 16, 20, "%d) Delete a TTY entry", NUM_TTY+2); X mvwprintw(tt_win, 19, 0, "--------------------------------------------------------------------------------"); X mvwattrstr(tt_win, 20, 0, A_BOLD, "OPTION ==> "); X mvwaddstr(tt_win, 20, 60, "Press ESC to return"); X wmove(tt_win, 20, 12); X touchwin(tt_win); X wrefresh(tt_win); X /* get the option number */ X ret_code = 0; X while ((i = get_num(tt_win, 2)) != -1) { X /* if beyond t_entries, fake it */ X if (i>modem->t_entries && i<=NUM_TTY) X i=999; X /* change an entry */ X if (i>=1 && i<=NUM_TTY) { X if (tty_prompt(tt_win, i-1)) X break; X /* requires modem update ? */ X create_modem(modem->tname[i-1]); X delete_modem(); X X ret_code++; X } X /* add a entry */ X if (i == NUM_TTY+1) { X if (modem->t_entries == NUM_TTY) { X sprintf(buf, "'%s'", status->m_path); X error_win(0, "No empty TTY slots in", buf); X continue; X } X /* prompt for info */ X j = modem->t_entries; X if (tty_prompt(tt_win, j)) X break; X /* add modem entry ? */ X modem->t_entries++; X create_modem(modem->tname[j]); X X ret_code++; X } X /* delete an entry */ X if (i == NUM_TTY+2) { X mvwaddstr(tt_win, 21, 0, "Entry number to delete: "); X wrefresh(tt_win); X while ((num = get_num(tt_win, 4)) != -1) { X /* valid range */ X if (!num || num>modem->t_entries) { X beep(); X mvwaddstr(tt_win, 21, 24, " "); X wrefresh(tt_win); X continue; X } X delete_tty(num-1); X delete_modem(); X X /* show the new list */ X disp_tty(tt_win); X ret_code = 1; X } X X } X if (i == 0 || i>NUM_TTY+2) X beep(); X mvwaddstr(tt_win, 20, 12, " "); X clear_line(tt_win, 21, 0, 0); X clear_line(tt_win, 22, 0, 0); X wmove(tt_win, 20, 12); X wrefresh(tt_win); X } X delwin(tt_win); X return(ret_code); X} X X/* X * Display the current tty list. No scrolling yet, so if your NUM_TTY is X * greater than ten, this routine will need some work. X */ X Xvoid Xdisp_tty(win) XWINDOW *win; X{ X int i; X X for (i=0; itty[i], modem->tname[i], modem->mbaud[i]); X return; X} X X/* X * Prompt the user for the TTY database info. A return code of 1 means a X * user abort. The second argument is the zero based index. X */ X Xtty_prompt(win, i) XWINDOW *win; Xint i; X{ X char *ans, *temp_tty, *temp_tname, *str_prompt(), *menu_prompt(); X extern char *v_baud[]; X void free_ptr(); X /* get temp tty */ X if ((ans = str_prompt(win, i+4, 24, "TTY name", NULL)) == NULL) X return(1); X X temp_tty = strdup(ans); X clear_line(win, 21, 0, 0); X X /* get temp tname */ X if ((ans = str_prompt(win, i+4, 39, "Modem name", NULL)) == NULL) X return(1); X X temp_tname = strdup(ans); X clear_line(win, 21, 0, 0); X X /* get maximum baud */ X if ((ans = menu_prompt(win, i+4, 55, "Maximum baud", v_baud)) == NULL) X return(1); X X wrefresh(win); X /* store 'em for real */ X free_ptr(modem->tty[i]); X free_ptr(modem->tname[i]); X X modem->tty[i] = strdup(temp_tty); X modem->tname[i] = strdup(temp_tname); X modem->mbaud[i] = atoi(ans); X X free_ptr(temp_tty); X free_ptr(temp_tname); X return(0); X} X X/* X * Delete a tty entry. Since the list must be contiguous, we collapse the X * list to cover the hole we made. X */ X Xvoid Xdelete_tty(i) Xint i; X{ X int j; X char *strdup(); X void free_ptr(); X extern char *null_ptr; X /* collapse the list */ X for (j=i; jt_entries-1; j++) { X free_ptr(modem->tty[j]); X free_ptr(modem->tname[j]); X modem->tty[j] = strdup(modem->tty[j+1]); X modem->tname[j] = strdup(modem->tname[j+1]); X modem->mbaud[j] = modem->mbaud[j+1]; X } X j = modem->t_entries-1; X /* zap the entry */ X free_ptr(modem->tty[j]); X free_ptr(modem->tname[j]); X modem->tty[j] = null_ptr; X modem->tname[j] = null_ptr; X modem->mbaud[j] = 0; X /* update the count */ X modem->t_entries--; X if (modem->t_cur >= modem->t_entries) X modem->t_cur = -1; X return; X} SHAR_EOF if test 4775 -ne "`wc -c < 's_tty.c'`" then echo shar: "error transmitting 's_tty.c'" '(should have been 4775 characters)' fi fi echo shar: "extracting 'screen.c'" '(1421 characters)' if test -f 'screen.c' then echo shar: "will not over-write existing file 'screen.c'" else sed 's/^X//' << \SHAR_EOF > 'screen.c' X/* X * Routines to read and copy the virtual screen image file. X */ X X#define MAX_COL 128 X X#include X#include X#include "param.h" X#include "status.h" X X/* X * Do a screen dump. Actually, the screen is already dumped, all we X * do is copy the file. X */ X Xvoid Xscreen_dump() X{ X FILE *fp_in, *fp_out; X char buf[MAX_COL+2]; X void error_win(); X /* not guaranteed to exist yet */ X if (!(fp_in = fopen(status->vs_path, "r"))) X return; X /* open for append */ X if (!(fp_out = fopen(param->dumpfile, "a"))) { X fclose(fp_in); X sprintf(buf, "'%s' for write", param->dumpfile); X error_win(0, "Can't open screen dump file", buf); X return; X } X /* skip the x, y coordinates */ X fgets(buf, 10, fp_in); X X while (fgets(buf, MAX_COL+2, fp_in) != NULL) X fputs(buf, fp_out); X X fclose(fp_in); X fclose(fp_out); X X return; X} X X/* X * Read the virtual screen file and paint its contents to the X * stdscr with curses. Leave the cursor where it belongs. X */ X Xvoid Xload_vs() X{ X FILE *fp; X int row, col, i; X char buf[MAX_COL+2]; X /* not guaranteed to exist yet */ X if (!(fp = fopen(status->vs_path, "r"))) X return; X /* get the x, y coordinates */ X fgets(buf, 10, fp); X sscanf(buf, "%d,%d\n", &row, &col); X X clearok(stdscr, TRUE); X i = 0; X while (fgets(buf, MAX_COL+2, fp) != NULL) { X buf[COLS] = NULL; X mvaddstr(i++, 0, buf); X } X move(row, col); X refresh(); X clearok(stdscr, FALSE); X X fclose(fp); X return; X} SHAR_EOF if test 1421 -ne "`wc -c < 'screen.c'`" then echo shar: "error transmitting 'screen.c'" '(should have been 1421 characters)' fi fi echo shar: "extracting 'st_line.c'" '(1815 characters)' if test -f 'st_line.c' then echo shar: "will not over-write existing file 'st_line.c'" else sed 's/^X//' << \SHAR_EOF > 'st_line.c' X/* X * Display the status line. Up to now, we've never really cared how X * large the physical screen was... but now we want the status line X * on the bottom. X */ X X#include X#include "dial_dir.h" X#include "misc.h" X#include "modem.h" X#include "param.h" X#include "status.h" X Xvoid Xstatus_line(message) Xchar *message; X{ X WINDOW *sl_win, *newwin(); X int d, x, y; X static char *dn[2] = {"FDX", "HDX"}; X static char *ln[2] = {"LOG OFF", "LOG ON"}; X static char *pn[2] = {"PTR OFF", "PTR ON "}; X char buf[80], field_one[15], *cur_tty; X extern int xmc; X X /* X * Sometimes curses() doesn't remember where the cursor is on X * the screen, so we move it to the opposite corner to guarantee X * that the status line is on the bottom. X */ X getyx(stdscr, y, x); X move(0, COLS-1); X refresh(); X X sl_win = newwin(1, 80, LINES-1, 0); X /* duplex message */ X d = 0; X if (dir->duplex[dir->d_cur] == 'H') X d = 1; X /* the current tty */ X cur_tty = "No TTY"; X if (modem->t_cur != -1) X cur_tty = modem->tty[modem->t_cur]; X X /* X * The philosophy is: If you press a command sequence that X * doesn't generate a window on the screen, then show the user X * what's going on in the status line. X */ X if (message == NULL) X sprintf(field_one, " %4.4s-0 HELP ", param->ascii_hot); X else X sprintf(field_one, " %-13.13s", message); X X sprintf(buf, "%s | %-9.9s| %s | %5d %c%d%d | %-7.7s | %-7.7s | %-5.5s| %-5.5s", X field_one, cur_tty, dn[d], dir->baud[dir->d_cur], X dir->parity[dir->d_cur], dir->dbits[dir->d_cur], X dir->sbits[dir->d_cur], ln[status->log], pn[status->print], X param->cr_in, param->cr_out); X X if (xmc > 0) { X touchwin(sl_win); X werase(sl_win); X wrefresh(sl_win); X } X wattrstr(sl_win, A_STANDOUT, buf); X wrefresh(sl_win); X /* go ahead and delete it now */ X delwin(sl_win); X move(y, x); X return; X} SHAR_EOF if test 1815 -ne "`wc -c < 'st_line.c'`" then echo shar: "error transmitting 'st_line.c'" '(should have been 1815 characters)' fi fi echo shar: "extracting 'strings.c'" '(1349 characters)' if test -f 'strings.c' then echo shar: "will not over-write existing file 'strings.c'" else sed 's/^X//' << \SHAR_EOF > 'strings.c' X/* X * Miscellaneous string routines. X */ X X#include X X/* X * Do a fancy string copy. If NULL, return null. If pointer to NULL, then X * return the special 'null_ptr' variable. If a normal copy, allocate the X * memory first. X */ X Xchar * Xstrdup(str) Xchar *str; X{ X char *ret, *malloc(), *strcpy(); X extern char *null_ptr; X X if (str == NULL) X return(NULL); X /* if pointer to null */ X if (*str == NULL) X return(null_ptr); X X ret = malloc((unsigned int) strlen(str)+1); X strcpy(ret, str); X return(ret); X} X X/* X * Perform the free(2) function, but check for NULL and the special X * 'null_ptr' variable first. X */ X Xvoid Xfree_ptr(str) Xchar *str; X{ X extern char *null_ptr; X void free(); X X if (str != NULL && (long) str != (long) null_ptr) X free(str); X return; X} X X/* X * This routine is similar to strtok(3). But our version handles null X * strings and takes a single separator character as an argument. X * Returns a NULL on end of string or error. X */ X Xchar * Xstr_tok(str, c) Xchar *str, c; X{ X char *strchr(); X static char *ptr, *sep; X extern char *null_ptr; X /* start at beginning */ X if (str != NULL) X ptr = str; X else X ptr = sep; X /* at the end ? */ X if (*ptr == NULL) X return(NULL); X /* no separator ? */ X if (!(sep = strchr(ptr, c))) X return(NULL); X /* zap the sep, move past it */ X *sep = NULL; X sep++; X X return(ptr); X} SHAR_EOF if test 1349 -ne "`wc -c < 'strings.c'`" then echo shar: "error transmitting 'strings.c'" '(should have been 1349 characters)' fi fi echo shar: "extracting 'terminal.c'" '(8039 characters)' if test -f 'terminal.c' then echo shar: "will not over-write existing file 'terminal.c'" else sed 's/^X//' << \SHAR_EOF > 'terminal.c' X/* X * Start the terminal dialogue, fork the input routine, watch for the X * hot key so we can execute an option. X */ X X#include X#include X#include X#ifdef UNIXPC X#include X#include X#endif /* UNIXPC */ X#include "dial_dir.h" X#include "modem.h" X#include "param.h" X#include "status.h" X Xterminal(input_status) Xint input_status; X{ X int i, k, cr_lf; X char c, lf=10, *strdup(), *new_dir, *change_dir(); X void help_screen(), line_set(), native_shell(), load_vs(); X void setup_menu(), hang_up(), input_on(), list_dir(), pexit(); X void status_line(), free_ptr(), screen_dump(), input_off(); X X /* if starting out in command mode */ X if (!input_status) X status_line(NULL); X /* put the terminal in raw mode */ X resetterm(); X cr_lf = raw_mode(); X X if (input_status) X input_on(); X X while(1) { X read(0, &c, 1); X /* is it the hot key? */ X if (c == param->hot) { X /* suspend input */ X input_status = 0; X if (status->pid != -1) X kill(status->pid, SIGINT); X X /* X * Put in terminal in the curses mode and add X * the status line at the bottom. X */ X fixterm(); X status_line(NULL); X#ifndef OLDCURSES X keypad(stdscr, 1); X#endif /* OLDCURSES */ X i = wgetch(stdscr); X /* map the hot key to -1 */ X if (i == param->hot) X i = -1; X /* X * Load the virtual screen from the file. On X * very busy systems, the file might not "appear" X * fast enough for this routine to detect it. X * Or worse, it may contain partially written X * information. X */ X load_vs(); X /* look for options */ X k = -1; X switch (i) { X case -1: /* 2 'hots' means send 1 */ X k = param->hot; X break; X case '0': /* help screen */ X help_screen(param->ascii_hot, status->fd); X break; X case 'd': X case 'D': /* dialing directory */ X if (dial_menu()) X input_status = dial_win(); X break; X case 'r': X case 'R': /* redial */ X if (redial(status->fd)) X input_status = dial_win(); X break; X case 'p': X case 'P': /* line settings */ X if (line_set_menu(status->fd)) { X line_set(); X } X break; X case 'x': X case 'X': /* exit */ X pexit(status->fd); X break; X case '4': /* Unix gateway */ X native_shell(); X break; X case 'i': X case 'I': /* Program info screen */ X info(status->fd); X break; X case 's': /* setup menu */ X case 'S': X setup_menu(status->fd); X break; X case 'c': /* clear the screen */ X case 'C': X unlink(status->vs_path); X clear(); X clear_absolute(stdscr); X break; X case 'b': X case 'B': /* Change directory */ X if ((new_dir = change_dir(status->fd)) != NULL) { X chdir(new_dir); X free_ptr(new_dir); X } X break; X case 'e': X case 'E': /* toggle duplex */ X if (dir->duplex[dir->d_cur] == 'F') X dir->duplex[dir->d_cur] = 'H'; X else X dir->duplex[dir->d_cur] = 'F'; X line_set(); X X /* show changes */ X status_line(NULL); X k = wait_key(stdscr, 2); X break; X case 'h': X case 'H': /* hang up phone */ X hang_up(1); X input_off(); X break; X case 'l': X case 'L': /* toggle printer */ X status->print = status->print ? 0 : 1; X if (status->pid != -1) X kill(status->pid, SIGUSR2); X X /* show changes */ X status_line(NULL); X k = wait_key(stdscr, 2); X break; X case '3': /* toggle CR CR/LF */ X if (!strcmp(param->cr_in, "CR")) X param->cr_in = strdup("CR/LF"); X else X param->cr_in = strdup("CR"); X input_off(); X input_status = 1; X X /* show changes */ X status_line(NULL); X k = wait_key(stdscr, 2); X break; X case '7': /* break key */ X if (status->fd != -1) X ioctl(status->fd, TCSBRK, 0); X X status_line(" break"); X break; X#ifndef OLDCURSES X case KEY_UP: X#endif /* OLDCURSES */ X case 'u': X case 'U': /* send files */ X input_status = xfer_menu(1); X break; X#ifndef OLDCURSES X case KEY_DOWN: X case '\n': X#endif /* OLDCURSES */ X case 'n': X case 'N': /* receive files */ X input_status = xfer_menu(0); X break; X case 'f': X case 'F': /* list directory */ X list_dir(status->fd); X break; X case 'g': /* screen dump */ X case 'G': X screen_dump(); X status_line(" screen dump"); X k = wait_key(stdscr, 2); X break; X case '1': /* data logging */ X input_status = data_logging(status->fd); X break; X case '2': /* toggle log */ X if (!strcmp(status->log_path, "NOT_DEFINED")) { X beep(); X status_line(" no log file"); X k = wait_key(stdscr, 2); X break; X } X status->log = status->log ? 0 : 1; X if (status->pid != -1) X kill(status->pid, SIGUSR1); X X /* show changes */ X status_line(NULL); X k = wait_key(stdscr, 2); X break; X default: X fputc(7, stderr); X break; X } X X /* X * Repaint the stdscr (if we are already talking), X * get the terminal out of the curses mode and X * into the raw mode. X */ X if (status->fd != -1) { X touchwin(stdscr); X refresh(); X } X resetterm(); X cr_lf = raw_mode(); X /* re-start input routine */ X if (input_status) X input_on(); X else { X /* un-suspend (is that a word?) */ X if (status->pid != -1) X kill(status->pid, SIGINT); X } X /* X * If you pressed a key during one of the sleeping X * periods (typically the delay to see the status X * line change), let the keyboard value fall thru X * to the write() below. X */ X if (k == -1) X continue; X c = k; X } X write(status->fd, &c, 1); X /* map cr to cr_lf ? */ X if (cr_lf) X write(status->fd, &lf, 1); X } X} X X/* X * Put the terminal in the raw mode. We've divided up the responsibility X * for the line settings options between the serial port and the tty driver X * for the stdin and stdout. The return code is the cr_lf mapping. X */ X Xint Xraw_mode() X{ X int ret_code; X struct termio tbuf; X X ioctl(0, TCGETA, &tbuf); X X tbuf.c_cc[4] = 1; /* VMIN */ X tbuf.c_cc[5] = 0; /* VTIME */ X tbuf.c_iflag = 0; X tbuf.c_oflag = 0; X tbuf.c_lflag = 0; X X /* X * Some of the output processing options have to be faked... X * Unfortunately, adding a LF to CR is one of them. X */ X ret_code = 0; X if (!strcmp(param->cr_out, "CR/LF")) X ret_code++; X /* duplex */ X if (dir->duplex[dir->d_cur] == 'H') X tbuf.c_lflag = ECHO; X X ioctl(0, TCSETA, &tbuf); X ioctl(0, TCFLSH, 2); X return(ret_code); X} X X/* X * Fire up the input routine... X */ X Xvoid Xinput_on() X{ X int pid, add_lf; X /* if no tty, or already on */ X if (status->pid != -1 || status->fd == -1) X return; X /* input cr translations */ X add_lf = !strcmp(param->cr_in, "CR/LF"); X X /* fork the input routine */ X if (!(pid = fork())) X input(status->fd, add_lf, status->log, status->print, X LINES, COLS, status->vs_path, status->log_path); X X status->pid = pid; X return; X} X X/* X * shut it down... X */ X Xvoid Xinput_off() X{ X if (status->pid != -1) { X kill(status->pid, SIGTERM); X status->pid = -1; X } X return; X} X X/* X * Hang up the phone but remain in the pcomm command state. X */ X Xvoid Xhang_up(verbose) Xint verbose; X{ X void send_str(), status_line(); X#ifdef UNIXPC X char buf[20], *strcpy(), *strcat(); X#endif /* UNIXPC */ X X /* anything to hang up? */ X if (modem->m_cur == -1) X return; X X if (verbose) X status_line("disconnecting"); X /* special case for OBM */ X#ifdef UNIXPC X if (!strcmp(modem->mname[modem->m_cur], "OBM")) { X ioctl(status->fd, PIOCDISC); X /* X * The PIOCDISC ioctl prevents writes on the file descriptor! X * No other phone(7) ioctl can fix it... Whatever it does, it X * seems to escape detection with PIOCGETA and TCGETA. The X * best I can do is close the descriptor and start over. X */ X close(status->fd); X strcpy(buf, "/dev/"); X strcat(buf, modem->tty[modem->t_cur]); X status->fd = open(buf, O_RDWR|O_NDELAY); X fcntl(status->fd, F_SETFL, fcntl(status->fd, F_GETFL, 0) & ~O_NDELAY); X } X else X#endif /* UNIXPC */ X send_str(modem->hangup[modem->m_cur]); X X if (verbose) X status_line(NULL); X return; X} SHAR_EOF if test 8039 -ne "`wc -c < 'terminal.c'`" then echo shar: "error transmitting 'terminal.c'" '(should have been 8039 characters)' fi fi echo shar: "extracting 'x_ascii.c'" '(5950 characters)' if test -f 'x_ascii.c' then echo shar: "will not over-write existing file 'x_ascii.c'" else sed 's/^X//' << \SHAR_EOF > 'x_ascii.c' X/* X * Transfer a file using just XON/XOFF flow control. Currently limited to X * 7 bit ASCII codes. (If this causes too much trouble, I'll change it). X */ X X#include X#include X#include X#include X#include "param.h" X#include "status.h" X Xvoid Xxfer_ascii(list, up) Xchar *list; Xint up; X{ X int cr_lf; X char *file, *strtok(); X void send_ascii(), rcv_ascii(), line_set(), status_line(); X unsigned int sleep(); X X /* only one file from list */ X file = strtok(list, " "); X X cr_lf = ascii_mode(up); X if (up) { X /* un-suspend the input routine */ X if (status->pid != -1) X kill(status->pid, SIGINT); X X send_ascii(file, cr_lf); X /* re-suspend the input routine */ X if (status->pid != -1) X kill(status->pid, SIGINT); X } X else X rcv_ascii(file, cr_lf); X X /* X * Restoring the tty modes is easier than setting them... The X * fixterm() and line_set() routines fix most of the damage. X */ X fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NDELAY); X fixterm(); X line_set(); X sleep(1); X X status_line("xfer complete"); X sleep(2); X return; X} X X/* X * Put the tty line in a mode suitable for the ASCII transfer. Puts the X * terminal in the raw, non-blocking mode. Returns the status of the X * cr_lf parameter flag. X */ X Xint Xascii_mode(up) Xint up; X{ X int cr_lf; X struct termio tbuf; X void input_off(); X X ioctl(status->fd, TCGETA, &tbuf); X tbuf.c_oflag = 0; X /* flow control & 8th bit stripping */ X if (up) { X tbuf.c_iflag = (ISTRIP|IXON|IXANY); X X /* use NL delays if no CR */ X if (!strcmp(param->cr_up, "STRIP")) X tbuf.c_oflag = (OPOST|ONLRET); X X /* CR delay times */ X switch (param->cr_delay) { X case 0: X tbuf.c_oflag = 0; X break; X case 100: X tbuf.c_oflag |= (OPOST|CR2); X break; X case 150: X tbuf.c_oflag |= (OPOST|CR3); X break; X } X } X /* if down loading */ X else { X tbuf.c_iflag = (ISTRIP|IXOFF); X /* kill the input routine */ X input_off(); X } X X ioctl(status->fd, TCSETA, &tbuf); X ioctl(status->fd, TCFLSH, 2); X /* out of curses mode */ X resetterm(); X cr_lf = raw_mode(); X /* non-blocking mode */ X fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NDELAY); X return(cr_lf); X} X X/* X * Send a file. The local echo option is independent of the duplex option, X * and would very rarely be used since the characters are most likely X * being echoed on the screen anyway. X */ X Xvoid Xsend_ascii(file, cr_lf) Xchar *file; Xint cr_lf; X{ X FILE *fp; X int i, j, strip_cr, strip_lf, add_cr, add_lf, expand, last; X int lecho, pace; X unsigned int sleep(); X unsigned char c; X /* permission already checked */ X if (!(fp = fopen(file, "r"))) X return; X /* ASCII transfer options */ X strip_cr = !strcmp(param->cr_up, "STRIP"); X add_lf = !strcmp(param->cr_up, "ADD LF"); X strip_lf = !strcmp(param->lf_up, "STRIP"); X add_cr = !strcmp(param->lf_up, "ADD CR"); X expand = !strcmp(param->expand, "YES"); X lecho = !strcmp(param->lecho, "YES"); X pace = !strcmp(param->pace, "YES"); X X last = 0; X while ((i = fgetc(fp)) != EOF) { X /* any keyboard activity? */ X switch(j = getchar()) { X case -1: /* no key was pressed */ X break; X case 27: /* ESC key for abort */ X fclose(fp); X ioctl(status->fd, TCFLSH, 2); X return; X default: /* send the char */ X c = j; X putc_line(c); X if (c == 13 && cr_lf) X putc_line(10); X break; X } X c = i; X /* expand blank lines */ X if (expand && last == 10 && c == 10) X putc_line(' '); X last = c; X X /* CR translations */ X if (c == 13 && strip_cr) X continue; X if (c == 13 && add_lf) { X putc_line(c); X putc_line(10); X continue; X } X /* LF translations */ X if (c == 10 && strip_lf) X continue; X if (c == 10 && add_cr) { X putc_line(13); X putc_line(c); X continue; X } X putc_line(c); X /* X * There's really no mechanism for delaying characters X * going to the output, so we fake it by waiting for X * each character to clear the I/O buffer. X */ X if (pace) X ioctl(status->fd, TCSBRK, 1); X if (lecho) X write(1, (char *) &c, 1); X } X sleep(1); X ioctl(status->fd, TCSBRK, 1); X fclose(fp); X return; X} X X/* X * Receive a file. The timer is used to end the transfer. This is not X * that much different from the data logging option. The use of getc_line() X * and non-blocking input makes it seem like full duplex, but it's not. X * Beware that while the timer is active the keyboard is deaf. Input is X * NOT loaded into the virtual screen!! X */ X Xvoid Xrcv_ascii(file, cr_lf) Xchar *file; Xint cr_lf; X{ X FILE *fp; X int i, strip_cr, strip_lf, add_cr, add_lf, got_first; X unsigned int delay; X unsigned char c; X /* permission already checked */ X if (!(fp = fopen(file, "w"))) X return; X /* ASCII transfer options */ X strip_cr = !strcmp(param->cr_dn, "STRIP"); X add_lf = !strcmp(param->cr_dn, "ADD LF"); X strip_lf = !strcmp(param->lf_dn, "STRIP"); X add_cr = !strcmp(param->lf_dn, "ADD CR"); X X got_first = 0; X delay = 1; X while (1) { X /* keyboard activity */ X switch (i = getchar()) { X case -1: /* no key was pressed */ X break; X case 27: /* ESC key */ X fclose(fp); X return; X default: /* send it */ X c = i; X putc_line(c); X if (c == 13 && cr_lf) X putc_line(10); X break; X } X /* read a character */ X if ((i = getc_line(delay)) == -1) { X /* X * The transfer timeout is not activated until the X * first character is received. Until then, it polls X * the line for one second and loops backs for X * keyboard input. X */ X if (got_first) { X fclose(fp); X return; X } X continue; X } X got_first = 1; X delay = param->timer; X c = i & 0177; X /* display it on the screen */ X write(1, (char *) &c, 1); X /* CR translations */ X if (c == 13 && strip_cr) X continue; X if (c == 13 && add_lf) { X fputc((char) c, fp); X fputc(10, fp); X continue; X } X /* LF translations */ X if (c == 10 && strip_lf) X continue; X if (c == 10 && add_cr) { X fputc(13, fp); X fputc((char) c, fp); X continue; X } X fputc((char) c, fp); X } X} SHAR_EOF if test 5950 -ne "`wc -c < 'x_ascii.c'`" then echo shar: "error transmitting 'x_ascii.c'" '(should have been 5950 characters)' fi fi exit 0 # End of shell archive