home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / cohtty.c < prev    next >
C/C++ Source or Header  |  1995-10-09  |  7KB  |  258 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. /* May 10, 1993: This function will always return true for the following
  41.  * reasons:
  42.  *  1) lock files have already been dealt with
  43.  *  2) if someone else already has the port open, uucico should fail anyways
  44.  *  3) Coherent's disable command return can return '0' or '1', but will
  45.  *     succeed in any event.
  46.  *  4) It doesn't matter if there is a ttys entry for the port in question.
  47.  *     /etc/ttys generally only lists devices that MAY be enabled for logins.
  48.  *     If a device will never be used for logins, then there may not be a
  49.  *     ttys entry, in which case, disable won't be called anyways.
  50.  *    ---bob@mwc.com
  51.  */
  52.  
  53. boolean
  54. fscoherent_disable_tty (zdevice, pzenable)
  55.      const char *zdevice;
  56.      char **pzenable;
  57. {
  58.  
  59.  
  60. struct ttyentry{            /* this is an /etc/ttys entry */
  61.     char enable_disable[1];
  62.     char remote_local[1];
  63.     char baud_rate[1];
  64.     char tty_device[16];
  65. };
  66.  
  67. struct ttyentry sought_tty;
  68.  
  69. int x,y,z;                /* dummy */
  70. FILE *    infp;                /* this will point to /etc/ttys */
  71. char disable_command[66];        /* this will be the disable command
  72.                      * passed to the system.
  73.                      */
  74. char enable_device[16];            /* this will hold our device name
  75.                      * to enable.
  76.                      */
  77.  
  78.     *pzenable = NULL;
  79.  
  80.     strcpy(enable_device,"");    /* initialize our strings */
  81.     strcpy(sought_tty.tty_device,"");
  82.  
  83.     if( (infp = fopen("/etc/ttys","r")) == NULL){
  84.         ulog(LOG_ERROR,"Error: check_disable_tty: failed to open /etc/ttys\n");
  85.         return FALSE;
  86.     }
  87.  
  88.     while (NULL !=(fgets(&sought_tty, sizeof (sought_tty), infp ))){
  89.         sought_tty.tty_device[strlen(sought_tty.tty_device) -1] = '\0';
  90.         strcpy(enable_device,sought_tty.tty_device);
  91.  
  92.         /* we must strip away the suffix to the com port name or
  93.          * we will never find a match. For example, if we are passed
  94.          * /dev/com4l to call out with and the port is already enabled,
  95.          * 9/10 the port enabled will be com4r. After we strip away the
  96.          * suffix of the port found in /etc/ttys, then we can test
  97.          * if the base port name appears in the device name string
  98.          * passed to us.
  99.          */
  100.  
  101.         for(z = strlen(sought_tty.tty_device) ; z > 0 ; z--){
  102.             if(isdigit(sought_tty.tty_device[z])){
  103.                 break;
  104.             }
  105.         }
  106.         y = strlen(sought_tty.tty_device);
  107.         for(x = z+1 ; x <= y; x++){
  108.             sought_tty.tty_device[x] = '\0';
  109.         }
  110.  
  111.  
  112. /*        ulog(LOG_NORMAL,"found device {%s}\n",sought_tty.tty_device); */
  113.         if(strstr(zdevice, sought_tty.tty_device)){
  114.             if(sought_tty.enable_disable[0] == '1'){
  115.                 ulog(LOG_NORMAL, "coh_tty: Disabling device %s {%s}\n",
  116.                     zdevice, sought_tty.tty_device);
  117.                     sprintf(disable_command, "/etc/disable %s",enable_device);
  118.                 {
  119.                   pid_t ipid;
  120.                   const char *azargs[3];
  121.                   int aidescs[3];
  122.  
  123.                   azargs[0] = "/etc/disable";
  124.                   azargs[1] = enable_device;
  125.                   azargs[2] = NULL;
  126.                   aidescs[0] = SPAWN_NULL;
  127.                   aidescs[1] = SPAWN_NULL;
  128.                   aidescs[2] = SPAWN_NULL;
  129.                   ipid = ixsspawn (azargs, aidescs, TRUE,
  130.                            FALSE,
  131.                            (const char *) NULL, TRUE,
  132.                            TRUE,
  133.                            (const char *) NULL,
  134.                            (const char *) NULL,
  135.                            (const char *) NULL);
  136.                   if (ipid < 0)
  137.                     x = 1;
  138.                   else
  139.                     x = ixswait ((unsigned long) ipid,
  140.                          (const char *) NULL);
  141.                 }
  142.                 *pzenable = zbufalc (sizeof "/dev/"
  143.                              + strlen (enable_device));
  144.                 sprintf(*pzenable,"/dev/%s", enable_device);
  145. /*                ulog(LOG_NORMAL,"Enable string is {%s}",*pzenable); */
  146.                 return TRUE;
  147.             }else{
  148.                 /* device not enabled */
  149.                 return TRUE;    
  150.             }
  151.         }
  152.     }
  153.     return TRUE;    /* no ttys entry found */
  154. }
  155.  
  156. /* The following is COHERENT 4.0 specific. It is used to test for any
  157.  * existing lockfiles on a port which would have been created by init
  158.  * when a user logs into a port.
  159.  */
  160.  
  161. #define LOCKSIG        9    /* Significant Chars of Lockable Resources.  */
  162. #define LOKFLEN        64    /* Max Length of UUCP Lock File Name.         */
  163.  
  164. #define    LOCKPRE    "LCK.."
  165. #define PIDLEN    6    /* Maximum length of string representing a pid.  */
  166.  
  167. #ifndef LOCKDIR
  168. #define LOCKDIR SPOOLDIR
  169. #endif
  170.  
  171. /* There is a special version of DEVMASK for the PE multiport driver
  172.  * because of the peculiar way it uses the minor device number.  For
  173.  * all other drivers, the lower 5 bits describe the physical port--
  174.  * the upper 3 bits give attributes for the port.
  175.  */
  176.  
  177. #define PE_DRIVER 21    /* Major device number for the PE driver.  */
  178. #define PE_DEVMASK 0x3f    /* PE driver minor device mask.  */
  179. #define DEVMASK 0x1f    /* Minor device mask.  */
  180.  
  181. /*
  182.  * Generates a resource name for locking, based on the major number
  183.  * and the lower 4 bits of the minor number of the tty device.
  184.  *
  185.  * Builds the name in buff as two "." separated decimal numbers.
  186.  * Returns NULL on failure, buff on success.
  187.  */
  188. static char *
  189. gen_res_name(path, buff)
  190. char *path;
  191. char *buff;
  192. {
  193.     struct stat sbuf;
  194.     int status;
  195.     
  196.     if (0 != (status = stat(path, &sbuf))) {
  197.         /* Can't stat the file.  */
  198.         return (NULL);
  199.     }
  200.  
  201.     if (PE_DRIVER == major(sbuf.st_rdev)) {
  202.         sprintf(buff, "%d.%d", major(sbuf.st_rdev),
  203.                        PE_DEVMASK & minor(sbuf.st_rdev));
  204.     } else {
  205.         sprintf(buff, "%d.%d", major(sbuf.st_rdev),
  206.                        DEVMASK & minor(sbuf.st_rdev));
  207.     }
  208.  
  209.     return(buff);
  210. } /* gen_res_name */
  211.  
  212. /*
  213.  *  lockexist(resource)  char *resource;
  214.  *
  215.  *  Test for existance of a lock on the given resource.
  216.  *
  217.  *  Returns:  (1)  Resource is locked.
  218.  *          (0)  Resource is not locked.
  219.  */
  220.  
  221. static boolean
  222. lockexist(resource)
  223. const char    *resource;
  224. {
  225.     char lockfn[LOKFLEN];
  226.  
  227.     if ( resource == NULL )
  228.         return(0);
  229.     sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
  230.  
  231.     return (!access(lockfn, AEXISTS));
  232. } /* lockexist() */
  233.  
  234. /*
  235.  *  lockttyexist(ttyname)  char *ttyname;
  236.  *
  237.  *  Test for existance of a lock on the given tty.
  238.  *
  239.  *  Returns:  (1)  Resource is locked.
  240.  *          (0)  Resource is not locked.
  241.  */
  242. boolean
  243. lockttyexist(ttyn)
  244. const char *ttyn;
  245. {
  246.     char resource[LOKFLEN];
  247.     char filename[LOKFLEN];
  248.  
  249.     sprintf(filename, "/dev/%s", ttyn);
  250.     if (NULL == gen_res_name(filename, resource)){
  251.         return(0);    /* Non-existent tty can not be locked :-) */
  252.     }
  253.  
  254.     return(lockexist(resource));
  255. } /* lockttyexist() */
  256.  
  257. #endif /* HAVE_COHERENT_LOCKFILES */
  258.