|
|
1.1 root 1: /* Coherent tty locking support. This file was contributed by Bob
2: Hemedinger <[email protected]> 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: * [email protected]
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.