home *** CD-ROM | disk | FTP | other *** search
- /*
- * Routines to get or release a tty port.
- */
-
- #define LOCKDIR "/usr/spool/uucp"
- #undef ASCII_PID
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <termio.h>
- #ifdef UNIXPC
- #include <sys/phone.h>
- #endif /* UNIXPC */
- #include "dial_dir.h"
- #include "modem.h"
- #include "status.h"
-
- int getty_status;
- /*
- * Finds a free (or requested) serial port. Creates a lock file to hold
- * it for our use. Loads the modem database. A return code of 1 means
- * all ports (or the requested port) are busy.
- */
-
- int
- get_port()
- {
- int i, j, k, progpid, fd, list[NUM_TTY];
- char file[80], buf[80], message[80], *strdup();
- void error_win(), line_set(), release_port(), send_str();
- void free_ptr();
-
- /*
- * If we already have a port, see if it is good enough for the
- * current request.
- */
- if (status->fd != -1) {
- if (!strcmp(dir->index[dir->d_cur], modem->tty[modem->t_cur]) ||
- modem->mbaud[modem->t_cur] >= dir->baud[dir->d_cur]) {
- /*
- * Re-initialize the modem because the baud
- * rate (or other parameters) may have changed.
- */
- line_set();
- send_str(modem->init[modem->m_cur]);
- return(0);
- }
- }
- release_port(1);
-
- /*
- * See if you want a specific tty port. If the index field in the
- * dialing directory is a valid device name, then use that tty.
- */
- sprintf(buf, "/dev/%s", dir->index[dir->d_cur]);
- list[0] = -1;
- /* if index is a valid device */
- if (!access(buf, 0)) {
- for (i=0; i<modem->t_entries; i++) {
- /* and it exists in modem database */
- if (!strcmp(dir->index[dir->d_cur], modem->tty[i])) {
- list[0] = i;
- list[1] = -1;
- break;
- }
- }
- }
-
- /*
- * Create a list of acceptable ttys. It searches the tty database
- * for the requested baud rate.
- */
- k = 0;
- if (list[0] == -1) {
- for (i=0; i<modem->t_entries; i++) {
- /* skip ports with no modems */
- if (!strcmp(modem->tname[i], "DIRECT"))
- continue;
-
- /* can handle requested baud rate ? */
- if (modem->mbaud[i] >= dir->baud[dir->d_cur])
- list[k++] = i;
- }
- /* the end of list marker */
- list[k] = -1;
- }
- /* empty list ? */
- if (list[0] == -1) {
- sprintf(message, "No modem at a %d baud rating exists in", dir->baud[dir->d_cur]);
- sprintf(file, "modem file '%s'", status->m_path);
- error_win(0, message, file);
- return(1);
- }
- /* check the list for a free port */
- i = 0;
- while (list[i] != -1) {
- /* create a lock file name */
- sprintf(file, "%s/LCK..%s", LOCKDIR, modem->tty[list[i]]);
-
- /*
- * See if the lock file exists... We DO NOT look to see
- * if the pid in the file is still active. Maybe I'll
- * change this later...
- */
- if (access(file, 0)) {
- getty_status = set_getty(modem->tty[list[i]], 0);
-
- if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
- set_getty(modem->tty[list[i]], 1);
- sprintf(buf, "'%s'", file);
- error_win(1, "Can't create the lockfile", buf);
- }
- #ifdef ASCII_PID
- sprintf(buf, "%10d\n", getpid());
- write(fd, buf, 11);
- #else /* ASCII_PID */
- progpid = getpid();
- write(fd, (char *)&progpid, sizeof(int));
- #endif /* ASCII_PID */
- close(fd);
- /* store the new values */
- free_ptr(status->lock_path);
- status->lock_path = strdup(file);
- modem->t_cur = list[i];
-
- /* open the device (hold DTR high) */
- sprintf(buf, "/dev/%s", modem->tty[list[i]]);
- if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
- set_getty(modem->tty[list[i]], 1);
- sprintf(file, "Can't open port '%s' for read and write", buf);
- error_win(1, file, NULL);
- }
-
- /* turn off the "no delay" mode */
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
- status->fd = fd;
- /* change line settings */
- line_set();
- /* load the modem data base */
- for (j=0; j<modem->m_entries; j++) {
- if (!strcmp(modem->tname[list[i]], modem->mname[j])) {
- modem->m_cur = j;
- break;
- }
- }
- /* initialize the modem */
- send_str(modem->init[j]);
- return(0);
- }
- i++;
- }
- error_win(0, "All ports are busy now, try again later", NULL);
- return(1);
- }
-
- /*
- * Release the port. Closes the file descriptor and removes the
- * lock file
- */
-
- void
- release_port(verbose)
- int verbose;
- {
- char buf[80];
- extern char *null_ptr;
- void free_ptr(), hang_up();
-
- /*
- * The modem structure can't be guaranteed to exist yet. For example,
- * an error in reading one of the other support files would cause
- * this routine to be used before the MODEM structure gets allocated.
- */
- if (modem == NULL)
- return;
- /* close the port */
- if (status->fd != -1) {
- ioctl(status->fd, TCFLSH, 2);
- /*
- * Since HUPCL is set, the close() should drop the DTR and
- * hang up the modem (provided you've got the modem to
- * respond to DTR). Since this is not guaranteed, we send
- * the hangup string first.
- */
- hang_up(verbose);
- close(status->fd);
- }
- /* remove the lock */
- if (*status->lock_path != NULL) {
- if (unlink(status->lock_path)) {
- sprintf(buf, "'%s'", status->lock_path);
- error_win(0, "Can't remove the lock file", buf);
- }
- free_ptr(status->lock_path);
- status->lock_path = null_ptr;
- }
- /* turn the getty back on? */
- if (getty_status)
- set_getty(modem->tty[modem->t_cur], 1);
- /* cleanup the structure */
- status->fd = -1;
- modem->m_cur = -1;
- modem->t_cur = -1;
- return;
- }
-
- /*
- * Turn the /etc/getty on or off for the specified port. A return code
- * of 1 means that the getty was on. Systems with uugetty or dedicated
- * dialout ports won't need this routine.
- */
-
- int
- set_getty(tty, on)
- char *tty;
- int on;
- {
- #ifdef UNIXPC
- int i, ret_code;
- char buf[40];
- unsigned int sleep();
- /* the last three characters */
- i = strlen(tty) -3;
-
- ret_code = 0;
- if (on) {
- sprintf(buf, "setgetty %s 1", tty+i);
- system(buf);
- }
- else {
- sprintf(buf, "setgetty %s 0", tty+i);
- if (system(buf) == 512)
- ret_code = 1;
- sleep(1);
- }
- return(ret_code);
- #else /* UNIXPC */
- /*
- * If you don't have one of these cute little routines, you
- * might wanna write one. It should check for an existing lock
- * file, edit the /etc/inittab file, and issue an init -q.
- * Obviously the program would be suid to root.
- */
- return(0);
- #endif /* UNIXPC */
- }
-