jbayer@ispi.UUCP (Jonathan Bayer) (11/20/88)
Due to demand I am re-posting these patches to Pcomm 1.1. THIS IS NOT AN OFFICIAL PATCH These are the local mods made to Pcomm with all five official patches applied first. It includes all of my previous patches as described below: **************************** The enclosed patches fix two problems with pcomm 1.1, with the first patch applied. The first bug is that after pcomm sets the CLOCAL mode it doesn't re-open the tty port. This is important if the program is sharing a dial-out port with uucp and you have to specify a port which has modem control. In this case the program would just chug merrily along sending characters to the modem, while the OS would not pass them along to the modem. The addition to port.c allows Pcomm to be able to access the modem if the port was originally opened with modem control. line_set() removes the modem control, but the open file still has it. By re-opening the port here, and then closing the old file descriptor, Pcomm can access the port correctly. The second bug is not with Pcomm directly, but with some stupid modems which are on the market. Some modems cannot receive the AT commands at the full baud rate they are set at. The sent_str() routine is the problem here. The modifications force Pcomm to send characters to the modem at a rate of 10 chars per second. Each character is sent at the correct baud rate, there is just a delay of 1/10 sec inserted between each character. The modem commands in port.c which use the send_str() function now call slow_send_str(). See the changes in both port.c and dial.c. The function do_pause() is dial.c does the delay. do_pause() depends on the environment variable HZ to store the number of clock ticks per second. A few features I would like to see added to pcomm are: 1. VERY IMPORTANT: Please add a patchlevel.h file indicating the patchlevel of the current system. 2. a local dialing directory, probably with a name like: .pcomm.phone in the user's home directory 3. zmodem support built in, possibly using external programs 4. Compuserve B protocol 5. Adding the lock file format and location to the configuration file. 6. A possible check of long distance numbers is to limit the number of digits in a phone number. Also, specify which digit would be the SECOND digit of the area code; if it is a zero or a 1 then it is an area code and therefore a long-distance number. I have not done any work on this since I don't have that problem. ********************* Adds option to control what happens when a hang up command is given ********************* A word of explanation; I use rz/sz almost exclusively, and having to type in the external command every time is a small pain. These patches add a line to the up/download menu called zmodem. The patches are set up so that a compile time option called ZMODM must be defined for them to take effect. The only file you have to worry about in these patches is "config.h". The options are set up for my system, and they probably are a little different from the options in the distribution files. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *** Makefile Wed Oct 19 12:12:44 1988 --- ../src/Makefile Wed Oct 19 12:24:16 1988 *************** *** 6,17 **** #GETCWD = getcwd.o #GETOPT = getopt.o ! CFLAGS = -O #CURSES = -ltermlib -lcurses CURSES = -lcurses ! LDFLAGS = -s SHAR = shar -a BIN = /usr/local/bin PCOMM = $(GETCWD) $(GETOPT) admin.o chg_dir.o curses.o d_delete.o \ d_lib.o d_manual.o d_menu.o d_print.o d_prompt.o d_revise.o \ --- 6,18 ---- #GETCWD = getcwd.o #GETOPT = getopt.o ! CFLAGS = -Ox -DM_TERMINFO #CURSES = -ltermlib -lcurses CURSES = -lcurses ! LDFLAGS = -s -ltinfo -lx SHAR = shar -a BIN = /usr/local/bin + CC = mcc PCOMM = $(GETCWD) $(GETOPT) admin.o chg_dir.o curses.o d_delete.o \ d_lib.o d_manual.o d_menu.o d_print.o d_prompt.o d_revise.o \ *** config.h Wed Oct 19 12:12:46 1988 --- ../src/config.h Wed Oct 19 12:21:04 1988 *************** *** 13,25 **** #define SHAREDMEM /* Should a missing video attribute be promoted to standout? */ ! #define NOPROMOTE /* Use extra precautions if Pcomm is set-user-id or set-group-id */ ! #undef SETUGID /* Should Pcomm make a log of all phone calls? */ #undef LOG_CALLS /* The name of the log file (if used). */ #define LOGFILE "/usr/adm/phone.calls" --- 13,27 ---- #define SHAREDMEM /* Should a missing video attribute be promoted to standout? */ ! #undef NOPROMOTE /* Use extra precautions if Pcomm is set-user-id or set-group-id */ ! /* #undef SETUGID */ ! #define SETUGID /* Should Pcomm make a log of all phone calls? */ #undef LOG_CALLS + /* #define LOG_CALLS */ /* The name of the log file (if used). */ #define LOGFILE "/usr/adm/phone.calls" *************** *** 46,55 **** #undef ASCII_PID /* Should Pcomm optimize redialing by keeping the TTY port open */ ! #define KEEP_PORT /* Does the status line scroll up on "magic cookie" terminals? */ #undef XMC_BROKE /* Does the alarm() system call work correctly with the wgetch() function? */ #undef WGETCH_BROKE --- 48,63 ---- #undef ASCII_PID /* Should Pcomm optimize redialing by keeping the TTY port open */ ! /* #define KEEP_PORT */ /* Does the status line scroll up on "magic cookie" terminals? */ #undef XMC_BROKE /* Does the alarm() system call work correctly with the wgetch() function? */ #undef WGETCH_BROKE + + /* are the rz/sz zmodem routines available ? */ + #define ZMODM + + /* Disconnect from port when hang up command given? */ + #undef D_ON_HUP *** dial.c Wed Oct 19 12:12:50 1988 --- ../src/dial.c Wed Oct 19 12:14:36 1988 *************** *** 123,133 **** --- 123,182 ---- return; } + + /* The following routines was added by J. Bayer to slow down the transmission + ** of commands to the modem. Some modems choke if the commands are sent + ** at full speed. This code is designed to send the commands at a speed + ** of app. 10 characters per second. This is different from the baud rate + */ + int slow_send = 0; + + /* do_pause depends on the environment variable HZ to store + ** the number of clock ticks per second. If it is + ** not there then it will default to 50, which is + ** a reasonable number for Xenix + */ + + void do_pause() + { + #include <sys/types.h> + #include <sys/times.h> + struct tms t; + long t1; + int hz = 0; + char *home; + unsigned int sleep(); + + if ((home = getenv("HZ")) != NULL) + hz = atoi(home); + if (!hz) hz = 50; + + t1 = times(&t); + while ( (times(&t) - t1) < hz/10); + } /* do_pause */ + + + void + slow_send_str(s) + char *s; + { + void send_str(); + + slow_send++; + send_str(s); + slow_send--; + } /* slow_send_str */ + + + + + /* * Send a string to the modem. Performs all the character synonym * translations. No sanity checking on the "m_cur" value. */ + void send_str(s) char *s; *************** *** 151,156 **** --- 200,206 ---- if (skip) { skip = 0; write(fd, s, 1); + if (slow_send) do_pause(); ioctl(fd, TCSBRK, 1); #ifdef DEBUG fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s); *************** *** 197,202 **** --- 247,254 ---- } write(fd, s, 1); + if (slow_send) do_pause(); + #ifdef DEBUG fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s); #endif /* DEBUG */ *************** *** 209,214 **** --- 261,268 ---- } return; } + + /* * Read the result codes coming back from the modem. Test for the 6 *** port.c Wed Oct 19 12:13:00 1988 --- ../src/port.c Wed Oct 19 12:19:41 1988 *************** *** 31,42 **** int j, k, lfd, list[NUM_TTY], cmask, tbaud, is_dev; char file[80], buf[80], message[80], *strdup(); unsigned int sleep(); ! void error_win(), line_set(), release_port(), send_str(); void free_ptr(); #ifndef ASCII_PID int progpid; #endif /* ASCII_PID */ is_dev = chk_index(dir->index[dir->d_cur]); /* * If we already have a port, see if it is good enough for the --- 31,44 ---- int j, k, lfd, list[NUM_TTY], cmask, tbaud, is_dev; char file[80], buf[80], message[80], *strdup(); unsigned int sleep(); ! void error_win(), line_set(), release_port(), send_str(), slow_send_str(); void free_ptr(); #ifndef ASCII_PID int progpid; #endif /* ASCII_PID */ + int fd1; /* added by J. Bayer */ + is_dev = chk_index(dir->index[dir->d_cur]); /* * If we already have a port, see if it is good enough for the *************** *** 139,145 **** /* open the device (ignore DCD) */ sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]); ! if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) { if (getty_status) set_getty(modem->tty[modem->t_cur], 1); sprintf(file, "Can't open port '%s' for read and write", buf); --- 141,147 ---- /* open the device (ignore DCD) */ sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]); ! if ((fd1 = fd = open(buf, O_RDWR|O_NDELAY)) < 0) { if (getty_status) set_getty(modem->tty[modem->t_cur], 1); sprintf(file, "Can't open port '%s' for read and write", buf); *************** *** 147,152 **** --- 149,173 ---- } /* change line settings */ line_set(); + + /* This section added by J. Bayer. It allows Pcomm to be + ** able to access the modem if the port was originally opened + ** with modem control. line_set() removes the modem control, + ** but the open file still has it. By re-opening the port + ** here, and then closing the old file descriptor, Pcomm + ** can access the port correctly + */ + + if ((fd = open(buf, O_RDWR)) < 0) { + if (getty_status) + set_getty(modem->tty[modem->t_cur], 1); + sprintf(file, "Can't open port '%s' for read and write", buf); + error_win(1, file, ""); + } + close(fd1); + + /* End of addition */ + /* turn off the "no delay" mode */ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY); /* load the modem data base */ *************** *** 167,177 **** tbaud = dir->baud[dir->d_cur]; dir->baud[dir->d_cur] = modem->init_sp[modem->t_cur]; line_set(); ! send_str(modem->init[modem->m_cur]); dir->baud[dir->d_cur] = tbaud; } else ! send_str(modem->init[modem->m_cur]); sleep(1); return(0); } --- 188,208 ---- tbaud = dir->baud[dir->d_cur]; dir->baud[dir->d_cur] = modem->init_sp[modem->t_cur]; line_set(); ! ! /* changed by J. Bayer to be a slow send. See my comments ! ** in dial.c for the reason. ! */ ! ! slow_send_str(modem->init[modem->m_cur]); dir->baud[dir->d_cur] = tbaud; } else ! ! /* changed by J. Bayer to be a slow send. See my comments ! ** in dial.c for the reason. ! */ ! ! slow_send_str(modem->init[modem->m_cur]); sleep(1); return(0); } *** terminal.c Wed Oct 19 12:13:04 1988 --- ../src/terminal.c Wed Oct 19 12:20:33 1988 *************** *** 31,37 **** void help_screen(), line_set(), n_shell(), load_vs(), send_str(); void release_port(), do_input(), list_dir(), pexit(), zap_vs(); void st_line(), chg_dir(), screen_dump(), input_off(), suspend(); ! void info(), term_mode(); /* if starting out in command mode */ if (!input_status) --- 31,37 ---- void help_screen(), line_set(), n_shell(), load_vs(), send_str(); void release_port(), do_input(), list_dir(), pexit(), zap_vs(); void st_line(), chg_dir(), screen_dump(), input_off(), suspend(); ! void info(), term_mode(), hang_up(); /* if starting out in command mode */ if (!input_status) *************** *** 132,139 **** --- 132,143 ---- break; case 'h': case 'H': /* hang up phone */ + #ifdef D_ON_HUP release_port(1); input_off(); + #else + hang_up(1); + #endif break; case 'l': case 'L': /* toggle printer */ *** x_menu.c Wed Oct 19 12:13:08 1988 --- ../src/x_menu.c Wed Oct 19 12:21:04 1988 *************** *** 31,37 **** --- 31,42 ---- mvwaddstr(xm_win, 5, 3, "4) ymodem"); mvwaddstr(xm_win, 6, 3, "5) ymodem-g"); mvwaddstr(xm_win, 7, 3, "6) ASCII"); + #ifdef ZMODM + mvwaddstr(xm_win, 8, 3, "7) zmodem"); + mvwaddstr(xm_win, 9, 3, "8) (external)"); + #else mvwaddstr(xm_win, 8, 3, "7) (external)"); + #endif mvwaddstr(xm_win, 11, 3, "<ESC> to Abort"); mvwaddstr(xm_win, 13, 3, "Protocol:"); box(xm_win, VERT, HORZ); *************** *** 77,82 **** --- 82,90 ---- case MODEM7: case YMODEM: case YMODEM_G: + #ifdef ZMODM + case ZMODEM: + #endif is_batch++; break; default: *************** *** 106,112 **** } char *protocol[PROTOCOLS] = {"xmodem", "xmodem-1k", "modem7", "ymodem", ! "ymodem-g", "ASCII", "(external)"}; /* * Prompt for a list of files for the transfer programs. A NULL return --- 114,124 ---- } char *protocol[PROTOCOLS] = {"xmodem", "xmodem-1k", "modem7", "ymodem", ! "ymodem-g", "ASCII", ! #ifdef ZMODM ! "zmodem", ! #endif ! "(external)"}; /* * Prompt for a list of files for the transfer programs. A NULL return *** x_rcv.c Wed Oct 19 12:13:09 1988 --- ../src/x_rcv.c Wed Oct 19 12:21:06 1988 *************** *** 63,68 **** --- 63,77 ---- max_block = 1024; performance = 1.02; break; + #ifdef ZMODM + case ZMODEM: + { + void extrnl(); + + extrnl("rz"); + return 0; + } + #endif default: return(1); } *** x_send.c Wed Oct 19 12:13:10 1988 --- ../src/x_send.c Wed Oct 19 12:21:07 1988 *************** *** 65,70 **** --- 65,82 ---- max_block = 1024; performance = 1.02; break; + #ifdef ZMODM + case ZMODEM: + { + void extrnl(); + char str[255]; + + strcpy(str,"sz "); + strcat(str,list); + extrnl(str); + return(0); + } + #endif default: return(1); } *** x_win.c Wed Oct 19 12:13:10 1988 --- ../src/x_win.c Wed Oct 19 12:21:08 1988 *************** *** 29,34 **** --- 29,37 ---- refresh(); st_line(""); + #ifdef ZMODM + if (type != ZMODEM) { + #endif xf_win = newwin(15, 44, 2, 30); /* * This window should be in the non-blocking mode, so we can *************** *** 74,84 **** --- 77,93 ---- if (my_speed >= dir->baud[dir->d_cur]) fast++; + #ifdef ZMODM + } + #endif if (up) ret_code = send_xmodem(xf_win, list, type, fast); else ret_code = rcv_xmodem(xf_win, list, type, fast); + #ifdef ZMODM + if (type != ZMODEM) { + #endif nodelay(xf_win, 0); /* prompt for a key on errors */ if (ret_code) { *************** *** 91,96 **** --- 100,108 ---- werase(xf_win); wrefresh(xf_win); delwin(xf_win); + #ifdef ZMODM + } + #endif /* undo what xmodem_mode() did */ line_set(); return; *** xmodem.h Wed Oct 19 12:13:11 1988 --- ../src/xmodem.h Wed Oct 19 12:21:08 1988 *************** *** 12,25 **** --- 12,35 ---- #define CAN 24 #define CTRLZ 26 + #ifdef ZMODM + #define PROTOCOLS 8 + #else #define PROTOCOLS 7 + #endif #define XMODEM 0 #define XMODEM_1k 1 #define MODEM7 2 #define YMODEM 3 #define YMODEM_G 4 #define XASCII 5 + + #ifdef ZMODM + #define ZMODEM 6 + #define EXTRNL 7 + #else #define EXTRNL 6 + #endif #define ABORT (-1) #define ERROR (-2)
jbayer@ispi.UUCP (Jonathan Bayer) (11/20/88)
I have received a number of inquiries regarding my patches to pcomm to make it work on Xenix 386, v 2.3.1. These patches apply to Pcomm 1.1 with all five official patches applied. If you are running Xenix you should apply the other patches I posted first. THIS IS NOT AN OFFICIAL PATCH The following patches fixes pcomm to work properly with the version of HDB that comes with SCO Xenix 2.3.1. The patch will work for any HDB system since the one line that is specific to SCO Xenix is ifdef'ed in place. A word of explaination: SCO uses two device names to refer to the same modem port, one for modem control, and one for no modem control. This created problems in the past since when one port was locked the other was not. The port names all end with a letter, with the case of the letter indicating whether modem control is active or not. A capitol letter indicates modem control. SCO has specified in the new HDB that the last letter should be folded into lower case, thereby ensuring that when one port is locked both of them are. The below patch adds this to pcomm. - - - - - - - patch starts here - - - - - - - - - - *** ../oldsrc/config.h Sat Nov 19 13:13:52 1988 --- config.h Wed Nov 16 22:42:10 1988 *************** *** 45,51 **** #define LOCK_DIR "/usr/spool/uucp" /* Do the lock files use ASCII encoded PID's? */ ! #undef ASCII_PID /* Should Pcomm optimize redialing by keeping the TTY port open */ /* #define KEEP_PORT */ --- 45,52 ---- #define LOCK_DIR "/usr/spool/uucp" /* Do the lock files use ASCII encoded PID's? */ ! /* #undef ASCII_PID */ ! #define ASCII_PID /* Should Pcomm optimize redialing by keeping the TTY port open */ /* #define KEEP_PORT */ *** ../oldsrc/port.c Sat Nov 19 13:13:53 1988 --- port.c Fri Nov 18 23:59:07 1988 *************** *** 110,115 **** --- 110,120 ---- while (list[i] != -1) { /* create a lock file name */ sprintf(file, "%s/LCK..%s", LOCK_DIR, modem->tty[list[i]]); + #ifdef ASCII_PID + #ifdef M_XENIX + file[strlen(file) - 1] = tolower(file[strlen(file) - 1]); + #endif + #endif #ifdef DEBUG fprintf(stderr, "get_port: checking '/dev/%s'\n", modem->tty[list[i]]); #endif /* DEBUG */