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. */
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.
9 * These are for checking for the existence of locks:
11 * lockttyexist(ttyname)
16 #if HAVE_COHERENT_LOCKFILES
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
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.
40 /* May 10, 1993: This function will always return true for the following
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.
54 fscoherent_disable_tty (zdevice, pzenable)
60 struct ttyentry{ /* this is an /etc/ttys entry */
61 char enable_disable[1];
67 struct ttyentry sought_tty;
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.
74 char enable_device[16]; /* this will hold our device name
80 strcpy(enable_device,""); /* initialize our strings */
81 strcpy(sought_tty.tty_device,"");
83 if( (infp = fopen("/etc/ttys","r")) == NULL){
84 ulog(LOG_ERROR,"Error: check_disable_tty: failed to open /etc/ttys\n");
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);
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
101 for(z = strlen(sought_tty.tty_device) ; z > 0 ; z--){
102 if(isdigit(sought_tty.tty_device[z])){
106 y = strlen(sought_tty.tty_device);
107 for(x = z+1 ; x <= y; x++){
108 sought_tty.tty_device[x] = '\0';
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);
120 const char *azargs[3];
123 azargs[0] = "/etc/disable";
124 azargs[1] = enable_device;
126 aidescs[0] = SPAWN_NULL;
127 aidescs[1] = SPAWN_NULL;
128 aidescs[2] = SPAWN_NULL;
129 ipid = ixsspawn (azargs, aidescs, TRUE,
131 (const char *) NULL, TRUE,
135 (const char *) NULL);
139 x = ixswait ((unsigned long) ipid,
140 (const char *) NULL);
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); */
148 /* device not enabled */
153 return TRUE; /* no ttys entry found */
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.
161 #define LOCKSIG 9 /* Significant Chars of Lockable Resources. */
162 #define LOKFLEN 64 /* Max Length of UUCP Lock File Name. */
164 #define LOCKPRE "LCK.."
165 #define PIDLEN 6 /* Maximum length of string representing a pid. */
168 #define LOCKDIR SPOOLDIR
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.
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. */
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.
185 * Builds the name in buff as two "." separated decimal numbers.
186 * Returns NULL on failure, buff on success.
189 gen_res_name(path, buff)
196 if (0 != (status = stat(path, &sbuf))) {
197 /* Can't stat the file. */
201 if (PE_DRIVER == major(sbuf.st_rdev)) {
202 sprintf(buff, "%d.%d", major(sbuf.st_rdev),
203 PE_DEVMASK & minor(sbuf.st_rdev));
205 sprintf(buff, "%d.%d", major(sbuf.st_rdev),
206 DEVMASK & minor(sbuf.st_rdev));
213 * lockexist(resource) char *resource;
215 * Test for existance of a lock on the given resource.
217 * Returns: (1) Resource is locked.
218 * (0) Resource is not locked.
223 const char *resource;
225 char lockfn[LOKFLEN];
227 if ( resource == NULL )
229 sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
231 return (!access(lockfn, AEXISTS));
235 * lockttyexist(ttyname) char *ttyname;
237 * Test for existance of a lock on the given tty.
239 * Returns: (1) Resource is locked.
240 * (0) Resource is not locked.
246 char resource[LOKFLEN];
247 char filename[LOKFLEN];
249 sprintf(filename, "/dev/%s", ttyn);
250 if (NULL == gen_res_name(filename, resource)){
251 return(0); /* Non-existent tty can not be locked :-) */
254 return(lockexist(resource));
255 } /* lockttyexist() */
257 #endif /* HAVE_COHERENT_LOCKFILES */