home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / uucp-1.04 / unix / cohtty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-13  |  6.6 KB  |  245 lines

  1. /* Coherent tty locking support.  This file was contributed by Bob
  2.    Hemedinger <bob@dalek.mwc.com> of Mark Williams Corporation and
  3.    lightly edited by Ian Lance Taylor.  */
  4.  
  5. /* The bottom part of this file is lock.c.
  6.  * This is a hacked lock.c. A full lock.c can be found in the libmisc sources 
  7.  * under /usr/src/misc.tar.Z.
  8.  *
  9.  * These are for checking for the existence of locks:
  10.  * lockexist(resource)
  11.  * lockttyexist(ttyname)
  12.  */
  13.  
  14. #include "uucp.h"
  15.  
  16. #if HAVE_COHERENT_LOCKFILES
  17.  
  18. /* cohtty.c:    Given a serial device name, read /etc/ttys and determine if
  19.  *        the device is already enabled. If it is, disable the
  20.  *        device and return a string so that it can be re-enabled
  21.  *         at the completion of the uucico session as part of the
  22.  *        function that resets the serial device before uucico
  23.  *        terminates.
  24.  *
  25.  */
  26.  
  27. #include "uudefs.h"
  28. #include "sysdep.h"
  29.  
  30. #include <ctype.h>
  31. #include <access.h>
  32.  
  33. /* fscoherent_disable_tty() is a COHERENT specific function. It takes the name
  34.  * of a serial device and then scans /etc/ttys for a match. If it finds one,
  35.  * it checks the first field of the entry. If it is a '1', then it will disable
  36.  * the port and set a flag. The flag will be checked later when uucico wants to
  37.  * reset the serial device to see if the device needs to be re-enabled.
  38.  */
  39.  
  40. boolean
  41. fscoherent_disable_tty (zdevice, pzenable)
  42.      const char *zdevice;
  43.      char **pzenable;
  44. {
  45.  
  46.  
  47. struct ttyentry{            /* this is an /etc/ttys entry */
  48.     char enable_disable[1];
  49.     char remote_local[1];
  50.     char baud_rate[1];
  51.     char tty_device[16];
  52. };
  53.  
  54. struct ttyentry sought_tty;
  55.  
  56. int x,y,z;                /* dummy */
  57. FILE *    infp;                /* this will point to /etc/ttys */
  58. char disable_command[66];        /* this will be the disable command
  59.                      * passed to the system.
  60.                      */
  61. char enable_device[16];            /* this will hold our device name
  62.                      * to enable.
  63.                      */
  64.  
  65.     *pzenable = NULL;
  66.  
  67.     strcpy(enable_device,"");    /* initialize our strings */
  68.     strcpy(sought_tty.tty_device,"");
  69.  
  70.     if( (infp = fopen("/etc/ttys","r")) == NULL){
  71.         ulog(LOG_ERROR,"Error: check_disable_tty: failed to open /etc/ttys\n");
  72.         return FALSE;
  73.     }
  74.  
  75.     while (NULL !=(fgets(&sought_tty, sizeof (sought_tty), infp ))){
  76.         sought_tty.tty_device[strlen(sought_tty.tty_device) -1] = '\0';
  77.         strcpy(enable_device,sought_tty.tty_device);
  78.  
  79.         /* we must strip away the suffix to the com port name or
  80.          * we will never find a match. For example, if we are passed
  81.          * /dev/com4l to call out with and the port is already enabled,
  82.          * 9/10 the port enabled will be com4r. After we strip away the
  83.          * suffix of the port found in /etc/ttys, then we can test
  84.          * if the base port name appears in the device name string
  85.          * passed to us.
  86.          */
  87.  
  88.         for(z = strlen(sought_tty.tty_device) ; z > 0 ; z--){
  89.             if(isdigit(sought_tty.tty_device[z])){
  90.                 break;
  91.             }
  92.         }
  93.         y = strlen(sought_tty.tty_device);
  94.         for(x = z+1 ; x <= y; x++){
  95.             sought_tty.tty_device[x] = '\0';
  96.         }
  97.  
  98.  
  99. /*        ulog(LOG_NORMAL,"found device {%s}\n",sought_tty.tty_device); */
  100.         if(strstr(zdevice, sought_tty.tty_device)){
  101.             if(sought_tty.enable_disable[0] == '1'){
  102.                 ulog(LOG_NORMAL, "coh_tty: Disabling device %s {%s}\n",
  103.                     zdevice, sought_tty.tty_device);
  104.                     sprintf(disable_command, "/etc/disable %s",enable_device);
  105.                 {
  106.                   pid_t ipid;
  107.                   const char *azargs[3];
  108.                   int aidescs[3];
  109.  
  110.                   azargs[0] = "/etc/disable";
  111.                   azargs[1] = enable_device;
  112.                   azargs[2] = NULL;
  113.                   aidescs[0] = SPAWN_NULL;
  114.                   aidescs[1] = SPAWN_NULL;
  115.                   aidescs[2] = SPAWN_NULL;
  116.                   ipid = ixsspawn (azargs, aidescs, TRUE,
  117.                            FALSE,
  118.                            (const char *) NULL, TRUE,
  119.                            TRUE,
  120.                            (const char *) NULL,
  121.                            (const char *) NULL,
  122.                            (const char *) NULL);
  123.                   if (ipid < 0)
  124.                     x = 1;
  125.                   else
  126.                     x = ixswait ((unsigned long) ipid,
  127.                          (const char *) NULL);
  128.                 }
  129.                 *pzenable = zbufalc (sizeof "/dev/"
  130.                              + strlen (enable_device));
  131.                 sprintf(*pzenable,"/dev/%s", enable_device);
  132. /*                ulog(LOG_NORMAL,"Enable string is {%s}",*pzenable); */
  133.                 return(x==0? TRUE : FALSE); /* disable either failed
  134.                                or succeded */
  135.             }else{
  136.                 return FALSE;    /* device in tty entry not enabled */
  137.             }
  138.         }
  139.     }
  140.     return FALSE;    /* no ttys entry found */
  141. }
  142.  
  143. /* The following is COHERENT 4.0 specific. It is used to test for any
  144.  * existing lockfiles on a port which would have been created by init
  145.  * when a user logs into a port.
  146.  */
  147.  
  148. #define LOCKSIG        9    /* Significant Chars of Lockable Resources.  */
  149. #define LOKFLEN        64    /* Max Length of UUCP Lock File Name.         */
  150.  
  151. #define    LOCKPRE    "LCK.."
  152. #define PIDLEN    6    /* Maximum length of string representing a pid.  */
  153.  
  154. #ifndef LOCKDIR
  155. #define LOCKDIR SPOOLDIR
  156. #endif
  157.  
  158. /* There is a special version of DEVMASK for the PE multiport driver
  159.  * because of the peculiar way it uses the minor device number.  For
  160.  * all other drivers, the lower 5 bits describe the physical port--
  161.  * the upper 3 bits give attributes for the port.
  162.  */
  163.  
  164. #define PE_DRIVER 21    /* Major device number for the PE driver.  */
  165. #define PE_DEVMASK 0x3f    /* PE driver minor device mask.  */
  166. #define DEVMASK 0x1f    /* Minor device mask.  */
  167.  
  168. /*
  169.  * Generates a resource name for locking, based on the major number
  170.  * and the lower 4 bits of the minor number of the tty device.
  171.  *
  172.  * Builds the name in buff as two "." separated decimal numbers.
  173.  * Returns NULL on failure, buff on success.
  174.  */
  175. static char *
  176. gen_res_name(path, buff)
  177. char *path;
  178. char *buff;
  179. {
  180.     struct stat sbuf;
  181.     int status;
  182.     
  183.     if (0 != (status = stat(path, &sbuf))) {
  184.         /* Can't stat the file.  */
  185.         return (NULL);
  186.     }
  187.  
  188.     if (PE_DRIVER == major(sbuf.st_rdev)) {
  189.         sprintf(buff, "%d.%d", major(sbuf.st_rdev),
  190.                        PE_DEVMASK & minor(sbuf.st_rdev));
  191.     } else {
  192.         sprintf(buff, "%d.%d", major(sbuf.st_rdev),
  193.                        DEVMASK & minor(sbuf.st_rdev));
  194.     }
  195.  
  196.     return(buff);
  197. } /* gen_res_name */
  198.  
  199. /*
  200.  *  lockexist(resource)  char *resource;
  201.  *
  202.  *  Test for existance of a lock on the given resource.
  203.  *
  204.  *  Returns:  (1)  Resource is locked.
  205.  *          (0)  Resource is not locked.
  206.  */
  207.  
  208. static boolean
  209. lockexist(resource)
  210. const char    *resource;
  211. {
  212.     char lockfn[LOKFLEN];
  213.  
  214.     if ( resource == NULL )
  215.         return(0);
  216.     sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
  217.  
  218.     return (!access(lockfn, AEXISTS));
  219. } /* lockexist() */
  220.  
  221. /*
  222.  *  lockttyexist(ttyname)  char *ttyname;
  223.  *
  224.  *  Test for existance of a lock on the given tty.
  225.  *
  226.  *  Returns:  (1)  Resource is locked.
  227.  *          (0)  Resource is not locked.
  228.  */
  229. boolean
  230. lockttyexist(ttyn)
  231. const char *ttyn;
  232. {
  233.     char resource[LOKFLEN];
  234.     char filename[LOKFLEN];
  235.  
  236.     sprintf(filename, "/dev/%s", ttyn);
  237.     if (NULL == gen_res_name(filename, resource)){
  238.         return(0);    /* Non-existent tty can not be locked :-) */
  239.     }
  240.  
  241.     return(lockexist(resource));
  242. } /* lockttyexist() */
  243.  
  244. #endif /* HAVE_COHERENT_LOCKFILES */
  245.