home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-13 | 96.7 KB | 4,104 lines |
- Newsgroups: comp.sources.unix
- From: fthood!egray@uxc.cso.uiuc.edu (Emmet Gray)
- Subject: v26i155: pcomm-2.0.2 - a serial communications program (clone of ProComm), Part03/06
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: fthood!egray@uxc.cso.uiuc.edu (Emmet Gray)
- Posting-Number: Volume 26, Issue 155
- Archive-Name: pcomm-2.0.2/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 6)."
- # Contents: Makefile cmd.c d_lib.c d_menu.c input.c p_lib.c s_modem.c
- # terminal.c x_ascii.c x_batch.c x_menu.c xmodem.c
- # Wrapped by vixie@gw.home.vix.com on Wed Apr 14 00:38:42 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(6622 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# PCOMM v2.0
- X# for generic SVR4
- X
- X#for 80286 versions of SCO Xenix
- X#CFLAGS = -Od -DM_TERMINFO -Mle2 -LARGE
- X#LDFLAGS = -SEG 1000 -F 5000 -Mle2
- X#CURSES = -ltinfo -lx
- X
- X#for 80386 versions of SCO Xenix
- X#CFLAGS = -O -DM_TERMINFO
- X#LDFLAGS = -s
- X#CURSES = -ltinfo -lx
- X
- X#for the AT&T Unix PC 7300/3b1
- X#LD = ld
- X#SHLIB = /lib/crt0s.o /lib/shlib_c.ifile
- X#OTHER = /lib/setvbuf.o /lib/doprnt.o -luipc
- X
- X#for Sun OS (using the System V compiler)
- X#CC = /usr/5bin/cc
- X#LD = /usr/5bin/cc
- X
- LD = cc
- SHLIB =
- OTHER =
- CFLAGS = -O
- LDFLAGS = -s
- SHAR = shar -a
- X
- BIN_DIR = /usr/local/bin
- MAN_DIR = /usr/man1
- MAN_EXT = 1
- PCOMM_LIB = /usr/local/lib/pcomm
- X
- X#for old curses (i.e. Berkeley systems)
- X#CURSES = -lcurses -ltermcap
- CURSES = -lcurses
- X
- X#for systems without getcwd(3) or getopt(3)
- X#GETCWD.O = getcwd.o
- X#GETCWD.C = getcwd.c
- X#GETOPT.O = getopt.o
- X#GETOPT.C = getopt.c
- X
- X#for System V or Berkeley TTY interface
- X#TTY.O = tty_ucb.o
- X#TTY.C = tty_ucb.c
- TTY.O = tty_att.o
- TTY.C = tty_att.c
- X
- X#for System V poll() or Berkeley select()
- X#IPC.O = ipc_ucb.o
- X#IPC.C = ipc_ucb.c
- IPC.O = ipc_att.o
- IPC.C = ipc_att.c
- X
- PCOMM = $(GETCWD.O) $(GETOPT.O) $(TTY.O) $(IPC.O) admin.o chg_dir.o cmd.o \
- X curses.o d_delete.o d_lib.o d_manual.o d_menu.o d_print.o \
- X d_prompt.o d_revise.o data_log.o di_delay.o di_win.o dial.o \
- X e_lib.o expand.o help.o info.o init.o input.o list_dir.o ls_menu.o \
- X m_lib.o macro.o main.o n_shell.o p_lib.o passthru.o pexit.o \
- X port.o redial.o s_axfer.o s_extrnl.o s_gen.o s_menu.o s_modem.o \
- X s_prompt.o s_term.o s_tty.o screen.o script.o st_line.o \
- X strings.o terminal.o vcs.o x_ascii.o x_batch.o x_extrnl.o \
- X x_menu.o x_rcv.o x_send.o x_win.o xmodem.o
- X
- all: pcomm waitfor matches pcomm_cmd
- X
- pcomm: $(PCOMM)
- X $(LD) $(LDFLAGS) $(PCOMM) $(OTHER) -o pcomm $(CURSES) $(SHLIB)
- X
- waitfor: waitfor.o
- X $(LD) $(LDFLAGS) waitfor.o -o waitfor $(SHLIB)
- X
- matches: matches.o
- X $(LD) $(LDFLAGS) matches.o -o matches $(SHLIB)
- X
- pcomm_cmd: pcomm_cmd.o
- X $(LD) $(LDFLAGS) pcomm_cmd.o -o pcomm_cmd $(SHLIB)
- X
- pcomm_cmd.o:
- X $(CC) $(CFLAGS) -DIPC=\"$(IPC.C)\" -c pcomm_cmd.c
- X
- install:
- X cp pcomm waitfor matches pcomm_cmd $(BIN_DIR)
- X# obviously this requires super-user privelidges...
- X# chmod 4755 $(BIN_DIR)/pcomm
- X# chown uucp $(BIN_DIR)/pcomm
- X
- install_man:
- X cp Pcomm.1 $(MAN_DIR)/pcomm.$(MAN_EXT)
- X cp Pcomm_cmd.1 $(MAN_DIR)/pcomm_cmd.$(MAN_EXT)
- X cp Waitfor.1 $(MAN_DIR)/waitfor.$(MAN_EXT)
- X cp Matches.1 $(MAN_DIR)/matches.$(MAN_EXT)
- X
- install_support:
- X cp Pcomm.dial_dir $(PCOMM_LIB)/pcomm.dial_dir
- X cp Pcomm.modem $(PCOMM_LIB)/pcomm.modem
- X cp Pcomm.param $(PCOMM_LIB)/pcomm.param
- X cp Pcomm.extrnl $(PCOMM_LIB)/pcomm.extrnl
- X
- clean:
- X rm pcomm waitfor matches pcomm_cmd
- X
- lint:
- X lint -p -Dlint $(GETCWD.C) $(GETOPT.C) $(TTY.C) $(IPC.C) admin.c \
- X chg_dir.c cmd.c curses.c d_delete.c d_lib.c d_manual.c d_menu.c \
- X d_print.c d_prompt.c d_revise.c data_log.c di_delay.c di_win.c \
- X dial.c e_lib.c expand.c help.c info.c init.c input.c list_dir.c \
- X ls_menu.c m_lib.c macro.c main.c n_shell.c p_lib.c passthru.c \
- X pexit.c port.c redial.c s_axfer.c s_extrnl.c s_gen.c s_menu.c \
- X s_modem.c s_prompt.c s_term.c s_tty.c screen.c script.c \
- X st_line.c strings.c terminal.c vcs.c x_ascii.c x_batch.c \
- X x_extrnl.c x_menu.c x_rcv.c x_send.c x_win.c xmodem.c $(CURSES)
- X lint -p -Dlint -DIPC=\"$(IPC.C)\" pcomm_cmd.c
- X lint -p -Dlint waitfor.c
- X lint -p -Dlint matches.c
- X
- shar:
- X $(SHAR) Doc.me > pcomm_sh.1
- X $(SHAR) Configure.sh Convert.sh Makefile Matches.1 Pcomm.1 \
- X Pcomm.dial_dir Pcomm.extrnl Pcomm.modem Pcomm.param Pcomm_cmd.1 \
- X Q_and_A Readme Release.notes Sample > pcomm_sh.2
- X $(SHAR) Unixpc.shar Waitfor.1 admin.c chg_dir.c cmd.c cmd.h \
- X config.h curses.c d_delete.c d_lib.c d_manual.c > pcomm_sh.3
- X $(SHAR) d_menu.c d_print.c d_prompt.c d_revise.c data_log.c \
- X di_delay.c di_win.c dial.c dial_dir.h e_lib.c expand.c extrnl.h \
- X getcwd.c getopt.c help.c > pcomm_sh.4
- X $(SHAR) info.c init.c input.c ipc.h ipc_att.c ipc_ucb.c \
- X list_dir.c ls_menu.c m_lib.c macro.c main.c matches.c misc.h \
- X modem.h n_shell.c > pcomm_sh.5
- X $(SHAR) p_lib.c param.h passthru.c patchlevel.h pcomm_cmd.c \
- X pexit.c port.c redial.c s_axfer.c s_extrnl.c s_gen.c > pcomm_sh.6
- X $(SHAR) s_menu.c s_modem.c s_prompt.c s_term.c s_tty.c screen.c \
- X script.c st_line.c status.h strings.c terminal.c tty_att.c \
- X tty_ucb.c > pcomm_sh.7
- X $(SHAR) vcs.c vcs.h waitfor.c x_ascii.c x_batch.c x_extrnl.c \
- X x_menu.c x_rcv.c > pcomm_sh.8
- X $(SHAR) x_send.c x_win.c xmodem.c xmodem.h > pcomm_sh.9
- X# $(SHAR) Doc.out Matches.out Pcomm.out Pcomm_cmd.out Waitfor.out \
- X# > pcomm_sh.10
- X
- admin.o: config.h dial_dir.h param.h
- chg_dir.o: config.h misc.h
- cmd.o: cmd.h config.h dial_dir.h extrnl.h modem.h param.h status.h xmodem.h
- curses.o: config.h misc.h status.h
- d_delete.o: dial_dir.h misc.h param.h
- d_lib.o: dial_dir.h param.h
- d_manual.o: config.h dial_dir.h misc.h
- d_menu.o: config.h dial_dir.h misc.h param.h
- d_print.o: config.h dial_dir.h misc.h
- d_prompt.o: dial_dir.h misc.h
- d_revise.o: dial_dir.h misc.h param.h
- data_log.o: misc.h param.h status.h
- di_delay.o: misc.h param.h
- di_win.o: dial_dir.h misc.h modem.h param.h status.h
- dial.o: config.h dial_dir.h misc.h modem.h param.h
- e_lib.o: extrnl.h
- expand.o: config.h
- getopt.o: config.h
- help.o: config.h misc.h
- info.o: patchlevel.h
- init.o: config.h misc.h status.h
- input.o: config.h misc.h param.h status.h vcs.h
- ipc_att.o: ipc.h
- ipc_ucb.o: ipc.h
- list_dir.o: misc.h
- ls_menu.o: dial_dir.h misc.h param.h
- m_lib.o: modem.h
- macro.o: misc.h param.h
- main.o: config.h dial_dir.h extrnl.h misc.h modem.h param.h status.h
- n_shell.o: config.h
- p_lib.o: param.h
- passthru.o: config.h misc.h
- pexit.o: dial_dir.h misc.h param.h status.h
- port.o: config.h dial_dir.h modem.h status.h
- redial.o: config.h dial_dir.h misc.h
- s_axfer.o: misc.h param.h
- s_extrnl.o: extrnl.h misc.h
- s_gen.o: misc.h param.h
- s_menu.o: misc.h
- s_modem.o: misc.h modem.h
- s_prompt.o: misc.h
- s_term.o: dial_dir.h misc.h param.h
- s_tty.o: misc.h modem.h
- screen.o: param.h status.h
- script.o: config.h dial_dir.h misc.h modem.h status.h
- st_line.o: config.h dial_dir.h misc.h modem.h param.h status.h
- strings.o: config.h
- terminal.o: config.h dial_dir.h ipc.h misc.h modem.h param.h status.h xmodem.h
- tty_att.o: dial_dir.h modem.h param.h
- tty_ucb.o: dial_dir.h modem.h param.h
- vcs.o: config.h status.h vcs.h
- x_ascii.o: config.h misc.h param.h
- x_batch.o: config.h misc.h xmodem.h
- x_extrnl.o: config.h
- x_menu.o: extrnl.h misc.h xmodem.h
- x_rcv.o: config.h dial_dir.h misc.h xmodem.h
- x_send.o: config.h dial_dir.h misc.h xmodem.h
- x_win.o: dial_dir.h misc.h status.h xmodem.h
- xmodem.o: config.h misc.h param.h xmodem.h
- X
- pcomm_cmd.o: config.h cmd.h $(IPC.C)
- matches.o: config.h
- waitfor.o: config.h
- END_OF_FILE
- if test 6622 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'cmd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cmd.c'\"
- else
- echo shar: Extracting \"'cmd.c'\" \(7048 characters\)
- sed "s/^X//" >'cmd.c' <<'END_OF_FILE'
- X/*
- X * Pcomm script commands. Since these will be executed from a forked
- X * shell script, the commands, queries, and responses are sent thru an
- X * IPC channel to Pcomm.
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "cmd.h"
- X#include "config.h"
- X#include "dial_dir.h"
- X#include "extrnl.h"
- X#include "modem.h"
- X#include "param.h"
- X#include "status.h"
- X#include "xmodem.h"
- X
- static void send_reply(), do_xfer(), cmode(), tmode();
- X
- void
- cmd_input()
- X{
- X extern int fd;
- X int cmd, arg1, i, n, ret_code;
- X char buf[256], *s, arg2[256], *strchr(), *str_rep();
- X char *entry, *strtok(), ld_code;
- X void hang_up(), line_set(), pexit(), screen_dump(), log_toggle();
- X void lpr_toggle();
- X
- X if (ipc_read(status->cmd_ipc, buf, 256))
- X return;
- X
- X /* parse the comand line */
- X if (sscanf(buf, "%d %d %s\n", &cmd, &arg1, arg2) != 3)
- X return;
- X
- X ret_code = 0;
- X switch(cmd) {
- X case SET: /* the SET command */
- X switch(arg1) {
- X case BAUD:
- X dir->baud[0] = (unsigned int) atoi(arg2);
- X line_set();
- X break;
- X case PARITY:
- X dir->parity[0] = arg2[0];
- X line_set();
- X break;
- X case DATA_BITS:
- X dir->data_bits[0] = atoi(arg2);
- X line_set();
- X break;
- X case STOP_BITS:
- X dir->stop_bits[0] = atoi(arg2);
- X line_set();
- X break;
- X case DUPLEX:
- X dir->duplex[0] = arg2[0];
- X line_set();
- X break;
- X case AUX:
- X dir->aux[0] = str_rep(dir->aux[0], arg2);
- X break;
- X case HOT_KEY:
- X param->hot_key = atoi(arg2);
- X break;
- X case ASCII_HOT:
- X param->ascii_hot = str_rep(param->ascii_hot, arg2);
- X break;
- X case FLOW_CTRL:
- X param->flow_ctrl = str_rep(param->flow_ctrl, arg2);
- X break;
- X case CR_IN:
- X param->cr_in = str_rep(param->cr_in, arg2);
- X break;
- X case CR_OUT:
- X param->cr_out = str_rep(param->cr_out, arg2);
- X break;
- X case LOGFILE:
- X param->logfile = str_rep(param->logfile, arg2);
- X break;
- X case DUMPFILE:
- X param->dumpfile = str_rep(param->dumpfile, arg2);
- X break;
- X case STRIP:
- X param->strip = str_rep(param->strip, arg2);
- X break;
- X case LOCAL_ECHO:
- X param->local_echo = str_rep(param->local_echo, arg2);
- X break;
- X case EXPAND:
- X param->expand = str_rep(param->expand, arg2);
- X break;
- X case CR_DELAY:
- X param->cr_delay = atoi(arg2);
- X break;
- X case PACE:
- X param->pace = str_rep(param->pace, arg2);
- X break;
- X case CR_UP:
- X param->cr_up = str_rep(param->cr_up, arg2);
- X break;
- X case LF_UP:
- X param->lf_up = str_rep(param->lf_up, arg2);
- X break;
- X case TIMER:
- X param->timer = atoi(arg2);
- X break;
- X case CR_DN:
- X param->cr_dn = str_rep(param->cr_dn, arg2);
- X break;
- X case LF_DN:
- X param->lf_dn = str_rep(param->lf_dn, arg2);
- X break;
- X default:
- X break;
- X }
- X break;
- X case QUERY: /* the QUERY commands */
- X switch(arg1) {
- X case TTY_NAME:
- X if (modem->t_cur != -1)
- X send_reply(modem->tty[modem->t_cur]);
- X else
- X send_reply("NONE");
- X ret_code = 99;
- X break;
- X case MODEM_NAME:
- X if (modem->m_cur != -1)
- X send_reply(modem->mname[modem->m_cur]);
- X else
- X send_reply("NONE");
- X ret_code = 99;
- X break;
- X default:
- X break;
- X }
- X break;
- X case IF: /* the IF commands */
- X switch(arg1) {
- X case CONNECTED:
- X if (status->connected)
- X ret_code = 1;
- X break;
- X case LOG_STATUS:
- X if (status->log_status)
- X ret_code = 1;
- X break;
- X case PRINTER_STATUS:
- X if (status->print_status)
- X ret_code = 1;
- X break;
- X default:
- X break;
- X }
- X break;
- X case DIAL:
- X cmode();
- X ld_code = '\0';
- X s = arg2;
- X if (strchr("+-@#", *s)) {
- X ld_code = *s;
- X s++;
- X }
- X
- X if (arg1 == 1) { /* manual dial */
- X dir->name[0] = str_rep(dir->number[0], s);
- X dir->number[0] = str_rep(dir->number[0], s);
- X dir->d_cur = 0;
- X dir->q_num[0] = 0;
- X }
- X else {
- X n = atoi(s);
- X if (n == 0 || n > NUM_DIR) {
- X tmode();
- X break;
- X }
- X
- X dir->d_cur = n;
- X dir->q_num[0] = n;
- X }
- X dir->q_ld[0] = ld_code;
- X dir->q_num[1] = -1;
- X ret_code = dial_win(1);
- X tmode();
- X break;
- X case REDIAL:
- X cmode();
- X entry = strtok(arg2, " ");
- X for (i=0; i<NUM_QUEUE; i++) {
- X if (entry == NULL) {
- X dir->q_num[i] = -1;
- X break;
- X }
- X
- X ld_code = '\0';
- X if (strchr("+-@#", *entry)) {
- X ld_code = *entry;
- X entry++;
- X }
- X
- X n = atoi(entry);
- X if (n > NUM_DIR || *dir->number[n] == '\0')
- X continue;
- X
- X dir->q_ld[i] = ld_code;
- X dir->q_num[i] = n;
- X entry = strtok((char *) NULL, " \t");
- X }
- X ret_code = dial_win(10);
- X tmode();
- X break;
- X case EXIT:
- X pexit();
- X break;
- X case CLEAR_SCREEN:
- X fixterm();
- X erase();
- X refresh();
- X resetterm();
- X break;
- X case CHG_DIR:
- X chdir(arg2);
- X break;
- X case HANG_UP:
- X hang_up(QUIET);
- X break;
- X case PRINTER:
- X if (status->print_status + arg1 == 1)
- X lpr_toggle();
- X break;
- X case MODEM_BREAK:
- X tty_break(fd);
- X break;
- X case SEND:
- X do_xfer(arg1, UP_LOAD, arg2);
- X break;
- X case RECEIVE:
- X do_xfer(arg1, DOWN_LOAD, arg2);
- X break;
- X case SCREEN_DUMP:
- X screen_dump();
- X break;
- X case DATA_LOG:
- X if (status->log_status + arg1 == 1) {
- X if (arg1 == 1 && !strcmp(status->log_path, "NOT_DEFINED"))
- X status->log_path = str_rep(status->log_path, param->logfile);
- X log_toggle();
- X }
- X break;
- X default:
- X break;
- X }
- X if (ret_code != 99) {
- X sprintf(buf, "%d", ret_code);
- X send_reply(buf);
- X }
- X return;
- X}
- X
- X/*
- X * Send a string back to pcomm_cmd
- X */
- X
- static void
- send_reply(s)
- char *s;
- X{
- X char buf[256];
- X
- X sprintf(buf, "%254.254s\n", s);
- X if (ipc_write(status->cmd_ipc, buf, 256))
- X fprintf(stderr, "Can't write to IPC\n");
- X return;
- X}
- X
- X/*
- X * Put the screen in the "curses" mode
- X */
- X
- static void
- cmode()
- X{
- X void load_vs(), st_line();
- X
- X fixterm();
- X load_vs();
- X st_line("");
- X return;
- X}
- X
- X/*
- X * Put the screen in the "terminal" mode
- X */
- X
- static void
- tmode()
- X{
- X extern int fd;
- X void term_mode();
- X
- X if (fd != -1) {
- X touchwin(stdscr);
- X refresh();
- X }
- X resetterm();
- X term_mode();
- X return;
- X}
- X
- X/*
- X * Do the file transfers
- X */
- X
- static void
- do_xfer(type, up, files)
- int type, up;
- char *files;
- X{
- X int n, is_batch, num_extrnl;
- X char buf[256], *strcpy(), *strcat();
- X void xfer_win(), xfer_ascii(), do_extrnl();
- X
- X num_extrnl = (up == UP_LOAD) ? extrnl->up_entries : extrnl->dn_entries;
- X
- X is_batch = 0;
- X switch(type) {
- X case MODEM7:
- X case YMODEM:
- X case YMODEM_G: /* built-in batch protocols */
- X is_batch++;
- X /* FALLTHRU */
- X case XMODEM:
- X case XMODEM_1k: /* non-batch built-ins */
- X cmode();
- X if (up == UP_LOAD || !is_batch)
- X xfer_win(files, up, type);
- X else
- X xfer_win("", up, type);
- X tmode();
- X break;
- X case XASCII: /* ascii xfer, yuck! */
- X xfer_ascii(files, up);
- X break;
- X case EXT_1:
- X case EXT_2:
- X case EXT_3: /* one of the externals */
- X n = type -NUM_INTERNAL -1;
- X if (n > num_extrnl)
- X break;
- X strcpy(buf, extrnl->command[up][n]);
- X /* see if we need to add files */
- X if (extrnl->prompt[up][n] == 'Y') {
- X strcat(buf, " ");
- X strcat(buf, files);
- X }
- X do_extrnl(buf);
- X break;
- X default:
- X break;
- X }
- X return;
- X}
- END_OF_FILE
- if test 7048 -ne `wc -c <'cmd.c'`; then
- echo shar: \"'cmd.c'\" unpacked with wrong size!
- fi
- # end of 'cmd.c'
- fi
- if test -f 'd_lib.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'d_lib.c'\"
- else
- echo shar: Extracting \"'d_lib.c'\" \(6988 characters\)
- sed "s/^X//" >'d_lib.c' <<'END_OF_FILE'
- X/*
- X * Routines to manipulate the dialing directory file pcomm.dial_dir
- X */
- X
- X#include <stdio.h>
- X#include "dial_dir.h"
- X#include "param.h"
- X
- X/*
- X * Read the dialing directory. Returns a pointer to a static area
- X * containing the DIAL_DIR structure. All of the entries are created
- X * regardless of the number of physical entries in the file. Element
- X * number zero is reserved for the "manual" entry. All errors are fatal.
- X */
- X
- struct DIAL_DIR *
- read_dir()
- X{
- X extern char *null_ptr;
- X FILE *fp, *uid_fopen();
- X int i, line, oops;
- X char *str_dup(), buf[200], *temp_token, *str, *str_tok(), token[20];
- X char message[80], *sep, *findfile();
- X static struct DIAL_DIR d;
- X void error_win();
- X
- X if ((d.d_path = findfile("pcomm.dial_dir")) == NULL)
- X error_win(1, "Support file \"pcomm.dial_dir\" is missing", "or no read permission");
- X
- X if (!(fp = uid_fopen(d.d_path, "r"))) {
- X sprintf(buf, "\"%s\" for read", d.d_path);
- X error_win(1, "Can't open dialing directory file", buf);
- X }
- X
- X sep = ";;---;;\n";
- X line = 0;
- X oops = 0;
- X while (fgets(buf, 200, fp) != NULL) {
- X line++;
- X if (line > NUM_DIR)
- X break;
- X /* get the token */
- X if (!(temp_token = str_tok(buf, '='))) {
- X sprintf(message, "is missing a token at line %d", line);
- X oops++;
- X break;
- X }
- X /*
- X * Parse the rest of the line. This is similar to using
- X * the "real" strtok() function, but this version returns
- X * a pointer to NULL if the token is missing. Note the use
- X * of the array of field separators.
- X */
- X for (i=0; i<8; i++) {
- X if (!(str = str_tok((char *) NULL, sep[i]))) {
- X sprintf(message, "is missing a parameter at line %d", line);
- X oops++;
- X break;
- X }
- X switch (i) {
- X case 0:
- X d.name[line] = str_dup(str);
- X break;
- X case 1:
- X d.number[line] = str_dup(str);
- X break;
- X case 2:
- X d.baud[line] = (unsigned int) atoi(str);
- X break;
- X case 3:
- X d.parity[line] = *str;
- X break;
- X case 4:
- X d.data_bits[line] = atoi(str);
- X break;
- X case 5:
- X d.stop_bits[line] = atoi(str);
- X break;
- X case 6:
- X d.duplex[line] = *str;
- X break;
- X case 7:
- X d.aux[line] = str_dup(str);
- X break;
- X }
- X }
- X if (oops)
- X break;
- X /* sanity checking */
- X sprintf(token, "DIR_%d", line);
- X if (strcmp(temp_token, token)) {
- X sprintf(message, "is corrupted at line %d", line);
- X oops++;
- X break;
- X }
- X }
- X fclose(fp);
- X
- X if (oops) {
- X sprintf(buf, "Dialing directory file \"%s\"", d.d_path);
- X error_win(1, buf, message);
- X }
- X d.d_entries = line;
- X /* if empty database */
- X if (!line) {
- X sprintf(buf, "Dialing directory file \"%s\"", d.d_path);
- X error_win(0, buf, "has no data");
- X }
- X /* fill in the rest with defaults */
- X for (i=line+1; i<=NUM_DIR; i++) {
- X d.name[i] = null_ptr;
- X d.number[i] = null_ptr;
- X d.baud[i] = param->d_baud;
- X d.parity[i] = param->d_parity;
- X d.data_bits[i] = param->d_data_bits;
- X d.stop_bits[i] = param->d_stop_bits;
- X d.duplex[i] = *param->d_duplex;
- X d.aux[i] = null_ptr;
- X }
- X /* create an empty "manual" entry */
- X d.name[0] = null_ptr;
- X d.number[0] = null_ptr;
- X d.baud[0] = param->d_baud;
- X d.parity[0] = param->d_parity;
- X d.data_bits[0] = param->d_data_bits;
- X d.stop_bits[0] = param->d_stop_bits;
- X d.duplex[0] = *param->d_duplex;
- X d.aux[0] = null_ptr;
- X /* create an empty queue */
- X for (i=0; i<NUM_QUEUE; i++) {
- X d.q_ld[i] = '\0';
- X d.q_num[i] = -1;
- X }
- X /* the start up d_cur is 0 */
- X d.d_cur = 0;
- X return(&d);
- X}
- X
- X/*
- X * Update a dialing directory entry. Update only the one entry asked for,
- X * not the entire image in memory. If the new entry is beyond the end of
- X * the physical file, then fill in the holes, and update "dir->d_entries".
- X * A non-zero return code means a non-fatal error.
- X */
- X
- int
- up_dir(entry)
- int entry;
- X{
- X FILE *fp_in, *fp_out, *uid_fopen();
- X int i;
- X char *temp[NUM_DIR+1], buf[200], *str_dup(), *str_rep();
- X void error_win(), free_ptr();
- X
- X /* open for read */
- X if (!(fp_in = uid_fopen(dir->d_path, "r"))) {
- X sprintf(buf, "\"%s\" for read", dir->d_path);
- X error_win(1, "Can't open dialing directory file", buf);
- X }
- X /* read in a temporary version */
- X i = 0;
- X while (fgets(buf, 200, fp_in) != NULL)
- X temp[++i] = str_dup(buf);
- X
- X fclose(fp_in);
- X /* alter only 1 entry */
- X sprintf(buf, "DIR_%d=%s;%s;%d-%c-%d-%d;%c;%s\n", entry,
- X dir->name[entry], dir->number[entry], dir->baud[entry],
- X dir->parity[entry], dir->data_bits[entry], dir->stop_bits[entry],
- X dir->duplex[entry], dir->aux[entry]);
- X
- X if (entry <= dir->d_entries)
- X temp[entry] = str_rep(temp[entry], buf);
- X else
- X temp[entry] = str_dup(buf);
- X
- X /* fill in holes if beyond end */
- X if (entry > dir->d_entries+1) {
- X for (i=dir->d_entries+1; i<entry; i++) {
- X sprintf(buf, "DIR_%d=;;%d-%c-%d-%d;%c;\n", i,
- X param->d_baud, param->d_parity, param->d_data_bits,
- X param->d_stop_bits, *param->d_duplex);
- X temp[i] = str_dup(buf);
- X }
- X }
- X /* update "dir->d_entries" */
- X if (entry > dir->d_entries)
- X dir->d_entries = entry;
- X
- X /* open for write */
- X if (!(fp_out = uid_fopen(dir->d_path, "w"))) {
- X for (i=1; i<=dir->d_entries; i++)
- X free_ptr(temp[i]);
- X sprintf(buf, "\"%s\"", dir->d_path);
- X error_win(0, "No write permission on dialing directory file", buf);
- X return(1);
- X }
- X /* put it back */
- X for (i=1; i<=dir->d_entries; i++) {
- X fputs(temp[i], fp_out);
- X free_ptr(temp[i]);
- X }
- X
- X fclose(fp_out);
- X return(0);
- X}
- X
- X/*
- X * Delete a range of dialing directory entries. Actually, just copies
- X * default (empty) entries in place of deleted entries. However, it will
- X * shrink the file if deletions occur at the physical EOF. A non-zero
- X * return code means a non-fatal error.
- X */
- X
- int
- del_dir(first, last)
- int first, last;
- X{
- X FILE *fp_in, *fp_out, *uid_fopen();
- X int i;
- X char *temp[NUM_DIR+1], buf[200], *str_dup(), *str_rep();
- X void error_win(), free_ptr();
- X /* sanity checking */
- X if (first > dir->d_entries)
- X return(0);
- X if (last > dir->d_entries)
- X last = dir->d_entries;
- X
- X /* open for read */
- X if (!(fp_in = uid_fopen(dir->d_path, "r"))) {
- X sprintf(buf, "\"%s\" for read", dir->d_path);
- X error_win(1, "Can't open dialing directory file", buf);
- X }
- X /* read in a temporary version */
- X i = 0;
- X while (fgets(buf, 200, fp_in) != NULL)
- X temp[++i] = str_dup(buf);
- X
- X fclose(fp_in);
- X /* delete the range of values */
- X for (i=first; i<=last; i++) {
- X sprintf(buf, "DIR_%d=;;%d-%c-%d-%d;%c;\n", i, param->d_baud,
- X param->d_parity, param->d_data_bits, param->d_stop_bits,
- X *param->d_duplex);
- X temp[i] = str_rep(temp[i], buf);
- X }
- X /* shrink the file? */
- X if (last >= dir->d_entries) {
- X for (i=first; i<=last; i++)
- X free_ptr(temp[i]);
- X dir->d_entries = first-1;
- X }
- X /* open for write */
- X if (!(fp_out = uid_fopen(dir->d_path, "w"))) {
- X for (i=1; i<=dir->d_entries; i++)
- X free_ptr(temp[i]);
- X sprintf(buf, "\"%s\"", dir->d_path);
- X error_win(0, "No write permission on dialing directory file", buf);
- X return(1);
- X }
- X /* put it all back */
- X for (i=1; i<=dir->d_entries; i++) {
- X fputs(temp[i], fp_out);
- X free_ptr(temp[i]);
- X }
- X
- X fclose(fp_out);
- X return(0);
- X}
- END_OF_FILE
- if test 6988 -ne `wc -c <'d_lib.c'`; then
- echo shar: \"'d_lib.c'\" unpacked with wrong size!
- fi
- # end of 'd_lib.c'
- fi
- if test -f 'd_menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'d_menu.c'\"
- else
- echo shar: Extracting \"'d_menu.c'\" \(7134 characters\)
- sed "s/^X//" >'d_menu.c' <<'END_OF_FILE'
- X/*
- X * Routines for the dialing directory menu.
- 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
- static int current = 1;
- static void dir_scroll(), active_ld(), disp_ld();
- X
- X/*
- X * Display the dialing directory and prompt for options. A non-zero return
- X * code means we're ready to dial.
- X */
- X
- int
- dial_menu()
- X{
- X extern int xmc;
- X WINDOW *dm_win, *newwin();
- X char buf[5], ld_code;
- X int ans, start, needs_repair, count, x, y, i, ret_code;
- X void print_dir(), st_line();
- X
- X touchwin(stdscr);
- X refresh();
- X st_line("");
- X
- X dm_win = newwin(22, 78, 1, 1);
- X mvwattrstr(dm_win, 1, 20, A_BOLD, "D I A L I N G D I R E C T O R Y");
- X horizontal(dm_win, 2, 0, 78);
- X mvwattrstr(dm_win, 3, 0, A_STANDOUT, " Name Number Baud P D S Dpx Auxiliary ");
- X /* show 10 entries */
- X dir_scroll(dm_win, current);
- X
- X mvwaddstr(dm_win, 15, 4, "==>");
- X mvwattrch(dm_win, 15, 14, A_BOLD, 'R');
- X waddstr(dm_win, " Revise");
- X mvwattrch(dm_win, 15, 34, A_BOLD, 'M');
- X waddstr(dm_win, " Manual Dialing");
- X mvwaddstr(dm_win, 15, 55, "Entry to Dial");
- X
- X mvwattrch(dm_win, 16, 14, A_BOLD, 'P');
- X waddstr(dm_win, " LD Codes");
- X mvwattrch(dm_win, 16, 34, A_BOLD, 'D');
- X waddstr(dm_win, " Delete Entry");
- X mvwattrstr(dm_win, 16, 55, A_BOLD, "<CR>");
- X waddstr(dm_win, " Scroll Down");
- X
- X#ifdef OLDCURSES
- X mvwattrstr(dm_win, 17, 14, A_BOLD, "U/N");
- X#else /* OLDCURSES */
- X mvwattrstr(dm_win, 17, 14, A_BOLD, "<up>/<down>");
- X#endif /* OLDCURSES */
- X waddstr(dm_win, " Page");
- X mvwattrch(dm_win, 17, 34, A_BOLD, 'L');
- X waddstr(dm_win, " Print Entries");
- X mvwattrstr(dm_win, 17, 55, A_BOLD, "<ESC>");
- X waddstr(dm_win, " Exit");
- X
- X mvwaddstr(dm_win, 19, 4, "LD Codes Active:");
- X /* show which LD codes are active */
- X active_ld(dm_win);
- X
- X box(dm_win, VERT, HORZ);
- X y = 15;
- X x = 8;
- X wmove(dm_win, 15, 8);
- X wrefresh(dm_win);
- X
- X#ifndef OLDCURSES
- X keypad(dm_win, TRUE);
- X#endif /* OLDCURSES */
- X /* prompt for options */
- X count = 0;
- X ld_code = '\0';
- X ret_code = 0;
- X do {
- X needs_repair = 0;
- X ans = wgetch(dm_win);
- X /* get an entry number */
- X if (ans >= '0' && ans <= '9') {
- X if (count > 2) {
- X beep();
- X continue;
- X }
- X buf[count] = (char) ans;
- X waddch(dm_win, (chtype) ans);
- X wrefresh(dm_win);
- X count++;
- X continue;
- X }
- X switch (ans) {
- X case DEL:
- X case BS: /* do our own backspace */
- X if (!count) {
- X beep();
- X break;
- X }
- X count--;
- X if (!count)
- X ld_code = '\0';
- X buf[count] = '\0';
- X getyx(dm_win, y, x);
- X x--;
- X wmove(dm_win, y, x);
- X waddch(dm_win, (chtype) ' ');
- X wmove(dm_win, y, x);
- X wrefresh(dm_win);
- X break;
- X#ifndef OLDCURSES
- X case KEY_UP:
- X#endif /* OLDCURSES */
- X case 'u':
- X case 'U': /* up arrow key */
- X if (current == 1) {
- X beep();
- X break;
- X }
- X start = current - 10;
- X if (start < 1)
- X start = 1;
- X current = start;
- X dir_scroll(dm_win, start);
- X break;
- X#ifndef OLDCURSES
- X case KEY_DOWN:
- X case '\n':
- X#endif /* OLDCURSES */
- X case 'n':
- X case 'N': /* down arrow key */
- X if (current == NUM_DIR-9) {
- X beep();
- X break;
- X }
- X start = current + 10;
- X if (start > NUM_DIR-9)
- X start = NUM_DIR-9;
- X current = start;
- X dir_scroll(dm_win, start);
- X break;
- X case '\r': /* <CR> key */
- X if (!count) {
- X if (current == NUM_DIR-9) {
- X beep();
- X break;
- X }
- X current++;
- X if (current > NUM_DIR-9)
- X current = NUM_DIR-9;
- X dir_scroll(dm_win, current);
- X }
- X /*
- X * The <CR> is used for the scroll-down-one-line
- X * function, and to terminate numeric input.
- X */
- X else {
- X buf[count] = '\0';
- X i = atoi(buf);
- X if (!i || i > NUM_DIR) {
- X beep();
- X mvwaddstr(dm_win, 15, 8, " ");
- X x = 8;
- X count = 0;
- X break;
- X }
- X dir->q_ld[0] = ld_code;
- X dir->q_num[0] = i;
- X dir->d_cur = i;
- X
- X /* end of queue marker */
- X dir->q_num[1] = -1;
- X
- X ret_code++;
- X break;
- X }
- X break;
- X case 'r':
- X case 'R': /* revise */
- X if (revise()) {
- X active_ld(dm_win);
- X dir_scroll(dm_win, current);
- X }
- X touchwin(dm_win);
- X break;
- X case 'p': /* display LD codes */
- X case 'P':
- X disp_ld();
- X touchwin(dm_win);
- X needs_repair++;
- X break;
- X case 'd':
- X case 'D': /* delete a range of entries */
- X if (delete())
- X dir_scroll(dm_win, current);
- X touchwin(dm_win);
- X break;
- X case 'm':
- X case 'M': /* manual dial */
- X if (manual()) {
- X ret_code++;
- X break;
- X }
- X touchwin(dm_win);
- X needs_repair++;
- X break;
- X case 'l':
- X case 'L': /* print the entries */
- X print_dir();
- X touchwin(dm_win);
- X needs_repair++;
- X break;
- X case '+': /* LD codes */
- X case '-':
- X case '@':
- X case '#':
- X waddch(dm_win, (chtype) ans);
- X wrefresh(dm_win);
- X ld_code = (char) ans;
- X continue;
- X case ESC: /* <ESC> key (exit) */
- X break;
- X default:
- X beep();
- X }
- X if (ret_code)
- X break;
- X /* magic cookie terminal? */
- X if (xmc > 0 && needs_repair) {
- X clear_line(dm_win, 1, 0, FALSE);
- X clear_line(dm_win, 3, 0, FALSE);
- X wrefresh(dm_win);
- X mvwattrstr(dm_win, 1, 20, A_BOLD, "D I A L I N G D I R E C T O R Y");
- X mvwattrstr(dm_win, 3, 0, A_STANDOUT, " Name Number Baud P D S Dpx Auxiliary ");
- X box(dm_win, VERT, HORZ);
- X }
- X wmove(dm_win, y, x);
- X wrefresh(dm_win);
- X } while (ans != ESC);
- X
- X werase(dm_win);
- X wrefresh(dm_win);
- X delwin(dm_win);
- X if (ret_code) {
- X touchwin(stdscr);
- X refresh();
- X }
- X return(ret_code);
- X}
- X
- X/*
- X * Scroll the dialing directory. Actually, we're not doing a real scroll
- X * function on the screen, we're just repainting 10 lines.
- X */
- X
- static void
- dir_scroll(win, start)
- WINDOW *win;
- int start;
- X{
- X int i;
- X
- X wmove(win, 4, 0);
- X for (i=start; i<start+10; i++)
- X wprintw(win,
- X "%4d- %-20.20s %18.18s %5d-%c-%d-%d %c %-14.14s\n", i,
- X dir->name[i], dir->number[i], dir->baud[i], dir->parity[i],
- X dir->data_bits[i], dir->stop_bits[i], dir->duplex[i],
- X dir->aux[i]);
- X box(win, VERT, HORZ);
- X return;
- X}
- X
- X/*
- X * Display the Long Distance codes. Press any key to continue.
- X */
- X
- static void
- disp_ld()
- X{
- X WINDOW *ld_win, *newwin();
- X
- X ld_win = newwin(12, 30, 0, 0);
- X mvwaddstr(ld_win, 1, 5, "Long Distance Codes\n");
- X horizontal(ld_win, 2, 0, 30);
- X mvwprintw(ld_win, 3, 2, "+ %-20.20s", param->ld_plus);
- X mvwprintw(ld_win, 5, 2, "- %-20.20s", param->ld_minus);
- X mvwprintw(ld_win, 7, 2, "@ %-20.20s", param->ld_at);
- X mvwprintw(ld_win, 9, 2, "# %-20.20s", param->ld_pound);
- X box(ld_win, VERT, HORZ);
- X
- X mvwaddstr(ld_win, 11, 8, " Press any key ");
- X wmove(ld_win, 11, 29);
- X wrefresh(ld_win);
- X wgetch(ld_win);
- X /* it overlaps, so erase it */
- X werase(ld_win);
- X wrefresh(ld_win);
- X delwin(ld_win);
- X return;
- X}
- X
- X/*
- X * Display which of the Long Distance codes are active.
- X */
- X
- static void
- active_ld(win)
- WINDOW *win;
- X{
- X mvwaddstr(win, 19, 21, " ");
- X wmove(win, 19, 21);
- X /* a NULL means it's not active */
- X if (*param->ld_plus != '\0')
- X waddstr(win, "+ ");
- X if (*param->ld_minus != '\0')
- X waddstr(win, "- ");
- X if (*param->ld_at != '\0')
- X waddstr(win, "@ ");
- X if (*param->ld_pound != '\0')
- X waddstr(win, "# ");
- X return;
- X}
- END_OF_FILE
- if test 7134 -ne `wc -c <'d_menu.c'`; then
- echo shar: \"'d_menu.c'\" unpacked with wrong size!
- fi
- # end of 'd_menu.c'
- fi
- if test -f 'input.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'input.c'\"
- else
- echo shar: Extracting \"'input.c'\" \(7330 characters\)
- sed "s/^X//" >'input.c' <<'END_OF_FILE'
- X/*
- X * The input routines.
- X */
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "misc.h"
- X#include "param.h"
- X#include "status.h"
- X#include "vcs.h"
- X
- static int add_lf;
- static void vs_scroll();
- static FILE *logfp = (FILE *) NULL;
- static FILE *lprfp = (FILE *) NULL;
- X
- X/*
- X * Read the serial port and write the characters to the screen. Watch
- X * for changes in status structure to toggle the fancy options.
- X * Writes the characters received to a virtual screen buffer.
- X */
- X
- void
- tty_input()
- X{
- X extern int fd;
- X register int in_cnt, out_cnt;
- X char c, *bufp, in_buf[INPUT_BUF], out_buf[INPUT_BUF*2];
- X void vs_putchar();
- X
- X /* here we go... */
- X if ((in_cnt = read(fd, in_buf, INPUT_BUF)) <= 0)
- X return;
- X
- X /*
- X * If we're doing a script, send a duplicate down the pipe
- X */
- X if (status->dup_fd != -1)
- X write(status->dup_fd, in_buf, in_cnt);
- X
- X /* "peel" the buffer one at a time */
- X out_cnt = 0;
- X bufp = in_buf;
- X add_lf = !strcmp(param->cr_in, "CR/LF");
- X while (--in_cnt >= 0) {
- X c = *bufp++ & 0xff;
- X /* send to logfile? */
- X if (status->log_status) {
- X if (c == '\r' && 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_status)
- X putc(c, lprfp);
- X
- X /* put a char in virtual screen */
- X vs_putchar(c);
- X
- X /* build the output buffer */
- X out_buf[out_cnt++] = c;
- X if (c == '\r' && add_lf)
- X out_buf[out_cnt++] = '\n';
- X
- X /* output in smaller chunks */
- X if (out_cnt >= OUTPUT_BUF) {
- X write(1, out_buf, out_cnt);
- X out_cnt = 0;
- X }
- X }
- X if (out_cnt)
- X write(1, out_buf, out_cnt);
- X
- X return;
- 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
- void
- vs_putchar(c)
- char c;
- X{
- X register int i;
- X extern int vcs_param[NUM_VCS][5], vcs_opt[NUM_VCS][10];
- X char *memset();
- 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 status->row = 0;
- X status->col = 0;
- X break;
- X case 256+CLR_EOL: /* clear to end of line */
- X memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
- X status->col = status->max_col -1;
- X break;
- X case 256+CLR_EOS: /* clear to end of screen */
- X memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
- X for (i=status->row+1; i<status->max_row; i++)
- X memset(status->vs[i], ' ', status->max_col);
- X status->row = status->max_row -1;
- X status->col = status->max_col -1;
- X break;
- X case 256+CLEAR: /* clear all and home "cursor" */
- X for (i=0; i<status->max_row; i++)
- X memset(status->vs[i], ' ', status->max_col);
- X status->row = 0;
- X status->col = 0;
- X break;
- X case 256+MV_UP: /* move "cursor" up */
- X status->row--;
- X if (status->row < 0)
- X status->row = 0;
- X break;
- X case 256+MV_DOWN: /* move "cursor" down */
- X status->row++;
- X if (status->row >= status->max_row)
- X status->row = status->max_row -1;
- X break;
- X case 256+MV_RIGHT: /* move "cursor" right */
- X status->col++;
- X if (status->col >= status->max_col)
- X status->col = status->max_col -1;
- X break;
- X case 256+MV_LEFT: /* move "cursor" left */
- X case BS: /* non destructive back space */
- X status->col--;
- X if (status->col < 0)
- X status->col = 0;
- X break;
- X case 256+MV_DIRECT: /* direct cursor movement */
- X status->row = vcs_param[MV_DIRECT][0];
- X status->col = 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 status->row--;
- X status->col--;
- X }
- X /* if "character" */
- X if (vcs_opt[MV_DIRECT][2]) {
- X /* if "add offset" */
- X if (vcs_opt[MV_DIRECT][3]) {
- X status->row -= vcs_opt[MV_DIRECT][5];
- X status->col -= vcs_opt[MV_DIRECT][5];
- X }
- X /* if "subtract offset" */
- X if (vcs_opt[MV_DIRECT][4]) {
- X status->row += vcs_opt[MV_DIRECT][5];
- X status->col += vcs_opt[MV_DIRECT][5];
- X }
- X status->row--;
- X status->col--;
- X }
- X /* sanity check... */
- X if (status->row < 0)
- X status->row = 0;
- X if (status->col < 0)
- X status->col = 0;
- X if (status->row >= status->max_row)
- X status->row = status->max_row -1;
- X if (status->col >= status->max_col)
- X status->col = status->max_col -1;
- X break;
- X case 0:
- X case 7: /* skip NULL and "bell" character */
- X break;
- X case '\t': /* tab character */
- X tab_stop = status->col + 8 - (status->col % 8);
- X /* if wrap around */
- X if (tab_stop >= status->max_col) {
- X /* spaces up to eol */
- X memset(&status->vs[status->row][status->col], ' ', status->max_col - status->col);
- X status->row++;
- X if (status->row >= status->max_row)
- X vs_scroll();
- X
- X /* the remainder of the tab */
- X status->col = tab_stop - status->max_col;
- X }
- X else {
- X memset(&status->vs[status->row][status->col], ' ', tab_stop - status->col);
- X status->col = tab_stop;
- X }
- X break;
- X case '\r': /* carriage return */
- X status->col = 0;
- X if (!add_lf)
- X break;
- X /* FALLTHRU */
- X case '\n': /* line feed */
- X status->row++;
- X if (status->row >= status->max_row)
- X vs_scroll();
- X break;
- X default: /* a normal character */
- X status->vs[status->row][status->col] = c;
- X status->col++;
- X /* wrap around */
- X if (status->col >= status->max_col) {
- X status->col = 0;
- X status->row++;
- X if (status->row >= status->max_row)
- X vs_scroll();
- X }
- X break;
- X }
- X return;
- X}
- X
- X/*
- X * Do a software scroll on the virtual screen. Does not alter the
- X * "col" variable.
- X */
- X
- static void
- vs_scroll()
- X{
- X char *memset();
- X /* move 'em up 1 line */
- X#ifdef MEMMOVE
- X MEMMOVE(status->vs[0], status->vs[1], (status->max_row -1) * MAX_COL);
- X#else /* MEMMOVE */
- X register int i;
- X char *strcpy();
- X
- X for (i=0; i<status->max_row-1; i++)
- X strcpy(status->vs[i], status->vs[i+1]);
- X#endif /* MEMMOVE */
- X /* clear the bottom line */
- X memset(status->vs[status->max_row-1], ' ', status->max_col);
- X
- X status->row = status->max_row -1;
- X return;
- X}
- X
- X/*
- X * A short-cut for charcters that are "echoed" in the half duplex
- X * mode. Since the TTY driver is putting the characters on the
- X * screen (rather than being sent back by the modem), they need
- X * to be faked as modem input.
- X */
- X
- void
- half_duplex(c)
- char c;
- X{
- X /* send to logfile? */
- X if (status->log_status) {
- X if (c == '\r' && 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_status)
- X putc(c, lprfp);
- X
- X /* put a char in virtual screen */
- X vs_putchar(c);
- X return;
- X}
- X
- X/*
- X * Toggle the printer log
- X */
- X
- void
- lpr_toggle()
- X{
- X FILE *n_popen();
- X
- X status->print_status = status->print_status ? 0 : 1;
- X
- X if (status->print_status && lprfp == NULL) {
- X if (!(lprfp = n_popen(LPR, "w")))
- X status->print_status = 0;
- X }
- X
- X if (!status->print_status && lprfp != NULL) {
- X putc('\f', lprfp);
- X n_pclose(lprfp);
- X lprfp = (FILE *) NULL;
- X }
- X return;
- X}
- X
- X/*
- X * Toggle the data log
- X */
- X
- void
- log_toggle()
- X{
- X FILE *uid_fopen();
- X
- X status->log_status = status->log_status ? 0 : 1;
- X
- X if (status->log_status && logfp == NULL) {
- X if (!(logfp = uid_fopen(status->log_path, "a")))
- X status->log_status = 0;
- X }
- X
- X if (!status->log_status && logfp != NULL) {
- X fclose(logfp);
- X logfp = (FILE *) NULL;
- X }
- X return;
- X}
- END_OF_FILE
- if test 7330 -ne `wc -c <'input.c'`; then
- echo shar: \"'input.c'\" unpacked with wrong size!
- fi
- # end of 'input.c'
- fi
- if test -f 'p_lib.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'p_lib.c'\"
- else
- echo shar: Extracting \"'p_lib.c'\" \(7341 characters\)
- sed "s/^X//" >'p_lib.c' <<'END_OF_FILE'
- X/*
- X * Routines to manipulate the pcomm.param file.
- X */
- X
- X#include <stdio.h>
- X#include "param.h"
- X
- X/*
- X * Read the parameter structure from the pcomm.param file. Returns a
- X * pointer to a static area containing the PARAM structure. All errors
- X * are fatal.
- X */
- X
- struct PARAM *
- read_param()
- X{
- X FILE *fp, *uid_fopen();
- X int i, line, oops;
- X char buf[200], *temp_token, *str, *str_dup(), *findfile();
- X char message[80], *str_tok();
- X static char *token[NUM_PARAM] = {"D_BAUD", "D_PARITY",
- X "D_DATA_BITS", "D_STOP_BITS", "HOT_KEY", "ASCII_HOT", "D_DUPLEX",
- X "FLOW_CTRL", "CR_IN", "CR_OUT", "LOGFILE", "DUMPFILE", "STRIP",
- X "PAUSE_CHAR", "CR_CHAR", "CTRL_CHAR", "ESC_CHAR", "BRK_CHAR",
- X "ABORT", "C_DELAY", "R_DELAY", "LOCAL_ECHO", "EXPAND", "CR_DELAY",
- X "PACE", "CR_UP", "LF_UP", "TIMER", "CR_DN", "LF_DN", "LD_PLUS",
- X "LD_MINUS", "LD_AT", "LD_POUND", "MAC_1", "MAC_2", "MAC_3",
- X "MAC_4", "MAC_5", "MAC_6", "MAC_7", "MAC_8", "MAC_9", "MAC_0"};
- X static struct PARAM p;
- X void error_win();
- X
- X if ((p.p_path = findfile("pcomm.param")) == NULL)
- X error_win(1, "Support file \"pcomm.param\" is missing", "or no read permission");
- X
- X if (!(fp = uid_fopen(p.p_path, "r"))) {
- X sprintf(buf, "\"%s\" for read", p.p_path);
- X error_win(1, "Can't open parameter file", buf);
- X }
- X
- X oops = 0;
- X line = 0;
- X for (i=0; i<NUM_PARAM; i++) {
- X line++;
- X if (fgets(buf, 200, fp) == NULL) {
- X sprintf(message, "is truncated at line %d", line);
- X oops++;
- X break;
- X }
- X /* parse the input line */
- X if (!(temp_token = str_tok(buf, '='))) {
- X sprintf(message, "is missing a token at line %d", line);
- X oops++;
- X break;
- X }
- X if (!(str = str_tok((char *) NULL, '\n'))) {
- X sprintf(message, "is missing a parameter at line %d", line);
- X oops++;
- X break;
- X }
- X /* sanity checking */
- X if (strcmp(temp_token, token[i])) {
- X sprintf(message, "is corrupted at line %d", line);
- X oops++;
- X break;
- X }
- X
- X switch (i) {
- X /* used in ls_menu() */
- X case LINE_SET:
- X p.d_baud = (unsigned int) atoi(str);
- X break;
- X case LINE_SET+1:
- X p.d_parity = *str;
- X break;
- X case LINE_SET+2:
- X p.d_data_bits = atoi(str);
- X break;
- X case LINE_SET+3:
- X p.d_stop_bits = atoi(str);
- X break;
- X
- X /* used in term_setup() */
- X case TERM_SETUP:
- X p.hot_key = atoi(str);
- X break;
- X case TERM_SETUP+1:
- X p.ascii_hot = str_dup(str);
- X break;
- X case TERM_SETUP+2:
- X p.d_duplex = str_dup(str);
- X break;
- X case TERM_SETUP+3:
- X p.flow_ctrl = str_dup(str);
- X break;
- X case TERM_SETUP+4:
- X p.cr_in = str_dup(str);
- X break;
- X case TERM_SETUP+5:
- X p.cr_out = str_dup(str);
- X break;
- X
- X /* used in gen_setup() */
- X case GEN_SETUP:
- X p.logfile = str_dup(str);
- X break;
- X case GEN_SETUP+1:
- X p.dumpfile = str_dup(str);
- X break;
- X case GEN_SETUP+2:
- X p.strip = str_dup(str);
- X break;
- X case GEN_SETUP+3:
- X p.pause_char = *str;
- X break;
- X case GEN_SETUP+4:
- X p.cr_char = *str;
- X break;
- X case GEN_SETUP+5:
- X p.ctrl_char = *str;
- X break;
- X case GEN_SETUP+6:
- X p.esc_char = *str;
- X break;
- X case GEN_SETUP+7:
- X p.brk_char = *str;
- X break;
- X case GEN_SETUP+8:
- X p.abort = str_dup(str);
- X break;
- X
- X /* used in gen_setup() delay_times() */
- X case DELAY_TIMES:
- X p.c_delay = atoi(str);
- X break;
- X case DELAY_TIMES+1:
- X p.r_delay = atoi(str);
- X break;
- X
- X /* used in axfer_setup() */
- X case ASCII_SETUP:
- X p.local_echo = str_dup(str);
- X break;
- X case ASCII_SETUP+1:
- X p.expand = str_dup(str);
- X break;
- X case ASCII_SETUP+2:
- X p.cr_delay = atoi(str);
- X break;
- X case ASCII_SETUP+3:
- X p.pace = str_dup(str);
- X break;
- X case ASCII_SETUP+4:
- X p.cr_up = str_dup(str);
- X break;
- X case ASCII_SETUP+5:
- X p.lf_up = str_dup(str);
- X break;
- X case ASCII_SETUP+6:
- X p.timer = atoi(str);
- X break;
- X case ASCII_SETUP+7:
- X p.cr_dn = str_dup(str);
- X break;
- X case ASCII_SETUP+8:
- X p.lf_dn = str_dup(str);
- X break;
- X
- X /* used in d_revise() */
- X case LD_CODES:
- X p.ld_plus = str_dup(str);
- X break;
- X case LD_CODES+1:
- X p.ld_minus = str_dup(str);
- X break;
- X case LD_CODES+2:
- X p.ld_at = str_dup(str);
- X break;
- X case LD_CODES+3:
- X p.ld_pound = str_dup(str);
- X break;
- X
- X /* used in macro() */
- X case MACROS:
- X p.mac_1 = str_dup(str);
- X break;
- X case MACROS+1:
- X p.mac_2 = str_dup(str);
- X break;
- X case MACROS+2:
- X p.mac_3 = str_dup(str);
- X break;
- X case MACROS+3:
- X p.mac_4 = str_dup(str);
- X break;
- X case MACROS+4:
- X p.mac_5 = str_dup(str);
- X break;
- X case MACROS+5:
- X p.mac_6 = str_dup(str);
- X break;
- X case MACROS+6:
- X p.mac_7 = str_dup(str);
- X break;
- X case MACROS+7:
- X p.mac_8 = str_dup(str);
- X break;
- X case MACROS+8:
- X p.mac_9 = str_dup(str);
- X break;
- X case MACROS+9:
- X p.mac_0 = str_dup(str);
- X break;
- X }
- X }
- X fclose(fp);
- X if (oops) {
- X sprintf(buf, "Parameter file \"%s\"", p.p_path);
- X error_win(1, buf, message);
- X }
- X return(&p);
- X}
- X
- X/*
- X * Write the updated param structure to disk. The values in memory should
- X * have already been "purified". A non-zero return code means non-fatal
- X * error.
- X */
- X
- int
- up_param()
- X{
- X FILE *fp, *uid_fopen();
- X char buf[80];
- X void error_win();
- X /* open for write */
- X if (!(fp = uid_fopen(param->p_path, "w"))) {
- X sprintf(buf, "\"%s\"", param->p_path);
- X error_win(0, "No write permission on parameter file", buf);
- X return(1);
- X }
- X
- X fprintf(fp, "D_BAUD=%d\n", param->d_baud);
- X fprintf(fp, "D_PARITY=%c\n", param->d_parity);
- X fprintf(fp, "D_DATA_BITS=%d\n", param->d_data_bits);
- X fprintf(fp, "D_STOP_BITS=%d\n", param->d_stop_bits);
- X fprintf(fp, "HOT_KEY=%d\n", param->hot_key);
- X fprintf(fp, "ASCII_HOT=%s\n", param->ascii_hot);
- X fprintf(fp, "D_DUPLEX=%s\n", param->d_duplex);
- X fprintf(fp, "FLOW_CTRL=%s\n", param->flow_ctrl);
- X fprintf(fp, "CR_IN=%s\n", param->cr_in);
- X fprintf(fp, "CR_OUT=%s\n", param->cr_out);
- X fprintf(fp, "LOGFILE=%s\n", param->logfile);
- X fprintf(fp, "DUMPFILE=%s\n", param->dumpfile);
- X fprintf(fp, "STRIP=%s\n", param->strip);
- X fprintf(fp, "PAUSE_CHAR=%c\n", param->pause_char);
- X fprintf(fp, "CR_CHAR=%c\n", param->cr_char);
- X fprintf(fp, "CTRL_CHAR=%c\n", param->ctrl_char);
- X fprintf(fp, "ESC_CHAR=%c\n", param->esc_char);
- X fprintf(fp, "BRK_CHAR=%c\n", param->brk_char);
- X fprintf(fp, "ABORT=%s\n", param->abort);
- X fprintf(fp, "C_DELAY=%d\n", param->c_delay);
- X fprintf(fp, "R_DELAY=%d\n", param->r_delay);
- X fprintf(fp, "LOCAL_ECHO=%s\n", param->local_echo);
- X fprintf(fp, "EXPAND=%s\n", param->expand);
- X fprintf(fp, "CR_DELAY=%d\n", param->cr_delay);
- X fprintf(fp, "PACE=%s\n", param->pace);
- X fprintf(fp, "CR_UP=%s\n", param->cr_up);
- X fprintf(fp, "LF_UP=%s\n", param->lf_up);
- X fprintf(fp, "TIMER=%d\n", param->timer);
- X fprintf(fp, "CR_DN=%s\n", param->cr_dn);
- X fprintf(fp, "LF_DN=%s\n", param->lf_dn);
- X fprintf(fp, "LD_PLUS=%s\n", param->ld_plus);
- X fprintf(fp, "LD_MINUS=%s\n", param->ld_minus);
- X fprintf(fp, "LD_AT=%s\n", param->ld_at);
- X fprintf(fp, "LD_POUND=%s\n", param->ld_pound);
- X fprintf(fp, "MAC_1=%s\n", param->mac_1);
- X fprintf(fp, "MAC_2=%s\n", param->mac_2);
- X fprintf(fp, "MAC_3=%s\n", param->mac_3);
- X fprintf(fp, "MAC_4=%s\n", param->mac_4);
- X fprintf(fp, "MAC_5=%s\n", param->mac_5);
- X fprintf(fp, "MAC_6=%s\n", param->mac_6);
- X fprintf(fp, "MAC_7=%s\n", param->mac_7);
- X fprintf(fp, "MAC_8=%s\n", param->mac_8);
- X fprintf(fp, "MAC_9=%s\n", param->mac_9);
- X fprintf(fp, "MAC_0=%s\n", param->mac_0);
- X
- X fclose(fp);
- X return(0);
- X}
- END_OF_FILE
- if test 7341 -ne `wc -c <'p_lib.c'`; then
- echo shar: \"'p_lib.c'\" unpacked with wrong size!
- fi
- # end of 'p_lib.c'
- fi
- if test -f 's_modem.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'s_modem.c'\"
- else
- echo shar: Extracting \"'s_modem.c'\" \(6948 characters\)
- sed "s/^X//" >'s_modem.c' <<'END_OF_FILE'
- X/*
- X * Display the modem setup, query for changes. A non-zero return code
- X * means something was changed.
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "misc.h"
- X#include "modem.h"
- X
- static int mod_prompt();
- static void disp_modem();
- X
- int
- modem_setup()
- X{
- X WINDOW *mo_win, *newwin();
- X int i, j, ret_code;
- X char *ans, *str_rep(), *str_prompt(), *menu_prompt();
- X extern char *v_yn[];
- 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 horizontal(mo_win, 0, 0, 33);
- X mvwattrstr(mo_win, 0, 34, A_BOLD, "Modem Setup");
- X horizontal(mo_win, 0, 46, 34);
- X /* display the current settings */
- X disp_modem(mo_win, j);
- X horizontal(mo_win, 19, 0, 80);
- X mvwattrstr(mo_win, 20, 0, A_BOLD, "OPTION ==> ");
- X mvwaddstr(mo_win, 20, 58, "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 = mod_prompt(mo_win);
- X break;
- X case 2:
- X if ((ans = str_prompt(mo_win, 3, 39, "Modem init string", "sent to the modem once")) != NULL) {
- X modem->init[j] = str_rep(modem->init[j], ans);
- X ret_code++;
- X }
- X break;
- X case 3:
- X if ((ans = str_prompt(mo_win, 4, 39, "Dialing command", "")) != NULL) {
- X modem->dial[j] = str_rep(modem->dial[j], ans);
- X ret_code++;
- X }
- X break;
- X case 4:
- X if ((ans = str_prompt(mo_win, 5, 39, "Dialing cmd suffix", "typically the <CR> character")) != NULL) {
- X modem->suffix[j] = str_rep(modem->suffix[j], ans);
- X ret_code++;
- X }
- X break;
- X case 5:
- X if ((ans = str_prompt(mo_win, 6, 39, "Hang up string", "")) != NULL) {
- X modem->hang_up[j] = str_rep(modem->hang_up[j], ans);
- X ret_code++;
- X }
- X break;
- X case 6:
- X if ((ans = menu_prompt(mo_win, 7, 39, "Auto Baud detect", v_yn)) != NULL) {
- X modem->auto_baud[j] = *ans;
- X ret_code++;
- X }
- X break;
- X case 7:
- X if ((ans = str_prompt(mo_win, 8, 39, "300 baud connect string", "")) != NULL) {
- X modem->con_3[j] = str_rep(modem->con_3[j], ans);
- X ret_code++;
- X }
- X break;
- X case 8:
- X if ((ans = str_prompt(mo_win, 9, 39, "1200 baud connect string", "")) != NULL) {
- X modem->con_12[j] = str_rep(modem->con_12[j], ans);
- X ret_code++;
- X }
- X break;
- X case 9:
- X if ((ans = str_prompt(mo_win, 10, 39, "2400 baud connect string", "")) != NULL) {
- X modem->con_24[j] = str_rep(modem->con_24[j], ans);
- X ret_code++;
- X }
- X break;
- X case 10:
- X if ((ans = str_prompt(mo_win, 11, 39, "4800 baud connect string", "")) != NULL) {
- X modem->con_48[j] = str_rep(modem->con_48[j], ans);
- X ret_code++;
- X }
- X break;
- X case 11:
- X if ((ans = str_prompt(mo_win, 12, 39, "9600 baud connect string", "")) != NULL) {
- X modem->con_96[j] = str_rep(modem->con_96[j], ans);
- X ret_code++;
- X }
- X break;
- X case 12:
- X if ((ans = str_prompt(mo_win, 13, 39, "19200 baud connect string", "")) != NULL) {
- X modem->con_192[j] = str_rep(modem->con_192[j], ans);
- X ret_code++;
- X }
- X break;
- X case 13:
- X if ((ans = str_prompt(mo_win, 14, 39, "38400 baud connect string", "")) != NULL) {
- X modem->con_384[j] = str_rep(modem->con_384[j], ans);
- X ret_code++;
- X }
- X break;
- X case 14:
- X if ((ans = str_prompt(mo_win, 15, 39, "No connect string 1", "")) != NULL) {
- X modem->no_con1[j] = str_rep(modem->no_con1[j], ans);
- X ret_code++;
- X }
- X break;
- X case 15:
- X if ((ans = str_prompt(mo_win, 16, 39, "No connect string 2", "")) != NULL) {
- X modem->no_con2[j] = str_rep(modem->no_con2[j], ans);
- X ret_code++;
- X }
- X break;
- X case 16:
- X if ((ans = str_prompt(mo_win, 17, 39, "No connect string 3", "")) != NULL) {
- X modem->no_con3[j] = str_rep(modem->no_con3[j], ans);
- X ret_code++;
- X }
- X break;
- X case 17:
- X if ((ans = str_prompt(mo_win, 18, 39, "No connect string 4", "")) != NULL) {
- X modem->no_con4[j] = str_rep(modem->no_con4[j], 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, FALSE);
- X clear_line(mo_win, 22, 0, FALSE);
- 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
- static int
- mod_prompt(win)
- WINDOW *win;
- X{
- X char ans;
- X int i;
- X void disp_modem();
- X /* print prompt lines */
- X mvwaddstr(win, 22, 0, "Press any key to change, or <CR> 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] == '\0')
- X i = 0;
- X if (ans == ESC)
- 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, 39, FALSE);
- X wrefresh(win);
- X mvwattrstr(win, 2, 39, A_BOLD, modem->mname[i]);
- X mvwprintw(win, 2, 25, "(%d of %d) ", i+1, modem->m_entries);
- X
- X return(i);
- X}
- X
- X/*
- X * Show the current settings for the given modem entry number.
- X */
- X
- static void
- disp_modem(w, i)
- WINDOW *w;
- int i;
- X{
- X mvwprintw(w, 2, 11, "1) Modem name ............. %-39.39s", modem->mname[i]);
- X mvwprintw(w, 2, 25, "(%d of %d) ", i+1, modem->m_entries);
- X mvwprintw(w, 3, 11, "2) Modem init string ...... %-39.39s", modem->init[i]);
- X mvwprintw(w, 4, 11, "3) Dialing command ........ %-39.39s", modem->dial[i]);
- X mvwprintw(w, 5, 11, "4) Dialing cmd suffix ..... %-39.39s", modem->suffix[i]);
- X mvwprintw(w, 6, 11, "5) Hang up string ......... %-39.39s", modem->hang_up[i]);
- X mvwprintw(w, 7, 11, "6) Auto baud detect ....... %c", modem->auto_baud[i]);
- X mvwprintw(w, 8, 11, "7) 300 baud connect ....... %-39.39s", modem->con_3[i]);
- X mvwprintw(w, 9, 11, "8) 1200 baud connect ...... %-39.39s", modem->con_12[i]);
- X mvwprintw(w, 10, 11, "9) 2400 baud connect ...... %-39.39s", modem->con_24[i]);
- X mvwprintw(w, 11, 10, "10) 4800 baud connect ...... %-39.39s", modem->con_48[i]);
- X mvwprintw(w, 12, 10, "11) 9600 baud connect ...... %-39.39s", modem->con_96[i]);
- X mvwprintw(w, 13, 10, "12) 19200 baud connect ..... %-39.39s", modem->con_192[i]);
- X mvwprintw(w, 14, 10, "13) 38400 baud connect ..... %-39.39s", modem->con_384[i]);
- X mvwprintw(w, 15, 10, "14) No connect string 1 .... %-39.39s", modem->no_con1[i]);
- X mvwprintw(w, 16, 10, "15) No connect string 2 .... %-39.39s", modem->no_con2[i]);
- X mvwprintw(w, 17, 10, "16) No connect string 3 .... %-39.39s", modem->no_con3[i]);
- X mvwprintw(w, 18, 10, "17) No connect string 4 .... %-39.39s", modem->no_con4[i]);
- X return;
- X}
- END_OF_FILE
- if test 6948 -ne `wc -c <'s_modem.c'`; then
- echo shar: \"'s_modem.c'\" unpacked with wrong size!
- fi
- # end of 's_modem.c'
- fi
- if test -f 'terminal.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'terminal.c'\"
- else
- echo shar: Extracting \"'terminal.c'\" \(8778 characters\)
- sed "s/^X//" >'terminal.c' <<'END_OF_FILE'
- X/*
- X * Start the terminal dialogue, scan the TTY, keyboard, and the "script"
- X * for input, watch for the hot key so we can execute an option.
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include <signal.h>
- X#include "config.h"
- X#include "dial_dir.h"
- X#include "ipc.h"
- X#include "misc.h"
- X#include "modem.h"
- X#include "param.h"
- X#include "status.h"
- X#include "xmodem.h"
- X
- X#ifdef BSD
- X#ifndef SIGCLD
- X#define SIGCLD SIGCHLD
- X#endif /* SIGCLD */
- X#include <sys/file.h>
- X#else /* BSD */
- X#include <fcntl.h>
- X#endif /* BSD */
- X
- X#ifdef UNIXPC
- X#include <sys/phone.h>
- X#endif /* UNIXPC */
- X
- static void key_input();
- static int cr_lf;
- X
- void
- terminal(script)
- char *script;
- X{
- X extern int fd;
- X int ret_code;
- X void tty_input(), st_line(), term_mode(), cmd_input(), do_script();
- X void is_active(), ipc_init();
- X
- X ipc_init(fd, status->cmd_ipc);
- X /* if not starting with -f option */
- X if (dir->q_num[0] == -1) {
- X erase();
- X refresh();
- X st_line("");
- X }
- X /* put stdin/stdout in terminal mode */
- X resetterm();
- X term_mode();
- X cr_lf = !strcmp(param->cr_out, "CR/LF");
- X
- X /* play a script from command line */
- X if (script != NULL && *script != '\0')
- X do_script(script);
- X
- X /* the main loop ! */
- X /* CONSTCOND */
- X while (1) {
- X ret_code = ipc_poll(fd, status->cmd_ipc);
- X
- X if (ret_code & TTY_READY)
- X tty_input();
- X
- X if (ret_code & KEY_READY)
- X key_input();
- X
- X /*
- X * This is the reason for the 1 sec "timeout" of the
- X * poll/select call... to periodically check the status
- X * of the "script" for input.
- X */
- X if (status->dup_fd != -1)
- X is_active();
- X /* do a command from a script */
- X if (ret_code & CMD_READY)
- X cmd_input();
- X }
- X /* NOTREACHED */
- X}
- X
- X/*
- X * There is something ready to be read from the keyboard.
- X */
- X
- static void
- key_input()
- X{
- X extern int fd;
- X int i, k;
- X char c, lf=10, *str_rep(), *keymac, *script, *script_menu();
- X void help_screen(), line_set(), n_shell(), load_vs(), send_str();
- X void release_port(), list_dir(), pexit(), st_line(), chg_dir();
- X void screen_dump(), info(), term_mode(), macro(), stop_script();
- X void setup_menu(), xfer_menu(), data_logging(), pass_thru();
- X void half_duplex(), do_script(), vs_clear(), tty_restart();
- X void log_toggle(), lpr_toggle();
- X
- X read(0, &c, 1);
- X c &= 0x7f;
- X /* stop the script? */
- X if (status->dup_fd != -1 && c == ESC) {
- X stop_script();
- X return;
- X }
- X /* is it the hot key? */
- X if (c == param->hot_key) {
- X
- X script = NULL;
- X /*
- X * Put the terminal in the curses mode, load the
- X * virtual screen and add the status line at the bottom.
- X */
- X fixterm();
- X load_vs();
- X st_line("");
- X#ifndef OLDCURSES
- X keypad(stdscr, TRUE);
- X#endif /* OLDCURSES */
- X i = wgetch(stdscr);
- X /* map an additional hot key to -1 */
- X if (i == param->hot_key)
- X i = -1;
- X
- X keymac = "";
- X /* look for options */
- X k = -1;
- X switch (i) {
- X case -1: /* 2 "hots" means send 1 */
- X k = param->hot_key;
- X break;
- X case '0': /* help screen */
- X help_screen(param->ascii_hot);
- X break;
- X case 'd':
- X case 'D': /* dialing directory */
- X if (dial_menu()) {
- X if (!dial_win(25))
- X script = dir->aux[0];
- X }
- X break;
- X case 'r':
- X case 'R': /* redial */
- X if (redial()) {
- X if (!dial_win(25))
- X script = dir->aux[0];
- X }
- X break;
- X case 'm':
- X case 'M': /* keyboard macros */
- X macro();
- X break;
- X case 'p':
- X case 'P': /* line settings */
- X if (ls_menu())
- X line_set();
- X break;
- X case 'x':
- X case 'X': /* exit */
- X pexit();
- X break;
- X case '4': /* Unix gateway */
- X n_shell();
- X break;
- X case '5': /* Command files */
- X script = script_menu();
- X break;
- X case 'i':
- X case 'I': /* program info screen */
- X info(MANUAL_CLEAR);
- X break;
- X case 's': /* setup menu */
- X case 'S':
- X setup_menu();
- X break;
- X case 'c': /* clear the screen */
- X case 'C':
- X erase();
- X vs_clear(0);
- X break;
- X case 'b':
- X case 'B': /* change directory */
- X chg_dir();
- X break;
- X case 'e':
- X case 'E': /* toggle duplex */
- X if (dir->duplex[0] == 'F')
- X dir->duplex[0] = 'H';
- X else
- X dir->duplex[0] = 'F';
- X
- X /* show changes */
- X st_line("");
- X k = wait_key(stdscr, 2);
- X break;
- X case 'h':
- X case 'H': /* hang up phone */
- X release_port(VERBOSE);
- X break;
- X case 'l':
- X case 'L': /* print toggle */
- X lpr_toggle();
- X /* show changes */
- X st_line("");
- 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 = str_rep(param->cr_in, "CR/LF");
- X else
- X param->cr_in = str_rep(param->cr_in, "CR");
- X /* show changes */
- X st_line("");
- X k = wait_key(stdscr, 2);
- X break;
- X case '7': /* break key */
- X if (fd != -1)
- X tty_break(fd);
- X
- X st_line(" break");
- X break;
- X#ifndef OLDCURSES
- X case KEY_UP:
- X#endif /* OLDCURSES */
- X case 'u':
- X case 'U': /* send files */
- X xfer_menu(UP_LOAD);
- X break;
- X#ifndef OLDCURSES
- X case KEY_DOWN:
- X case '\n':
- X#endif /* OLDCURSES */
- X case 'n':
- X case 'N': /* receive files */
- X xfer_menu(DOWN_LOAD);
- X break;
- X case 't':
- X case 'T':
- X pass_thru();
- X break;
- X case 'f':
- X case 'F': /* list directory */
- X list_dir();
- X break;
- X case 'g': /* screen dump */
- X case 'G':
- X screen_dump();
- X st_line(" screen dump");
- X k = wait_key(stdscr, 2);
- X break;
- X case '1': /* data logging */
- X data_logging();
- X break;
- X case '2': /* toggle log */
- X if (!strcmp(status->log_path, "NOT_DEFINED")) {
- X beep();
- X st_line(" no log file");
- X k = wait_key(stdscr, 2);
- X break;
- X }
- X log_toggle();
- X /* show changes */
- X st_line("");
- X k = wait_key(stdscr, 2);
- X break;
- X /*
- X * The following are the keyboard macros
- X * corresponding to the shifted number keys.
- X * (Too many keys... [control] [A] [shift] [1]
- X * is hardly a shortcut!)
- X */
- X case '!':
- X keymac = param->mac_1;
- X break;
- X case '@':
- X keymac = param->mac_2;
- X break;
- X case '#':
- X keymac = param->mac_3;
- X break;
- X case '$':
- X keymac = param->mac_4;
- X break;
- X case '%':
- X keymac = param->mac_5;
- X break;
- X case '^':
- X keymac = param->mac_6;
- X break;
- X case '&':
- X keymac = param->mac_7;
- X break;
- X case '*':
- X keymac = param->mac_8;
- X break;
- X case '(':
- X keymac = param->mac_9;
- X break;
- X case ')':
- X keymac = param->mac_0;
- X break;
- X default:
- X fputc(BEL, stderr);
- X break;
- X }
- X
- X /*
- X * Repaint the stdscr (if we are already talking),
- X * get the stdin/stdout out of the curses mode and
- X * into the terminal mode.
- X */
- X if (fd != -1) {
- X touchwin(stdscr);
- X refresh();
- X }
- X resetterm();
- X term_mode();
- X /* restart stopped flow control */
- X tty_restart();
- X
- X /*
- X * Some of the output processing options have to be
- X * faked... Unfortunately, adding a LF to CR on
- X * output is one of them.
- X */
- X cr_lf = !strcmp(param->cr_out, "CR/LF");
- X
- X /* play the script */
- X if (script != NULL && *script != '\0')
- X do_script(script);
- X
- X /* send the macro */
- X if (*keymac != '\0')
- X send_str(keymac, FAST);
- 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 return;
- X c = (char) k;
- X }
- X /* ignore errors if fd == -1 */
- X write(fd, &c, 1);
- X
- X /*
- X * If you're using the half duplex mode, characters don't get
- X * echoed by the driver (cause you don't type them!)
- X */
- X if (dir->duplex[0] == 'H')
- X half_duplex(c);
- X /* map cr to cr_lf? */
- X if (c == '\r' && cr_lf) {
- X write(fd, &lf, 1);
- X
- X if (dir->duplex[0] == 'H') {
- X write(1, &lf, 1);
- X half_duplex(lf);
- X }
- X }
- X return;
- X}
- X
- X/*
- X * Hang up the phone but remain in the Pcomm command state. Uses the
- X * hang_up string only, does *not* drop the DTR!
- X */
- X
- void
- hang_up(verbose)
- int verbose;
- X{
- X extern int fd;
- X void send_str(), st_line(), tty_restart();
- X unsigned int sleep();
- X /* sanity checking */
- X if (modem == NULL)
- X return;
- X /* anything to hang up? */
- X if (modem->m_cur == -1 || fd == -1)
- X return;
- X
- X if (verbose)
- X st_line("disconnecting");
- X /* special case for OBM */
- X if (!strcmp(modem->mname[modem->m_cur], "OBM")) /* EMPTY */ {
- X#ifdef UNIXPC
- X char buf[80];
- X void line_set();
- X
- X ioctl(fd, PIOCDISC);
- X /*
- X * The PIOCDISC ioctl screws up the file descriptor!!!
- X * No other phone(7) ioctl can fix it. Whatever it does,
- X * it seems to escape detection with PIOCGETA and TCGETA.
- X * The best I can do is close the port and start over.
- X */
- X sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
- X close(fd);
- X fd = open(buf, O_RDWR|O_NDELAY);
- X line_set();
- X tty_noblock(fd, FALSE);
- X#endif /* UNIXPC */
- X }
- X else {
- X tty_restart();
- X send_str(modem->hang_up[modem->m_cur], SLOW);
- X sleep(1);
- X }
- X
- X if (verbose)
- X st_line("");
- X
- X status->connected = 0;
- X return;
- X}
- END_OF_FILE
- if test 8778 -ne `wc -c <'terminal.c'`; then
- echo shar: \"'terminal.c'\" unpacked with wrong size!
- fi
- # end of 'terminal.c'
- fi
- if test -f 'x_ascii.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'x_ascii.c'\"
- else
- echo shar: Extracting \"'x_ascii.c'\" \(6560 characters\)
- sed "s/^X//" >'x_ascii.c' <<'END_OF_FILE'
- 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 <stdio.h>
- X#include <curses.h>
- X#include <signal.h>
- X#include "config.h"
- X#include "misc.h"
- X#include "param.h"
- X
- X#ifdef BSD
- X#include <setjmp.h>
- jmp_buf bl_buf;
- X#endif /* BSD */
- X
- static void send_ascii(), rcv_ascii(), putc_ascii();
- static int bgetc_line(), buf_read();
- X
- void
- xfer_ascii(list, up)
- char *list;
- int up;
- X{
- X int cr_lf;
- X char *file, *strtok();
- X void line_set(), st_line();
- X void ascii_mode(), term_mode();
- X unsigned int sleep();
- X
- X touchwin(stdscr);
- X refresh();
- X /* only one file from list */
- X file = strtok(list, " \t");
- X
- X cr_lf = !strcmp(param->cr_out, "CR/LF");
- X ascii_mode(up);
- X /* out of curses mode */
- X resetterm();
- X term_mode();
- X tty_noblock(0, TRUE);
- X
- X if (up)
- X send_ascii(file, cr_lf);
- 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 line_set();
- X fixterm();
- X tty_noblock(0, FALSE);
- X
- X beep();
- X st_line("xfer complete");
- X
- X sleep(2);
- X return;
- 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
- static void
- send_ascii(file, cr_lf)
- char *file;
- int cr_lf;
- X{
- X extern int fd;
- X FILE *fp, *uid_fopen();
- X int i, j, strip_cr, strip_lf, add_cr, add_lf, expand, local_echo, pace;
- X char buf[80], c, last;
- X unsigned int sleep();
- X void error_win();
- X /* permission already checked */
- X if (!(fp = uid_fopen(file, "r"))) {
- X sprintf(buf, "\"%s\"", file);
- X error_win(0, "Can't open file for read", buf);
- X return;
- X }
- 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 local_echo = !strcmp(param->local_echo, "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 ESC: /* <ESC> key for abort */
- X fclose(fp);
- X sleep(2);
- X tty_drain(fd);
- X return;
- X default: /* send the char */
- X c = (char) j & 0x7f;
- X putc_ascii(c, local_echo);
- X if (c == '\r' && cr_lf)
- X putc_ascii('\n', local_echo);
- X break;
- X }
- X c = (char) i & 0x7f;
- X /* expand blank lines */
- X if (expand && last == '\n' && c == '\n')
- X putc_ascii(' ', local_echo);
- X last = c;
- X
- X /* CR translations */
- X if (c == '\r' && strip_cr)
- X continue;
- X if (c == '\r' && add_lf) {
- X putc_ascii(c, local_echo);
- X putc_ascii('\n', local_echo);
- X continue;
- X }
- X /* LF translations */
- X if (c == '\n' && strip_lf)
- X continue;
- X if (c == '\n' && add_cr)
- X putc_ascii('\r', local_echo);
- X
- X putc_ascii(c, local_echo);
- 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 tty_drain(fd);
- X }
- X fclose(fp);
- X sleep(2);
- X tty_drain(fd);
- X return;
- X}
- X
- X/* Put a character on the line, echo it too, if required */
- X
- static void
- putc_ascii(c, local_echo)
- char c;
- int local_echo;
- X{
- X extern int fd;
- X void vs_putchar();
- X
- X write(fd, &c, 1);
- X if (local_echo) {
- X write(1, &c, 1);
- X vs_putchar(c);
- X }
- 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 bgetc_line()
- X * and non-blocking input makes it seem like full duplex, but it's not.
- X * Be aware that while the timer is active the keyboard is deaf.
- X */
- X
- static void
- rcv_ascii(file, cr_lf)
- char *file;
- int cr_lf;
- X{
- X FILE *fp, *uid_fopen();
- X int i, strip_cr, strip_lf, add_cr, add_lf, got_first;
- X unsigned int delay;
- X char c, buf[80];
- X void error_win(), vs_putchar();
- X /* permission already checked */
- X if (!(fp = uid_fopen(file, "w"))) {
- X sprintf(buf, "\"%s\"", file);
- X error_win(0, "Can't open file for write", buf);
- X return;
- X }
- 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 /* CONSTCOND */
- X while (1) {
- X /* keyboard activity */
- X switch (i = getchar()) {
- X case -1: /* no key was pressed */
- X break;
- X case ESC: /* <ESC> key */
- X fclose(fp);
- X return;
- X default: /* send it */
- X c = (unsigned int) i;
- X putc_line((unsigned char) c);
- X if (c == '\r' && cr_lf)
- X putc_line('\n');
- X break;
- X }
- X /* read a character */
- X if ((i = bgetc_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 & 0x7f;
- X /* display it on the screen */
- X write(1, &c, 1);
- X vs_putchar(c);
- X /* CR translations */
- X if (c == '\r' && strip_cr)
- X continue;
- X if (c == '\r' && add_lf) {
- X fputc(c, fp);
- X fputc('\n', fp);
- X continue;
- X }
- X /* LF translations */
- X if (c == '\n' && strip_lf)
- X continue;
- X if (c == '\n' && add_cr) {
- X fputc('\r', fp);
- X fputc(c, fp);
- X continue;
- X }
- X fputc(c, fp);
- X }
- X}
- X
- X/*
- X * Get a character from the line (using buffered I/O) with a specified
- X * time-out period in seconds. If the function times-out, it returns a -1.
- X */
- X
- static int bl_flag;
- static int bl_force();
- X
- static int
- bgetc_line(sec)
- unsigned int sec;
- X{
- X int c;
- X unsigned int alarm();
- X
- X signal(SIGALRM, (SIG_TYPE(*) ()) bl_force);
- X bl_flag = 0;
- X
- X alarm(sec);
- X
- X#ifdef BSD
- X if (setjmp(bl_buf))
- X return(-1);
- X#endif /* BSD */
- X
- X if ((c = buf_read()) < 0) {
- X alarm(0);
- X return(-1);
- X }
- X if (bl_flag)
- X return(-1);
- X alarm(0);
- X return(c);
- X}
- X
- X/* ARGSUSED */
- static int
- bl_force(dummy)
- int dummy;
- X{
- X#ifdef BSD
- X longjmp(bl_buf, 1);
- X#else /* BSD */
- X signal(SIGALRM, (SIG_TYPE(*) ()) bl_force);
- X bl_flag = 1;
- X return(0);
- X#endif /* BSD */
- X}
- X
- X/*
- X * Do a single character buffered read from the serial port.
- X */
- X
- static int
- buf_read()
- X{
- X extern int fd;
- X static char buf[CLIST_SIZ];
- X static char *bufp = buf;
- X static int n = 0;
- X
- X if (n <= 0) {
- X n = read(fd, buf, CLIST_SIZ);
- X bufp = buf;
- X }
- X if (--n >= 0)
- X return(*bufp++ & 0xff);
- X return(-1);
- X}
- END_OF_FILE
- if test 6560 -ne `wc -c <'x_ascii.c'`; then
- echo shar: \"'x_ascii.c'\" unpacked with wrong size!
- fi
- # end of 'x_ascii.c'
- fi
- if test -f 'x_batch.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'x_batch.c'\"
- else
- echo shar: Extracting \"'x_batch.c'\" \(8917 characters\)
- sed "s/^X//" >'x_batch.c' <<'END_OF_FILE'
- X/*
- X * Routines to support the batch protocols.
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <curses.h>
- X#include "config.h"
- X#include "misc.h"
- X#include "xmodem.h"
- X
- static char *fix_name();
- static void change_name(), unfix_name(), change_name();
- X
- X/*
- X * Send the file name for the modem7 batch. Only uses 11 characters
- X * of the filename. Returns zero on success or the standard error codes.
- X */
- X
- int
- send_modem7(win, name)
- WINDOW *win;
- char *name;
- X{
- X char *new_name;
- X unsigned char sum, calc_sum();
- X
- X /* convert to 11 character name */
- X new_name = fix_name(name);
- X sum = calc_sum((unsigned char *) new_name, 12);
- X
- X putc_line(ACK);
- X /* for each character in the name */
- X while (*new_name != CTRLZ) {
- X putc_line((unsigned char) *new_name);
- X
- X switch (getc_line(3)) {
- X case -1: /* timed out */
- X clear_line(win, 12, 24, TRUE);
- X waddstr(win, "NO RESPONSE");
- X wrefresh(win);
- X return(ERROR);
- X case ACK: /* got it! */
- X break;
- X case CAN: /* cancel transmission */
- X if (getc_line(2) == CAN) {
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "REMOTE ABORTED");
- X wrefresh(win);
- X return(CANCEL);
- X }
- X /* FALLTHRU */
- X default:
- X clear_line(win, 12, 24, TRUE);
- X waddstr(win, "NAME FAILED");
- X wrefresh(win);
- X return(ERROR);
- X }
- X new_name++;
- X }
- X putc_line(CTRLZ);
- X /* verify the checksum */
- X if (getc_line(10) != sum) {
- X putc_line('u');
- X clear_line(win, 12, 24, TRUE);
- X waddstr(win, "CHECKSUM FAILED");
- X wrefresh(win);
- X return(ERROR);
- X }
- X putc_line(ACK);
- X return(0);
- X}
- X
- X/*
- X * Receive a modem7 file name. Returns zero on success, the standard error
- X * codes, or a -1 on the end-of-batch. (Oddly enough, the end-of-batch code
- X * is the same as the code for a user abort)
- X */
- X
- int
- rcv_modem7(win, default_err)
- WINDOW *win;
- int default_err;
- X{
- X extern char file_name[15];
- X int i, j, err_method, err_count, got_it;
- X unsigned char sum, calc_sum();
- X char temp_name[13];
- X
- X err_method = default_err;
- X if (default_err == CRC_CHECKSUM)
- X err_method = CRC;
- X
- X err_count = 0;
- X got_it = 0;
- X while (err_count < MAX_ERRORS) {
- X /* switch to checksum? */
- X if (default_err == CRC_CHECKSUM && err_count > MAX_ERRORS/2)
- X err_method = CHECKSUM;
- X
- X if (err_method == CRC)
- X putc_line('C');
- X else
- X putc_line(NAK);
- X /* what'd we get? */
- X switch (getc_line(10)) {
- X case -1: /* timed out */
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "NO RESPONSE");
- X wrefresh(win);
- X err_count++;
- X break;
- X case ACK: /* ready to go... */
- X got_it++;
- X break;
- X default: /* huh? */
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "BAD HEADER");
- X wrefresh(win);
- X err_count++;
- X }
- X if (got_it)
- X break;
- X }
- X if (!got_it)
- X return(ERROR);
- X /* get the name */
- X for (i=0; i<12; i++) {
- X j = getc_line(3);
- X
- X switch (j) {
- X case -1: /* timed out */
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "NO RESPONSE");
- X wrefresh(win);
- X return(ERROR);
- X case EOT: /* end of batch? */
- X return(-1);
- X case CAN: /* cancel transmission */
- X if (getc_line(2) == CAN) {
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "REMOTE ABORTED");
- X wrefresh(win);
- X return(CANCEL);
- X }
- X /* FALLTHRU */
- X case 'u': /* bad name character */
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "BAD NAME");
- X wrefresh(win);
- X return(ERROR);
- X default: /* the name... */
- X temp_name[i] = j & 0xff;
- X if (j != CTRLZ)
- X putc_line(ACK);
- X break;
- X }
- X }
- X temp_name[12] = '\0';
- X /* send our checksum */
- X sum = calc_sum((unsigned char *) temp_name, 12);
- X putc_line(sum);
- X /* do they agree? */
- X if (getc_line(10) != ACK) {
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "BAD NAME");
- X wrefresh(win);
- X return(ERROR);
- X }
- X /* load the file_name array */
- X unfix_name(temp_name);
- X /* any name collisions? */
- X change_name(win, file_name);
- X return(0);
- X}
- X
- X/*
- X * Send the block 0 information for a ymodem batch transfer. Uses only
- X * the name component of the path and the file size.
- X */
- X
- int
- send_ymodem(win, file, size)
- WINDOW *win;
- char *file;
- long size;
- X{
- X unsigned short crc, calc_crc();
- X char *strcpy(), *memset();
- X unsigned char buf[133];
- X /* start with a clean block */
- X memset((char *) buf, '\0', 133);
- X /* the header */
- X buf[0] = SOH;
- X buf[1] = 0;
- X buf[2] = 255;
- X
- X /*
- X * The block zero consists of the file name (no path component),
- X * a NULL, and the file length (as a string). The end of batch
- X * marker is an empty block.
- X */
- X if (*file != '\0') {
- X strcpy((char *) &buf[3], file);
- X sprintf((char *) &buf[strlen(file)+4], "%ld", size);
- X }
- X /* the crc */
- X crc = calc_crc(&buf[3], 128);
- X buf[131] = crc >> 8;
- X buf[132] = crc & 0xff;
- X /* the block count */
- X mvwaddstr(win, 7, 24, "0 ");
- X
- X return(send_block(win, buf, 133));
- X}
- X
- X/*
- X * Receive the block 0 information for a ymodem batch transfer. We
- X * only use the file name and the size (if present). Currently doesn't
- X * support full path names.
- X */
- X
- int
- rcv_ymodem(win)
- WINDOW *win;
- X{
- X extern unsigned char buf[1029];
- X extern long file_length;
- X extern char file_name[15];
- X int code, length_is_at;
- X long atol();
- X
- X file_length = 0L;
- X file_name[0] = '\0';
- X /* read the zero block */
- X if (code = rcv_block(win, 1, 1024, 0))
- X return(code);
- X /* at end of batch */
- X if (buf[3] == '\0')
- X return(0);
- X /* get the file name */
- X change_name(win, (char *) &buf[3]);
- X /* any trouble? */
- X if (file_name[0] == '\0') {
- X putc_line(CAN);
- X return(0);
- X }
- X /*
- X * The file length is placed after the NULL of the file name
- X * and is terminated by another NULL. If the length is missing,
- X * atol() will see a NULL and return 0.
- X */
- X length_is_at = strlen((char *) &buf[3]) + 4;
- X file_length = atol((char *) &buf[length_is_at]);
- X return(0);
- X}
- X
- X/*
- X * Handle file name collisions. Prepend an "X" to the name until you find
- X * a name that doesn't already exist. Creates a NULL name on error.
- X * Loads the global character array "file_name".
- X */
- X
- static void
- change_name(win, str)
- WINDOW *win;
- char *str;
- X{
- X extern char file_name[15];
- X register int i;
- X int modified;
- X char temp[15], ans[15], *s, *strrchr(), *strcpy(), *strncat();
- X char *strncpy();
- X unsigned int sleep();
- X /* dissect the name component */
- X if ((s = strrchr(str, '/')))
- X strncpy(temp, ++s, 15);
- X else
- X strncpy(temp, str, 15);
- X temp[14] = '\0';
- X
- X strcpy(ans, temp);
- X file_name[0] = '\0';
- X /* write permission on directory? */
- X if (access(".", 2)) {
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X wattrstr(win, A_BOLD, "NO WRITE ON DIRECTORY");
- X wrefresh(win);
- X return;
- X }
- X /* prepend up to 13 "X"s */
- X modified = 0;
- X for (i=1; i<14; i++) {
- X if (access(ans, 0)) {
- X if (modified) {
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X waddstr(win, "NAME COLLISION");
- X wrefresh(win);
- X sleep(1);
- X }
- X strcpy(file_name, ans);
- X return;
- X }
- X
- X modified++;
- X strcpy(temp, "X");
- X strncat(temp, ans, 13);
- X temp[14] = '\0';
- X strcpy(ans, temp);
- X }
- X beep();
- X clear_line(win, 12, 24, TRUE);
- X waddstr(win, "BAD NAME");
- X wrefresh(win);
- X return;
- X}
- X
- X/*
- X * Convert a perfectly good Unix file name to fit the CP/M file name
- X * rules. Used for the modem7 batch file transfer. Returns a pointer
- X * to a static area containing the new name.
- X */
- X
- static char *
- fix_name(path)
- char *path;
- X{
- X int i, dot;
- X char *s, *name, temp[15], *ext, *strncpy(), *strrchr();
- X static char ans[13];
- X /* ignore the path component */
- X if (s = strrchr(path, '/'))
- X strncpy(temp, ++s, 15);
- X else
- X strncpy(temp, path, 15);
- X temp[14] = '\0';
- X name = temp;
- X
- X ext = "";
- X dot = 0;
- X for (i=strlen(temp)-1; i>=0; i--) {
- X if (temp[i] == '.' && !dot) {
- X dot = 1;
- X temp[i] = '\0';
- X ext = &temp[i+1];
- X }
- X if (islower(temp[i]))
- X temp[i] = toupper(temp[i]);
- X }
- X /* if null name component */
- X if (*name == '\0')
- X name = "X";
- X /* if name too long */
- X if (strlen(name) > 8)
- X *(name+8) = '\0';
- X /* if extension too long */
- X if (strlen(ext) > 3)
- X *(ext+3) = '\0';
- X
- X sprintf(ans, "%-8.8s%-3.3s%c", temp, ext, CTRLZ);
- X return(ans);
- X}
- X
- X/*
- X * Convert a CP/M style filename into a legal Unix file name. Loads the
- X * global character array "file_name".
- X */
- X
- static void
- unfix_name(cpm_name)
- char *cpm_name;
- X{
- X extern char file_name[15];
- X register int i, n;
- X int dot;
- X char temp[15], *strcpy();
- X
- X file_name[0] = '\0';
- X if (*cpm_name == '\0')
- X return;
- X
- X strcpy(temp, cpm_name);
- X /* 8 character of the name */
- X n = 0;
- X for (i=0; i<8; i++) {
- X if (temp[i] != ' ') {
- X if (isupper(temp[i]))
- X file_name[n++] = tolower(temp[i]);
- X else
- X file_name[n++] = temp[i];
- X }
- X }
- X /* 3 character extension */
- X dot = 0;
- X for (i=8; i<11; i++) {
- X if (temp[i] != ' ') {
- X if (!dot) {
- X dot++;
- X file_name[n++] = '.';
- X }
- X if (isupper(temp[i]))
- X file_name[n++] = tolower(temp[i]);
- X else
- X file_name[n++] = temp[i];
- X }
- X }
- X file_name[n] = '\0';
- X return;
- X}
- END_OF_FILE
- if test 8917 -ne `wc -c <'x_batch.c'`; then
- echo shar: \"'x_batch.c'\" unpacked with wrong size!
- fi
- # end of 'x_batch.c'
- fi
- if test -f 'x_menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'x_menu.c'\"
- else
- echo shar: Extracting \"'x_menu.c'\" \(7412 characters\)
- sed "s/^X//" >'x_menu.c' <<'END_OF_FILE'
- X/*
- X * Open a window to display the choices of file transfer protocols and
- X * prompt for the file name(s).
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <curses.h>
- X#include "extrnl.h"
- X#include "misc.h"
- X#include "xmodem.h"
- X
- static char *get_names(), *get_extrnl();
- X
- void
- xfer_menu(up)
- int up;
- X{
- X extern int fd;
- X extern char *null_ptr;
- X WINDOW *xm_win, *newwin();
- X char buf[2048], *list, *strcat(), *strcpy();
- X int type, is_batch, i, ans, num_extrnl, n;
- X void xfer_win(), xfer_ascii(), do_extrnl(), error_win();
- X
- X num_extrnl = (up) ? extrnl->up_entries : extrnl->dn_entries;
- X xm_win = newwin(14+num_extrnl, 20, 2, 45);
- X
- X mvwaddstr(xm_win, 2, 3, "1) xmodem");
- X mvwaddstr(xm_win, 3, 3, "2) xmodem-1k");
- X mvwaddstr(xm_win, 4, 3, "3) modem7");
- X mvwaddstr(xm_win, 5, 3, "4) ymodem");
- X mvwaddstr(xm_win, 6, 3, "5) ymodem-g");
- X mvwaddstr(xm_win, 7, 3, "6) ASCII");
- X
- X for (i=0; i<num_extrnl; i++)
- X mvwprintw(xm_win, i+8, 3, "%d) %-12.12s", i+7, extrnl->name[up][i]);
- X mvwaddstr(xm_win, i+8, 3, "E) (external)");
- X mvwaddstr(xm_win, i+10, 3, "<ESC> to Abort");
- X mvwaddstr(xm_win, i+11, 3, "Protocol:");
- X box(xm_win, VERT, HORZ);
- X if (up)
- X mvwattrstr(xm_win, 0, 6, A_BOLD, " Upload ");
- X else
- X mvwattrstr(xm_win, 0, 5, A_BOLD, " Download ");
- X
- X wmove(xm_win, i+11, 13);
- X wrefresh(xm_win);
- X /* get the protocol */
- X type = -1;
- X while ((ans = wgetch(xm_win)) != ESC) {
- X switch (ans) {
- X case '1':
- X type = XMODEM;
- X break;
- X case '2':
- X type = XMODEM_1k;
- X break;
- X case '3':
- X type = MODEM7;
- X break;
- X case '4':
- X type = YMODEM;
- X break;
- X case '5':
- X type = YMODEM_G;
- X break;
- X case '6':
- X type = XASCII;
- X break;
- X case '7':
- X if (num_extrnl >= 1)
- X type = EXT_1;
- X else
- X beep();
- X break;
- X case '8':
- X if (num_extrnl >= 2)
- X type = EXT_2;
- X else
- X beep();
- X break;
- X case '9':
- X if (num_extrnl >= 3)
- X type = EXT_3;
- X else
- X beep();
- X break;
- X case 'e':
- X case 'E':
- X type = EXT_MANUAL;
- X break;
- X default:
- X beep();
- X }
- X if (type != -1)
- X break;
- X }
- X werase(xm_win);
- X wrefresh(xm_win);
- X delwin(xm_win);
- X /* chicken'd out */
- X if (type == -1)
- X return;
- X
- X if (fd == -1) {
- X error_win(0, "Not currently connected to any host", "");
- X return;
- X }
- X /* which protocol? */
- X is_batch = 0;
- X switch(type) {
- X case MODEM7:
- X case YMODEM:
- X case YMODEM_G: /* built-in protocols */
- X is_batch++;
- X /* FALLTHRU */
- X case XMODEM:
- X case XMODEM_1k: /* non-batch built-ins */
- X list = null_ptr;
- X /*
- X * When receiving in a batch mode, don't prompt
- X * for file names.
- X */
- X if (up || !is_batch) {
- X if (!(list = get_names(up, type, is_batch)))
- X break;
- X }
- X xfer_win(list, up, type);
- X break;
- X case XASCII: /* ascii xfer, yuck! */
- X if (list = get_names(up, type, FALSE))
- X xfer_ascii(list, up);
- X break;
- X case EXT_1:
- X case EXT_2:
- X case EXT_3: /* one of the externals */
- X n = type -NUM_INTERNAL -1;
- X strcpy(buf, extrnl->command[up][n]);
- X /* see if we need to prompt for files */
- X if (extrnl->prompt[up][n] == 'Y') {
- X if (list = get_names(up, type, TRUE)) {
- X strcat(buf, " ");
- X strcat(buf, list);
- X }
- X else
- X break;
- X }
- X do_extrnl(buf);
- X break;
- X case EXT_MANUAL: /* the manual external protocol */
- X if (list = get_extrnl(up))
- X do_extrnl(list);
- X break;
- X }
- X return;
- X}
- X
- char *protocol[NUM_INTERNAL] = {"xmodem", "xmodem-1k", "modem7", "ymodem",
- X "ymodem-g", "ASCII"};
- X
- X/*
- X * Prompt for a list of files for the transfer programs. Since expand()
- X * is used, it returns a pointer to a static area. Returns a NULL if
- X * you chicken'd out.
- X */
- X
- static char *
- get_names(up, type, is_batch)
- int up, type, is_batch;
- X{
- X int got_it, n;
- X WINDOW *gn_win, *newwin();
- X char *ans, *file, *list, buf[40], *expand(), *get_str(), *strtok();
- X void st_line();
- X struct stat stbuf;
- X
- X touchwin(stdscr);
- X refresh();
- X st_line("");
- X
- X n = type -NUM_INTERNAL -1;
- X
- X gn_win = newwin(7, 70, 5, 5);
- X mvwaddstr(gn_win, 3, 4, "Enter filename: ");
- X box(gn_win, VERT, HORZ);
- X if (up) {
- X if (type <= NUM_INTERNAL)
- X sprintf(buf, " Send %s ", protocol[type -1]);
- X else
- X sprintf(buf, " Send %s ", extrnl->name[up][n]);
- X }
- X else {
- X if (type <= NUM_INTERNAL)
- X sprintf(buf, " Receive %s ", protocol[type -1]);
- X else
- X sprintf(buf, " Receive %s ", extrnl->name[up][n]);
- X }
- X mvwattrstr(gn_win, 0, 3, A_BOLD, buf);
- X
- X /* CONSTCOND */
- X while (1) {
- X wmove(gn_win, 3, 20);
- X wrefresh(gn_win);
- X /* get the answers */
- X if (is_batch)
- X ans = get_str(gn_win, 60, "", "\n");
- X else
- X ans = get_str(gn_win, 60, "", " \t\n");
- X
- X if (ans == NULL || *ans == '\0') {
- X list = NULL;
- X break;
- X }
- X list = expand(ans);
- X /* batches are checked on-the-fly */
- X if (is_batch)
- X break;
- X /*
- X * Here we have the opportunity to determine the read and
- X * write permissions before things get started. Much nicer
- X * than finding out later when there's no way to fix it.
- X * Only checks the first file.
- X */
- X file = strtok(list, " \t");
- X /* sanity checking */
- X if (!stat(file, &stbuf)) {
- X if ((stbuf.st_mode & S_IFREG) != S_IFREG) {
- X beep();
- X clear_line(gn_win, 4, 15, TRUE);
- X mvwattrstr(gn_win, 4, 15, A_BOLD, "Not a regular file");
- X wrefresh(gn_win);
- X wait_key(gn_win, 3);
- X clear_line(gn_win, 4, 15, TRUE);
- X clear_line(gn_win, 3, 20, TRUE);
- X continue;
- X }
- X }
- X /* check read permission */
- X if (up) {
- X if (access(file, 0)) {
- X beep();
- X mvwattrstr(gn_win, 4, 15, A_BOLD, "Can't find file");
- X wrefresh(gn_win);
- X wait_key(gn_win, 3);
- X clear_line(gn_win, 4, 15, TRUE);
- X clear_line(gn_win, 3, 20, TRUE);
- X continue;
- X }
- X if (access(file, 4)) {
- X beep();
- X mvwattrstr(gn_win, 4, 15, A_BOLD, "No read permission");
- X wrefresh(gn_win);
- X wait_key(gn_win, 3);
- X clear_line(gn_win, 4, 15, TRUE);
- X clear_line(gn_win, 3, 20, TRUE);
- X continue;
- X }
- X break;
- X }
- X /* check write permission */
- X got_it = 0;
- X switch(can_write(file)) {
- X case DENIED:
- X beep();
- X clear_line(gn_win, 4, 15, TRUE);
- X mvwattrstr(gn_win, 4, 15, A_BOLD, "No write permission");
- X wrefresh(gn_win);
- X wait_key(gn_win, 3);
- X clear_line(gn_win, 4, 15, TRUE);
- X clear_line(gn_win, 3, 20, TRUE);
- X break;
- X case OK_BUT_EXISTS:
- X if (!yes_prompt(gn_win, 4, 15, A_BOLD, "File exists, overwrite")) {
- X clear_line(gn_win, 4, 15, TRUE);
- X clear_line(gn_win, 3, 20, TRUE);
- X break;
- X }
- X /* FALLTHRU */
- X case WRITE_OK:
- X got_it++;
- X break;
- X }
- X if (got_it)
- X break;
- X }
- X werase(gn_win);
- X wrefresh(gn_win);
- X delwin(gn_win);
- X
- X return(list);
- X}
- X
- X/*
- X * Prompt for the Unix command line to be used as an external file
- X * transfer program. Since expand() is used, it returns a pointer to
- X * a static area.
- X */
- X
- static char *
- get_extrnl(up)
- int up;
- X{
- X WINDOW *ge_win, *newwin();
- X char *ans, *cmd, *get_str(), *expand();
- X void st_line();
- X
- X touchwin(stdscr);
- X refresh();
- X st_line("");
- X /* prompt for command line */
- X ge_win = newwin(7, 70, 5, 5);
- X mvwaddstr(ge_win, 3, 4, "Enter Unix command: ");
- X box(ge_win, VERT, HORZ);
- X
- X if (up)
- X mvwattrstr(ge_win, 0, 3, A_BOLD, " Send (external) ");
- X else
- X mvwattrstr(ge_win, 0, 3, A_BOLD, " Receive (external) ");
- X
- X wmove(ge_win, 3, 24);
- X wrefresh(ge_win);
- X /* get the line */
- X ans = get_str(ge_win, 60, "", "\n");
- X if (ans == NULL || *ans == '\0')
- X cmd = NULL;
- X else
- X cmd = expand(ans);
- X
- X werase(ge_win);
- X wrefresh(ge_win);
- X delwin(ge_win);
- X return(cmd);
- X}
- END_OF_FILE
- if test 7412 -ne `wc -c <'x_menu.c'`; then
- echo shar: \"'x_menu.c'\" unpacked with wrong size!
- fi
- # end of 'x_menu.c'
- fi
- if test -f 'xmodem.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xmodem.c'\"
- else
- echo shar: Extracting \"'xmodem.c'\" \(8800 characters\)
- sed "s/^X//" >'xmodem.c' <<'END_OF_FILE'
- X/*
- X * Miscellaneous routines to support the xmodem file transfer protocols.
- X */
- X
- X#define TMP_FILE "trunXXXXXX"
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "config.h"
- X#include "misc.h"
- X#include "param.h"
- X#include "xmodem.h"
- X
- X#ifdef BSD
- X#include <setjmp.h>
- jmp_buf gl_buf, rl_buf;
- X#endif /* BSD */
- X
- static int uid_link(), uid_unlink();
- X
- X/*
- X * Calculate the CRC for the given buffer
- X */
- X
- unsigned short
- calc_crc(buf, len)
- unsigned char *buf;
- int len;
- X{
- X register int i;
- X unsigned short crc;
- X static unsigned short crctab[256] = {
- X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- X 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- X 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- X 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- X 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- X 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- X 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- X 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- X 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- X 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- X 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- X 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- X 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- X 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- X 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- X 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- X 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- X 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- X 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- X 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- X 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- X 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- X 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- X 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- X 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- X 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- X 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- X 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- X 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- X 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- X 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- X 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
- X
- X crc = 0;
- X for (i=0; i<len; i++)
- X crc = (crc<<8) ^ crctab[(crc>>8) ^ *buf++];
- X
- X return(crc);
- X}
- X
- X/*
- X * Calculate the checksum for the given buffer.
- X */
- X
- unsigned char
- calc_sum(buf, len)
- unsigned char *buf;
- int len;
- X{
- X unsigned char sum;
- X
- X sum = 0;
- X while (--len >= 0)
- X sum += *buf++;
- X
- X return(sum);
- X}
- X
- X/*
- X * Get a single character from the line with a specified time-out period
- X * in seconds. If the function times-out, it returns a -1.
- X */
- X
- static int gl_flag;
- static int gl_force();
- X
- int
- getc_line(sec)
- unsigned int sec;
- X{
- X extern int fd;
- X char c;
- X unsigned int alarm();
- X
- X signal(SIGALRM, (SIG_TYPE(*) ()) gl_force);
- X gl_flag = 0;
- X
- X alarm(sec);
- X
- X#ifdef BSD
- X if (setjmp(gl_buf))
- X return(-1);
- X#endif /* BSD */
- X
- X if (read(fd, &c, 1) <= 0) {
- X alarm(0);
- X return(-1);
- X }
- X if (gl_flag)
- X return(-1);
- X alarm(0);
- X return(c & 0xff);
- X}
- X
- X/* ARGSUSED */
- static int
- gl_force(dummy)
- int dummy;
- X{
- X#ifdef BSD
- X longjmp(gl_buf, 1);
- X#else /* BSD */
- X signal(SIGALRM, (SIG_TYPE(*) ()) gl_force);
- X gl_flag = 1;
- X return(0);
- X#endif /* BSD */
- X}
- X
- X/*
- X * Same as above, but reads a bunch of characters. The return code is
- X * now just a success/fail indicator.
- X */
- X
- static int rl_flag;
- static int rl_force();
- X
- int
- fread_line(buf, len, sec)
- unsigned char *buf;
- unsigned int len, sec;
- X{
- X extern int fd;
- X int n;
- X unsigned int try, alarm();
- X
- X signal(SIGALRM, (SIG_TYPE(*) ()) rl_force);
- X rl_flag = 0;
- X
- X alarm(sec);
- X while (len) {
- X /* read at most CLIST_SIZ chars */
- X try = (len > CLIST_SIZ) ? CLIST_SIZ : len;
- X#ifdef BSD
- X if (setjmp(rl_buf))
- X return(-1);
- X#endif /* BSD */
- X if ((n = read(fd, (char *) buf, try)) <= 0) {
- X alarm(0);
- X return(-1);
- X }
- X if (rl_flag)
- X return(-1);
- X len -= n;
- X buf = buf + n;
- X }
- X alarm(0);
- X return(0);
- X}
- X
- X/* ARGSUSED */
- static int
- rl_force(dummy)
- int dummy;
- X{
- X#ifdef BSD
- X longjmp(rl_buf, 1);
- X#else /* BSD */
- X signal(SIGALRM, (SIG_TYPE(*) ()) rl_force);
- X rl_flag = 1;
- X return(0);
- X#endif /* BSD */
- X}
- X
- X/*
- X * Put a character on the TTY line. This serves no useful purpose other
- X * than making the code look pretty.
- X */
- X
- int
- putc_line(c)
- unsigned char c;
- X{
- X extern int fd;
- X
- X return(write(fd, (char *) &c, 1));
- X}
- X
- X/*
- X * Cancel the file transfer. Send several ^X's to the remote, followed
- X * by an equal number of backspaces (in case they have already aborted and
- X * we're really at the command line).
- X */
- X
- void
- cancel_xfer(up)
- int up;
- X{
- X extern char file_name[15];
- X
- X if (!up && !strcmp(param->abort, "DELETE"))
- X unlink(file_name);
- X
- X putc_line(CAN);
- X putc_line(CAN);
- X putc_line(CAN);
- X putc_line(BS);
- X putc_line(BS);
- X putc_line(BS);
- X return;
- X}
- X
- X/*
- X * Shorten a file to a predetermined length. Used to remove the ^Z
- X * padding from the end of files. (Heaven help us, if one day a binary
- X * file actually has ^Z's as part of the end of the file).
- X */
- X
- int
- fix_length(file, len)
- char *file;
- long len;
- X{
- X FILE *fp, *tempfp, *uid_fopen();
- X register int num;
- X char *mktemp(), tempfile[128], buf[BUFSIZ], *strcpy();
- X char *s, *strrchr(), *strcat();
- X struct stat stbuf;
- X
- X if (stat(file, &stbuf) < 0)
- X return(1);
- X /* see if we have any work to do */
- X if (len >= stbuf.st_size)
- X return(0);
- X
- X#ifdef HAVE_TRUNCATE
- X return(uid_truncate(file, len));
- X#else /* HAVE_TRUNCATE */
- X
- X if (!(fp = uid_fopen(file, "r")))
- X return(1);
- X
- X /*
- X * The temporary file should be in the same directory as the
- X * file being received because otherwise we'd have no way of
- X * guaranteeing they would be in the same file system. (Hard
- X * links across different file systems aren't allowed).
- X */
- X strcpy(tempfile, file);
- X if (s = strrchr(tempfile, '/'))
- X *++s = '\0';
- X else
- X strcpy(tempfile, "./");
- X
- X strcat(tempfile, TMP_FILE);
- X mktemp(tempfile);
- X
- X if (!(tempfp = uid_fopen(tempfile, "w"))) {
- X fclose(fp);
- X return(1);
- X }
- X
- X while (len != 0L) {
- X num = (len > BUFSIZ) ? BUFSIZ : (int) len;
- X fread(buf, sizeof(char), num, fp);
- X if (fwrite(buf, sizeof(char), num, tempfp) != num) {
- X fclose(fp);
- X fclose(tempfp);
- X return(1);
- X }
- X len -= (unsigned int) num;
- X }
- X
- X fclose(fp);
- X fclose(tempfp);
- X
- X if (uid_unlink(file) < 0)
- X return(1);
- X
- X if (uid_link(tempfile, file) < 0)
- X return(1);
- X
- X if (uid_unlink(tempfile) < 0)
- X return(1);
- X
- X return(0);
- X#endif /* HAVE_TRUNCATE */
- X}
- X
- static int
- uid_link(path1, path2)
- char *path1, *path2;
- X{
- X int ret;
- X
- X#ifdef SETUID_BROKE
- X int status;
- X void _exit();
- X
- X switch(fork()) {
- X case 0:
- X setuid(getuid());
- X setgid(getgid());
- X _exit(link(path1, path2));
- X case -1:
- X fprintf(stderr, "uid_link: Can't fork\n");
- X return(-1);
- X default:
- X if (wait(&status) == -1) {
- X fprintf(stderr, "uid_link: wait failed\n");
- X return(-1);
- X }
- X ret = status >> 8;
- X }
- X#else /* SETUID_BROKE */
- X int euid, egid;
- X
- X euid = geteuid();
- X egid = getegid();
- X
- X setuid(getuid());
- X setgid(getgid());
- X
- X ret = link(path1, path2);
- X
- X setuid(euid);
- X setgid(egid);
- X#endif /* SETUID_BROKE */
- X return(ret);
- X}
- X
- static int
- uid_unlink(path)
- char *path;
- X{
- X int ret;
- X
- X#ifdef SETUID_BROKE
- X int status;
- X void _exit();
- X
- X switch(fork()) {
- X case 0:
- X setuid(getuid());
- X setgid(getgid());
- X _exit(unlink(path));
- X case -1:
- X fprintf(stderr, "uid_unlink: Can't fork\n");
- X return(-1);
- X default:
- X if (wait(&status) == -1) {
- X fprintf(stderr, "uid_unlink: wait failed\n");
- X return(-1);
- X }
- X ret = status >> 8;
- X }
- X#else /* SETUID_BROKE */
- X int euid, egid;
- X
- X euid = geteuid();
- X egid = getegid();
- X
- X setuid(getuid());
- X setgid(getgid());
- X
- X ret = unlink(path);
- X
- X setuid(euid);
- X setgid(egid);
- X#endif /* SETUID_BROKE */
- X return(ret);
- X}
- X
- X#ifdef HAVE_TRUNCATE
- static int
- uid_truncate(path, len)
- char *path;
- long len;
- X{
- X int ret;
- X
- X#ifdef SETUID_BROKE
- X int status;
- X void _exit();
- X
- X switch(fork()) {
- X case 0:
- X setuid(getuid());
- X setgid(getgid());
- X _exit(truncate(path, len));
- X case -1:
- X fprintf(stderr, "uid_truncate: Can't fork\n");
- X return(-1);
- X default:
- X if (wait(&status) == -1) {
- X fprintf(stderr, "uid_truncate: wait failed\n");
- X return(-1);
- X }
- X ret = status >> 8;
- X }
- X#else /* SETUID_BROKE */
- X int euid, egid;
- X
- X euid = geteuid();
- X egid = getegid();
- X
- X setuid(getuid());
- X setgid(getgid());
- X
- X ret = truncate(path, len);
- X
- X setuid(euid);
- X setgid(egid);
- X#endif /* SETUID_BROKE */
- X return(ret);
- X}
- X#endif /* HAVE_TRUNCATE */
- END_OF_FILE
- if test 8800 -ne `wc -c <'xmodem.c'`; then
- echo shar: \"'xmodem.c'\" unpacked with wrong size!
- fi
- # end of 'xmodem.c'
- fi
- echo shar: End of archive 3 \(of 6\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-