home *** CD-ROM | disk | FTP | other *** search
- /*
- ibmpc/ulib.c
-
- DCP system-dependent library
-
- Services provided by ulib.c:
-
- - login
- - UNIX commands simulation
- - serial I/O
- - rnews
-
- Updated:
-
- 14May89 - Added hangup() procedure ahd
- 21Jan90 - Replaced code for rnews() from Wolfgang Tremmel
- <tremmel@garf.ira.uka.de> to correct failure to
- properly read compressed news. ahd
- 6 Sep 90 - Change logging of line data to printable ahd
- 8 Sep 90 - Split ulib.c into dcplib.c and ulib.c ahd
- */
-
- #include <fcntl.h>
- #include <io.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
-
- #include "lib.h"
- #include "ulib.h"
- #include "comm.h"
- #include "ssleep.h"
-
- boolean port_active = FALSE; /* TRUE = port handler handler active */
-
- static BPS current_baud;
- static char current_direct;
- static int old_status = 0x00;
-
- currentfile();
-
- /* IBM-PC I/O routines */
-
- /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
-
- /*************** BASIC I/O ***************************/
- /* Saltzers serial package (aka Info-IBMPC COM_PKG2):
- * Some notes: When packets are flying in both directions, there seems to
- * be some interrupt handling problems as far as receiving. Checksum errors
- * may therefore occur often even though we recover from them. This is
- * especially true with sliding windows. Errors are very few in the VMS
- * version. RH Lamb
- */
-
-
- #define STOPBIT 1
- #define LINELOG "LineData.Log" /* log serial line data here */
-
- static int log_handle;
- static int logmode = 0; /* Not yet logging */
- #define WRITING 1
- #define READING 2
- static FILE *log_stream;
- static boolean hangup_needed = TRUE;
-
- /*--------------------------------------------------------------------*/
- /* o p e n l i n e */
- /* */
- /* Open the serial port for I/O */
- /*--------------------------------------------------------------------*/
-
- int openline(char *name, BPS baud, const boolean direct)
- {
- int value;
-
- if (port_active) /* Was the port already active? ahd */
- closeline(); /* Yes --> Shutdown it before open ahd */
-
- printmsg(15, "openline: %s, %d", name, baud);
-
- logmode = 0;
-
- current_direct = direct ? 'D' : 'M' ;
-
- if (sscanf(name, "COM%d", &value) != 1)
- {
- printmsg(0,"Communications port must be format COMx, was %s",
- name);
- panic();
- }
-
- select_port(value);
- save_com();
- install_com();
- open_com(baud, current_direct, 'N', STOPBIT, 'D');
- current_baud = baud;
- dtr_on();
-
- /* log serial line data only if log file already exists */
- log_handle = open(LINELOG, O_WRONLY | O_TRUNC | O_BINARY);
- if (log_handle != -1) {
- printmsg(15, "openline: logging serial line data to %s", LINELOG);
- log_stream = fdopen(log_handle, "wb");
- }
-
- port_active = TRUE; /* record status for error handler */
-
- return 0;
-
- } /*openline*/
-
-
- /*--------------------------------------------------------------------*/
- /* s r e a d */
- /* */
- /* Read from the serial port */
- /* */
- /* Non-blocking read essential to "g" protocol. See */
- /* "dcpgpkt.c" for description. This all changes in a */
- /* multi-tasking system. Requests for I/O should get queued */
- /* and an event flag given. Then the requesting process (e.g. */
- /* gmachine()) waits for the event flag to fire processing */
- /* either a read or a write. Could be implemented on VAX/VMS */
- /* or DG but not MS-DOS. */
- /*--------------------------------------------------------------------*/
-
- unsigned int sread(char *buffer, unsigned int wanted, unsigned int timeout)
- {
- time_t start;
-
- hangup_needed = TRUE;
-
- start = time(nil(time_t));
-
- for ( ; ; )
- {
- unsigned int pending;
- pending = r_count_pending();
- printmsg(20, "sread: pending=%d, wanted=%d", pending, wanted);
- if ( debuglevel >= 4 )
- {
- int status = modem_status();
-
- if ( status != old_status )
- {
- old_status = status;
- printmsg(4,"sread: Modem status changed to %#02x", status);
- } /* if ( status != old_status ) */
-
- } /* if ( debuglevel >= 4 ) */
-
- if (pending >= wanted) { /* got enough in the buffer? */
- unsigned int i;
- for (i = 0; i < wanted; i++)
- *buffer++ = (char) receive_com();
- if (log_handle != -1) {
- #ifdef VERBOSE
- char s[18];
- #endif
- buffer -= wanted;
- if (logmode != READING)
- {
- fputs("\nRead: ", log_stream);
- logmode = READING;
- } /* if */
- #ifdef VERBOSE
- for (i = 0; i < wanted; i++) {
- itoa(0x100 | (unsigned) *buffer++, s, 16);
- /* Make it printable hex */
- fwrite(s, 1, 2, log_stream); /* Write hex to the log */
- } /* for */
- #else
- fwrite(buffer, 1, wanted, log_stream);
- /* Write data to the log */
- #endif
- } /* if */
-
- return pending;
- } else {
- time_t now = time(nil(time_t));
- time_t elapsed = now - start;
-
- if (elapsed >= (long) timeout)
- return pending;
-
- ddelay(0); /* Surrender our time slice */
-
- } /* else */
- } /* for ( ; ; ) */
-
- } /*sread*/
-
- /*--------------------------------------------------------------------*/
- /* s w r i t e */
- /* */
- /* Write to the serial port */
- /*--------------------------------------------------------------------*/
-
- int swrite(char *data, unsigned int len)
- {
- unsigned int i;
-
- hangup_needed = TRUE;
- for (i = 0; i < len; i++)
- {
- if ( debuglevel >= 4 )
- {
- int status = modem_status();
-
- if ( status != old_status )
- {
- old_status = status;
- printmsg(4,"swrite: Modem status changed to %#02x", status);
- } /* if ( status != old_status ) */
-
- } /* if ( debuglevel >= 4 ) */
- send_com(*data++);
- }
-
- if (log_handle != -1) {
- #ifdef VERBOSE
- char s[18];
- #endif
- if (logmode != WRITING)
- {
- fputs("\nWrite: ", log_stream);
- logmode = WRITING;
- } /* if */
- data -= len;
- #ifdef VERBOSE
- for (i = 0; i < len; i++) {
- itoa(0x100 | (unsigned) *data++, s, 16);
- /* Make it printable hex ahd */
- fwrite(s, 1, 2, log_stream);
- } /* for */
- #else
- fwrite(data, 1, len, log_stream); /* Write data to the log */
- #endif
- } /* if */
-
- return len;
-
- } /*swrite*/
-
-
- /*--------------------------------------------------------------------*/
- /* s s e n d b r k */
- /* */
- /* Send a break signal out the serial port */
- /*--------------------------------------------------------------------*/
-
- void ssendbrk(unsigned int duration)
- {
-
- printmsg(12, "ssendbrk: %d", duration);
-
- break_com();
-
- } /*ssendbrk*/
-
-
- /*--------------------------------------------------------------------*/
- /* c l o s e l i n e */
- /* */
- /* Close the serial port down */
- /*--------------------------------------------------------------------*/
-
- void closeline(void)
- {
- int far *stats;
-
- if (!port_active)
- panic();
-
- port_active = FALSE; /* flag port closed for error handler */
-
- dtr_off();
- close_com();
- restore_com();
-
- if (log_handle != -1) { /* close serial line log file */
- fclose(log_stream);
- close(log_handle);
- };
-
- stats = com_errors();
- printmsg(3, "Buffer overflows: %-4d",stats[COM_EOVFLOW]);
- printmsg(3, "Receive overruns: %-4d", stats[COM_EOVRUN]);
- printmsg(3, "Break characters: %-4d", stats[COM_EBREAK]);
- printmsg(3, "Framing errors: %-4d", stats[COM_EFRAME]);
- printmsg(3, "Parity errors: %-4d", stats[COM_EPARITY]);
- printmsg(3, "Transmit errors: %-4d", stats[COM_EXMIT]);
- printmsg(3, "DSR errors: %-4d", stats[COM_EDSR]);
- printmsg(3, "CTS errors: %-4d", stats[COM_ECTS]);
-
- } /*closeline*/
-
-
- /*--------------------------------------------------------------------*/
- /* H a n g u p */
- /* */
- /* Hangup the telephone by dropping DTR. Works with HAYES and */
- /* many compatibles. */
- /* 14 May 89 Drew Derbyshire */
- /*--------------------------------------------------------------------*/
-
- void hangup( void )
- {
- if (!hangup_needed)
- return;
- hangup_needed = FALSE;
- dtr_off(); /* Hang the phone up */
- printmsg(3,"hangup: Dropped DTR");
- ddelay(500); /* Really only need 250 milliseconds */
- dtr_on(); /* Bring the modem back on-line */
- ddelay(500); /* Now wait for the poor thing to recover */
-
- } /* hangup */
-
- /*--------------------------------------------------------------------*/
- /* S I O S p e e d */
- /* */
- /* Re-specify the speed of an opened serial port */
- /* */
- /* Dropped the DTR off/on calls because this makes a Hayes drop */
- /* the line if configured properly, and we don't want the modem */
- /* to drop the phone on the floor if we are performing */
- /* autobaud. */
- /* */
- /* (Configured properly = standard method of making a Hayes */
- /* hang up the telephone, especially when you can't get it into */
- /* command state because it is at the wrong speed or whatever.) */
- /*--------------------------------------------------------------------*/
-
- void SIOSpeed(BPS baud)
- {
-
- close_com();
- open_com(baud, current_direct , 'N', STOPBIT, 'D');
- current_baud = baud;
-
- } /*SIOSpeed*/
-
- /*--------------------------------------------------------------------*/
- /* f l o w c o n t r o l */
- /* */
- /* Enable/Disable in band (XON/XOFF) flow control */
- /*--------------------------------------------------------------------*/
-
- void flowcontrol( boolean flow )
- {
- close_com();
- open_com(current_baud, current_direct, 'N', STOPBIT, flow ? 'E' : 'D');
- } /*flowcontrol*/
-
- /*--------------------------------------------------------------------*/
- /* G e t S p e e d */
- /* */
- /* Report current speed of communications connection */
- /*--------------------------------------------------------------------*/
-
- BPS GetSpeed( void )
- {
- return current_baud;
- } /* GetSpeed */
-