]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libunix/cohtty.c
This commit was generated by cvs2svn to compensate for changes in r56545,
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libunix / cohtty.c
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 */