|
|
1.1 root 1: /* filnam.c
2: Get names to use for UUCP files.
3:
4: Copyright (C) 1991, 1992 Ian Lance Taylor
5:
6: This file is part of the Taylor UUCP package.
7:
8: This program is free software; you can redistribute it and/or
9: modify it under the terms of the GNU General Public License as
10: published by the Free Software Foundation; either version 2 of the
11: License, or (at your option) any later version.
12:
13: This program is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16: General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with this program; if not, write to the Free Software
20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucp.h"
27:
28: #include "uudefs.h"
29: #include "uuconf.h"
30: #include "sysdep.h"
31: #include "system.h"
32:
33: #include <errno.h>
34:
35: #if HAVE_FCNTL_H
36: #include <fcntl.h>
37: #else
38: #if HAVE_SYS_FILE_H
39: #include <sys/file.h>
40: #endif
41: #endif
42:
43: #ifndef O_RDONLY
44: #define O_RDONLY 0
45: #define O_WRONLY 1
46: #define O_RDWR 2
47: #endif
48:
49: #ifndef O_NOCTTY
50: #define O_NOCTTY 0
51: #endif
52:
53: /* We need a definition for SEEK_SET. */
54:
55: #ifndef SEEK_SET
56: #define SEEK_SET 0
57: #endif
58:
59: /* External functions. */
60: #ifndef lseek
61: extern off_t lseek ();
62: #endif
63:
64: #define ZCHARS \
65: "0123456789ABCDEFGHIJKLMNOPQRTSUVWXYZabcdefghijklmnopqrstuvwxyz"
66:
67: /* Local functions. */
68:
69: static boolean fscmd_seq P((const char *zsystem, char *zseq));
70: static char *zsfile_name P((int btype, const char *zsystem,
71: const char *zlocalname, int bgrade,
72: boolean fxqt, char *ztname, char *zdname,
73: char *zxname));
74:
75: /* Get a new command sequence number (this is not a sequence number to
76: be used for communicating with another system, but a sequence
77: number to be used when generating the name of a command file).
78: The sequence number is placed into zseq, which should be five
79: characters long. */
80:
81: static boolean
82: fscmd_seq (zsystem, zseq)
83: const char *zsystem;
84: char *zseq;
85: {
86: boolean ferr;
87: char *zfree;
88: const char *zfile;
89: int o;
90: int i;
91:
92: /* Lock the sequence file. This may not be correct for all systems,
93: but it only matters if the system UUCP and this UUCP are running
94: at the same time. */
95: while (! fsdo_lock ("LCK..SEQ", TRUE, &ferr))
96: {
97: if (ferr || FGOT_SIGNAL ())
98: return FALSE;
99: sleep (5);
100: }
101:
102: zfree = NULL;
103:
104: #if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43
105: zfile = "SEQF";
106: #endif
107: #if SPOOLDIR_HDB || SPOOLDIR_SVR4
108: zfree = zsysdep_in_dir (".Sequence", zsystem);
109: zfile = zfree;
110: #endif
111: #if SPOOLDIR_ULTRIX
112: if (! fsultrix_has_spool (zsystem))
113: zfile = "sys/DEFAULT/.SEQF";
114: else
115: {
116: zfree = zsappend3 ("sys", zsystem, ".SEQF");
117: zfile = zfree;
118: }
119: #endif /* SPOOLDIR_ULTRIX */
120: #if SPOOLDIR_TAYLOR
121: zfree = zsysdep_in_dir (zsystem, "SEQF");
122: zfile = zfree;
123: #endif /* SPOOLDIR_TAYLOR */
124:
125: #ifdef O_CREAT
126: o = open ((char *) zfile, O_RDWR | O_CREAT | O_NOCTTY, IPUBLIC_FILE_MODE);
127: #else
128: o = open ((char *) zfile, O_RDWR | O_NOCTTY);
129: if (o < 0 && errno == ENOENT)
130: {
131: o = creat ((char *) zfile, IPUBLIC_FILE_MODE);
132: if (o >= 0)
133: {
134: (void) close (o);
135: o = open ((char *) zfile, O_RDWR | O_NOCTTY);
136: }
137: }
138: #endif
139:
140: if (o < 0)
141: {
142: if (errno == ENOENT)
143: {
144: if (! fsysdep_make_dirs (zfile, FALSE))
145: {
146: (void) fsdo_unlock ("LCK..SEQ", TRUE);
147: return FALSE;
148: }
149: #ifdef O_CREAT
150: o = open ((char *) zfile,
151: O_RDWR | O_CREAT | O_NOCTTY,
152: IPUBLIC_FILE_MODE);
153: #else
154: o = creat ((char *) zfile, IPUBLIC_FILE_MODE);
155: if (o >= 0)
156: {
157: (void) close (o);
158: o = open ((char *) zfile, O_RDWR | O_NOCTTY);
159: }
160: #endif
161: }
162: if (o < 0)
163: {
164: ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno));
165: (void) fsdo_unlock ("LCK..SEQ", TRUE);
166: return FALSE;
167: }
168: }
169:
170: if (read (o, zseq, CSEQLEN) != CSEQLEN)
171: strcpy (zseq, "0000");
172: zseq[CSEQLEN] = '\0';
173:
174: /* We must add one to the sequence number and return the new value.
175: On Ultrix, arbitrary characters are allowed in the sequence
176: number. On other systems, the sequence number apparently must be
177: in hex. */
178: #if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_HDB || SPOOLDIR_SVR4
179: i = (int) strtol (zseq, (char **) NULL, 16);
180: ++i;
181: if (i > 0xffff)
182: i = 0;
183: /* The sprintf argument has CSEQLEN built into it. */
184: sprintf (zseq, "%04x", (unsigned int) i);
185: #endif
186: #if SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR
187: for (i = CSEQLEN - 1; i >= 0; i--)
188: {
189: const char *zdig;
190:
191: zdig = strchr (ZCHARS, zseq[i]);
192: if (zdig == NULL || zdig[0] == '\0' || zdig[1] == '\0')
193: zseq[i] = '0';
194: else
195: {
196: zseq[i] = zdig[1];
197: break;
198: }
199: }
200: #endif /* SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR */
201:
202: if (lseek (o, (off_t) 0, SEEK_SET) < 0
203: || write (o, zseq, CSEQLEN) != CSEQLEN
204: || close (o) < 0)
205: {
206: ulog (LOG_ERROR, "lseek or write or close: %s", strerror (errno));
207: (void) close (o);
208: (void) fsdo_unlock ("LCK..SEQ", TRUE);
209: return FALSE;
210: }
211:
212: (void) fsdo_unlock ("LCK..SEQ", TRUE);
213:
214: return TRUE;
215: }
216:
217: /* Get the name of a command or data file for a remote system. The
218: btype argument should be C for a command file or D for a data file.
219: If the grade of a data file is X, it is assumed that this is going
220: to become an execute file on some other system. The zsystem
221: argument is the system that the file will be transferred to. The
222: ztname argument will be set to a file name that could be passed to
223: zsysdep_spool_file_name. The zdname argument, if not NULL, will be
224: set to a data file name appropriate for the remote system. The
225: zxname argument, if not NULL, will be set to the name of an execute
226: file on the remote system. None of the names will be more than 14
227: characters long. */
228:
229: /*ARGSUSED*/
230: static char *
231: zsfile_name (btype, zsystem, zlocalname, bgrade, fxqt, ztname, zdname, zxname)
232: int btype;
233: const char *zsystem;
234: const char *zlocalname;
235: int bgrade;
236: boolean fxqt;
237: char *ztname;
238: char *zdname;
239: char *zxname;
240: {
241: char abseq[CSEQLEN + 1];
242: char absimple[11 + CSEQLEN];
243: char *zname;
244:
245: if (zlocalname == NULL)
246: zlocalname = zSlocalname;
247:
248: while (TRUE)
249: {
250: if (! fscmd_seq (zsystem, abseq))
251: return NULL;
252:
253: if (btype == 'C')
254: {
255: #if ! SPOOLDIR_TAYLOR
256: sprintf (absimple, "C.%.7s%c%s", zsystem, bgrade, abseq);
257: #else
258: sprintf (absimple, "C.%c%s", bgrade, abseq);
259: #endif
260: }
261: else if (btype == 'D')
262: {
263: /* This name doesn't really matter that much; it's just the
264: name we use on the local system. The name we use on the
265: remote system, which we return in zdname, should contain
266: our system name so that remote UUCP's running SPOOLDIR_V2
267: and the like can distinguish while files come from which
268: systems. */
269: #if SPOOLDIR_HDB || SPOOLDIR_SVR4
270: sprintf (absimple, "D.%.7s%c%s", zsystem, bgrade, abseq);
271: #else /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
272: #if ! SPOOLDIR_TAYLOR
273: sprintf (absimple, "D.%.7s%c%s", zlocalname, bgrade, abseq);
274: #else /* SPOOLDIR_TAYLOR */
275: if (fxqt)
276: sprintf (absimple, "D.X%s", abseq);
277: else
278: sprintf (absimple, "D.%s", abseq);
279: #endif /* SPOOLDIR_TAYLOR */
280: #endif /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
281: }
282: #if DEBUG > 0
283: else
284: ulog (LOG_FATAL, "zsfile_name: Can't happen");
285: #endif
286:
287: zname = zsfind_file (absimple, zsystem, bgrade);
288: if (zname == NULL)
289: return NULL;
290:
291: if (! fsysdep_file_exists (zname))
292: break;
293:
294: ubuffree (zname);
295: }
296:
297: if (ztname != NULL)
298: strcpy (ztname, absimple);
299:
300: if (zdname != NULL)
301: sprintf (zdname, "D.%.7s%c%s", zlocalname, bgrade, abseq);
302:
303: if (zxname != NULL)
304: sprintf (zxname, "X.%.7s%c%s", zlocalname, bgrade, abseq);
305:
306: return zname;
307: }
308:
309: /* Return a name to use for a data file to be copied to another
310: system. The name returned will be for a real file. The zlocalname
311: argument is the local name as seen by the remote system, the bgrade
312: argument is the file grade, and the fxqt argument is TRUE if this
313: file will become an execution file. The ztname argument, if not
314: NULL, will be set to a name that could be passed to
315: zsysdep_spool_file_name to get back the return value of this
316: function. The zdname argument, if not NULL, will be set to a name
317: that the file could be given on another system. The zxname
318: argument, if not NULL, will be set to a name for an execute file on
319: another system. */
320:
321: char *
322: zsysdep_data_file_name (qsys, zlocalname, bgrade, fxqt, ztname, zdname,
323: zxname)
324: const struct uuconf_system *qsys;
325: const char *zlocalname;
326: int bgrade;
327: boolean fxqt;
328: char *ztname;
329: char *zdname;
330: char *zxname;
331: {
332: return zsfile_name ('D', qsys->uuconf_zname, zlocalname, bgrade, fxqt,
333: ztname, zdname, zxname);
334: }
335:
336: /* Get a command file name. */
337:
338: char *
339: zscmd_file (qsys, bgrade)
340: const struct uuconf_system *qsys;
341: int bgrade;
342: {
343: return zsfile_name ('C', qsys->uuconf_zname, (const char *) NULL,
344: bgrade, FALSE, (char *) NULL, (char *) NULL,
345: (char *) NULL);
346: }
347:
348: /* Return a name for an execute file to be created locally. This is
349: used by uux to execute a command locally with remote files. */
350:
351: char *
352: zsysdep_xqt_file_name ()
353: {
354: char abseq[CSEQLEN + 1];
355: char absx[11 + CSEQLEN];
356: char *zname;
357:
358: while (TRUE)
359: {
360: if (! fscmd_seq (zSlocalname, abseq))
361: return NULL;
362:
363: sprintf (absx, "X.%.7sX%s", zSlocalname, abseq);
364:
365: zname = zsfind_file (absx, zSlocalname, -1);
366: if (zname == NULL)
367: return NULL;
368:
369: if (! fsysdep_file_exists (zname))
370: break;
371:
372: ubuffree (zname);
373: }
374:
375: return zname;
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.