|
|
1.1 root 1: static char *sccsid = "@(#)cu.c 4.7 (Berkeley) 82/10/21";
2:
3: #include <stdio.h>
4: #include <signal.h>
5: #include <sgtty.h>
6:
7: /*
8: * defs that come from uucp.h
9: */
10: #define NAMESIZE 15
11: #define FAIL -1
12: #define SAME 0
13: #define SLCKTIME 5400 /* system/device timeout (LCK.. files) in seconds */
14: #define ASSERT(e, f, v) if (!(e)) {\
15: fprintf(stderr, "AERROR - (%s) ", "e");\
16: fprintf(stderr, f, v);\
17: cleanup(FAIL);\
18: }
19:
20: /*
21: * cu telno [-t] [-s speed] [-l line] [-a acu] [-p]
22: *
23: * -t is for dial-out to terminal.
24: * speeds are: 110, 134, 150, 300, 1200, 2400. 300 is default.
25: *
26: * -p says strip parity of characters transmitted. (to compensate
27: * for c100's)
28: *
29: * Escape with `~' at beginning of line.
30: * Ordinary diversions are ~<, ~> and ~>>.
31: * Silent output diversions are ~>: and ~>>:.
32: * Terminate output diversion with ~> alone.
33: * Quit is ~. and ~! gives local command or shell.
34: * Also ~$ for canned procedure pumping remote.
35: * ~%put from [to] and ~%take from [to] invoke builtins
36: */
37:
38: #define CRLF "\r\n"
39: #define wrc(ds) write(ds,&c,1)
40:
41:
42: char *devcul = "/dev/cul0";
43: char *devcua = "/dev/cua0";
44: char *lspeed = "300";
45:
46: int ln; /* fd for comm line */
47: char tkill, terase; /* current input kill & erase */
48: int efk; /* process of id of listener */
49: char c;
50: char oc;
51:
52: char *connmsg[] = {
53: "",
54: "line busy",
55: "call dropped",
56: "no carrier",
57: "can't fork",
58: "acu access",
59: "tty access",
60: "tty hung",
61: "usage: cu telno [-t] [-s speed] [-l line] [-a acu]",
62: "lock failed: line busy"
63: };
64:
65: rdc(ds) {
66:
67: ds=read(ds,&c,1);
68: oc = c;
69: c &= 0177;
70: return (ds);
71: }
72:
73: int intr;
74:
75: sig2()
76: {
77: signal(SIGINT, SIG_IGN);
78: intr = 1;
79: }
80:
81: int set14;
82:
83: xsleep(n)
84: {
85: xalarm(n);
86: pause();
87: xalarm(0);
88: }
89:
90: xalarm(n)
91: {
92: set14=n;
93: alarm(n);
94: }
95:
96: sig14()
97: {
98: signal(SIGALRM, sig14);
99: if (set14) alarm(1);
100: }
101:
102: int dout;
103: int nhup;
104: int dbflag;
105: int pflag; /* strip parity on chars sent to remote */
106: int nullbrk; /* turn breaks (nulls) into dels */
107: int pipes[2] = { -1, -1 };
108:
109: /*
110: * main: get connection, set speed for line.
111: * spawn child to invoke rd to read from line, output to fd 1
112: * main line invokes wr to read tty, write to line
113: */
114: main(ac,av)
115: char *av[];
116: {
117: int fk;
118: int speed;
119: char *telno;
120: struct sgttyb stbuf;
121: int cleanup();
122:
123: signal(SIGALRM, sig14);
124: signal(SIGINT, cleanup);
125: signal(SIGHUP, cleanup);
126: signal(SIGQUIT, cleanup);
127: if (ac < 2) {
128: prf(connmsg[8]);
129: exit(8);
130: }
131: for (; ac > 1; av++,ac--) {
132: if (av[1][0] != '-')
133: telno = av[1];
134: else switch(av[1][1]) {
135: case 't':
136: dout = 1;
137: --ac;
138: continue;
139: case 'b':
140: nullbrk++;
141: continue;
142: case 'd':
143: dbflag++;
144: continue;
145: case 'p':
146: pflag++;
147: continue;
148: case 's':
149: lspeed = av[2]; ++av; --ac;
150: break;
151: case 'l':
152: devcul = av[2]; ++av; --ac;
153: break;
154: case 'a':
155: devcua = av[2]; ++av; --ac;
156: break;
157: case '0': case '1': case '2': case '3': case '4':
158: case '5': case '6': case '7': case '8': case '9':
159: devcua[strlen(devcua)-1] = av[1][1];
160: devcul[strlen(devcul)-1] = av[1][1];
161: break;
162: default:
163: prf("Bad flag %s", av[1]);
164: break;
165: }
166: }
167: if (!exists(devcua) || !exists(devcul))
168: exit(9);
169: ln = conn(devcul, devcua, telno);
170: if (ln < 0) {
171: prf("Connect failed: %s",connmsg[-ln]);
172: cleanup(-ln);
173: }
174: switch(atoi(lspeed)) {
175: case 110:
176: speed = B110;break;
177: case 150:
178: speed = B150;break;
179: default:
180: case 300:
181: speed = B300;break;
182: case 1200:
183: speed = B1200;break;
184: case 2400:
185: speed = B2400;break;
186: }
187: stbuf.sg_ispeed = speed;
188: stbuf.sg_ospeed = speed;
189: stbuf.sg_flags = EVENP|ODDP;
190: if (!dout) {
191: stbuf.sg_flags |= RAW;
192: stbuf.sg_flags &= ~ECHO;
193: }
194: ioctl(ln, TIOCSETP, &stbuf);
195: ioctl(ln, TIOCEXCL, (struct sgttyb *)NULL);
196: ioctl(ln, TIOCHPCL, (struct sgttyb *)NULL);
197: prf("Connected");
198: pipe(pipes);
199: if (dout)
200: fk = -1;
201: else
202: fk = fork();
203: nhup = (int)signal(SIGINT, SIG_IGN);
204: if (fk == 0) {
205: chwrsig();
206: rd();
207: prf("\007Lost carrier");
208: cleanup(3);
209: }
210: mode(1);
211: efk = fk;
212: wr();
213: mode(0);
214: if (fk != -1) kill(fk, SIGKILL);
215: wait((int *)NULL);
216: stbuf.sg_ispeed = 0;
217: stbuf.sg_ospeed = 0;
218: ioctl(ln, TIOCSETP, &stbuf);
219: prf("Disconnected");
220: cleanup(0);
221: }
222:
223: /*
224: * conn: establish dial-out connection.
225: * Example: fd = conn("/dev/ttyh","/dev/dn1","4500");
226: * Returns descriptor open to tty for reading and writing.
227: * Negative values (-1...-7) denote errors in connmsg.
228: * Uses alarm and fork/wait; requires sig14 handler.
229: * Be sure to disconnect tty when done, via HUPCL or stty 0.
230: */
231:
232: conn(dev,acu,telno)
233: char *dev, *acu, *telno;
234: {
235: struct sgttyb stbuf;
236: extern errno;
237: char *p, *q, b[30];
238: char *ltail, *atail;
239: char *rindex();
240: int er, fk, dn, dh, t;
241: er=0;
242: fk=(-1);
243: atail = rindex(acu, '/')+1;
244: if (mlock(atail) == FAIL) {
245: er = 9;
246: goto X;
247: }
248: ltail = rindex(dev, '/')+1;
249: if (mlock(ltail) == FAIL) {
250: er = 9;
251: delock(atail);
252: goto X;
253: }
254: if ((dn=open(acu,1))<0) {
255: er=(errno == 6? 1:5);
256: goto X;
257: }
258: if ((fk=fork()) == (-1)) {
259: er=4;
260: goto X;
261: }
262: if (fk == 0) {
263: open(dev,2);
264: for (;;) pause();
265: }
266: xsleep(2);
267: /*
268: * copy phone #, assure EON
269: */
270: p=b;
271: q=telno;
272: while (*p++=(*q++))
273: ;
274: p--;
275: if (*(p-1)!='<') {
276: /*if (*(p-1)!='-') *p++='-';*/
277: *p++='<';
278: }
279: t=p-b;
280: xalarm(5*t);
281: t=write(dn,b,t);
282: xalarm(0);
283: if (t<0) {
284: er=2;
285: goto X;
286: }
287: /* close(dn) */
288: xalarm(40); /* was 5; sometimes missed carrier */
289: dh = open(dev,2);
290: xalarm(0);
291: if (dh<0) {
292: er=(errno == 4? 3:6);
293: goto X;
294: }
295: ioctl(dh, TIOCGETP, &stbuf);
296: stbuf.sg_flags &= ~ECHO;
297: xalarm(10);
298: ioctl(dh, TIOCSETP, &stbuf);
299: ioctl(dh, TIOCHPCL, (struct sgttyb *)NULL);
300: xalarm(0);
301: X:
302: if (er) close(dn);
303: delock(atail);
304: if (fk!=(-1)) {
305: kill(fk, SIGKILL);
306: xalarm(10);
307: while ((t=wait((int *)NULL))!=(-1) && t!=fk);
308: xalarm(0);
309: }
310: return (er? -er:dh);
311: }
312:
313: /*
314: * wr: write to remote: 0 -> line.
315: * ~. terminate
316: * ~<file send file
317: * ~! local login-style shell
318: * ~!cmd execute cmd locally
319: * ~$proc execute proc locally, send output to line
320: * ~%cmd execute builtin cmd (put and take)
321: * ~# send 1-sec break
322: * ~^Z suspend cu process.
323: */
324:
325: wr()
326: {
327: int ds,fk,lcl,x;
328: char *p,b[600];
329: for (;;) {
330: p=b;
331: while (rdc(0) == 1) {
332: if (p == b) lcl=(c == '~');
333: if (p == b+1 && b[0] == '~') lcl=(c!='~');
334: if (nullbrk && c == 0) oc=c=0177; /* fake break kludge */
335: if (!lcl) {
336: if(!pflag)c = oc;
337: if (wrc(ln) == 0) {
338: prf("line gone"); return;
339: }
340: c &= 0177;
341: }
342: if (lcl) {
343: if (c == 0177) c=tkill;
344: if (c == '\r' || c == '\n') goto A;
345: if (!dout) wrc(0);
346: }
347: *p++=c;
348: if (c == terase) {
349: p=p-2;
350: if (p<b) p=b;
351: }
352: if (c == tkill || c == 0177 || c == '\4' || c == '\r' || c == '\n') p=b;
353: }
354: return;
355: A:
356: if (!dout) echo("");
357: *p=0;
358: switch (b[1]) {
359: case '.':
360: case '\004':
361: return;
362: case '#':
363: ioctl(ln, TIOCSBRK, 0);
364: sleep(1);
365: ioctl(ln, TIOCCBRK, 0);
366: continue;
367: case '!':
368: case '$':
369: fk = fork();
370: if (fk == 0) {
371: char *getenv();
372: char *shell = getenv("SHELL");
373: if (shell == 0) shell = "/bin/sh";
374: close(1);
375: dup(b[1] == '$'? ln:2);
376: close(ln);
377: mode(0);
378: if (!nhup) signal(SIGINT, SIG_DFL);
379: if (b[2] == 0) execl(shell,shell,0);
380: /* if (b[2] == 0) execl(shell,"-",0); */
381: else execl(shell,"sh","-c",b+2,0);
382: prf("Can't execute shell");
383: exit(~0);
384: }
385: if (fk!=(-1)) {
386: while (wait(&x)!=fk);
387: }
388: mode(1);
389: if (b[1] == '!') echo("!");
390: else {
391: if (dout) echo("$");
392: }
393: break;
394: case '<':
395: if (b[2] == 0) break;
396: if ((ds=open(b+2,0))<0) {
397: prf("Can't divert %s",b+1);
398: break;
399: }
400: intr=x=0;
401: mode(2);
402: if (!nhup) signal(SIGINT, sig2);
403: while (!intr && rdc(ds) == 1) {
404: if (wrc(ln) == 0) {
405: x=1;
406: break;
407: }
408: }
409: signal(SIGINT, SIG_IGN);
410: close(ds);
411: mode(1);
412: if (x) return;
413: if (dout) echo("<");
414: break;
415: case '>':
416: case ':':
417: {
418: register char *q;
419:
420: if(pipes[1]==-1) {
421: prf("Can't tell other demon to divert");
422: break;
423: }
424: q = b+1;
425: if(*q=='>') q++;
426: write(pipes[1],q,strlen(q)+1);
427: if(dbflag) prf("msg to be delivered:"),prf(q);
428: if (efk != -1) kill(efk,SIGEMT);
429: }
430: break;
431: #ifdef SIGTSTP
432: #define CTRLZ 26
433: case CTRLZ:
434: mode(0);
435: kill(getpid(), SIGTSTP);
436: mode(1);
437: break;
438: #endif
439: case '%':
440: dopercen(&b[2]);
441: break;
442: default:
443: prf("Use `~~' to start line with `~'");
444: }
445: continue;
446: }
447: }
448:
449: dopercen(line)
450: register char *line;
451: {
452: char *args[10];
453: register narg, f;
454: int rcount;
455: for (narg = 0; narg < 10;) {
456: while(*line == ' ' || *line == '\t')
457: line++;
458: if (*line == '\0')
459: break;
460: args[narg++] = line;
461: while(*line != '\0' && *line != ' ' && *line != '\t')
462: line++;
463: if (*line == '\0')
464: break;
465: *line++ = '\0';
466: }
467: if (equal(args[0], "take")) {
468: if (narg < 2) {
469: prf("usage: ~%%take from [to]");
470: return;
471: }
472: if (narg < 3)
473: args[2] = args[1];
474: write(pipes[1], ">:/dev/null",sizeof(">:/dev/null"));
475: if(dbflag) prf("sending take message");
476: if (efk != -1) kill(efk,SIGEMT);
477: xsleep(5);
478: wrln("echo '~>");
479: wrln(args[2]);
480: wrln("'; tee /dev/null <");
481: wrln(args[1]);
482: wrln(";echo '~>'\n");
483: return;
484: } else if (equal(args[0], "put")) {
485: if (narg < 2) {
486: prf("usage: ~%%put from [to]");
487: return;
488: }
489: if (narg < 3)
490: args[2] = args[1];
491: if ((f = open(args[1], 0)) < 0) {
492: prf("cannot open: %s", args[1]);
493: return;
494: }
495: wrln("stty -echo;cat >");
496: wrln(args[2]);
497: wrln(";stty echo\n");
498: xsleep(5);
499: intr = 0;
500: if (!nhup)
501: signal(SIGINT, sig2);
502: mode(2);
503: rcount = 0;
504: while(!intr && rdc(f) == 1) {
505: rcount++;
506: if (c == tkill || c == terase)
507: wrln("\\");
508: if (wrc(ln) != 1) {
509: xsleep(2);
510: if (wrc(ln) != 1) {
511: prf("character missed");
512: intr = 1;
513: break;
514: }
515: }
516: }
517: signal(SIGINT, SIG_IGN);
518: close(f);
519: if (intr) {
520: wrln("\n");
521: prf("stopped after %d bytes", rcount);
522: }
523: wrln("\004");
524: xsleep(5);
525: mode(1);
526: return;
527: }
528: prf("~%%%s unknown\n", args[0]);
529: }
530:
531: equal(s1, s2)
532: register char *s1, *s2;
533: {
534: while (*s1++ == *s2)
535: if (*s2++ == '\0')
536: return(1);
537: return(0);
538: }
539:
540: wrln(s)
541: register char *s;
542: {
543: while (*s)
544: write(ln, s++, 1);
545: }
546: /* chwrsig: Catch orders from wr process
547: * to instigate diversion
548: */
549: int whoami;
550: chwrsig(){
551: int readmsg();
552: whoami = getpid();
553: signal(SIGEMT,readmsg);
554: }
555: int ds,slnt,taking;
556: int justrung;
557: readmsg(){
558: static char dobuff[128], morejunk[256];
559: int n;
560: justrung = 1;
561: signal(SIGEMT,readmsg);
562: if(dbflag) {
563: prf("About to read from pipe");
564: }
565: n = read(pipes[0],morejunk,256);
566: if(dbflag) {
567: prf("diversion mesg recieved is");
568: prf(morejunk);
569: prf(CRLF);
570: }
571: dodiver(morejunk);
572: }
573: dodiver(msg)
574: char *msg;
575: {
576: register char *cp = msg;
577:
578: if (*cp=='>') cp++;
579: if (*cp==':') {
580: cp++;
581: if(*cp==0) {
582: slnt ^= 1;
583: return;
584: } else {
585: slnt = 1;
586: }
587: }
588: if (ds >= 0) close(ds);
589: if (*cp==0) {
590: slnt = 0;
591: ds = -1;
592: return;
593: }
594: if (*msg!='>' || (ds=open(cp,1))<0) ds=creat(cp,0644);
595: lseek(ds, (long)0, 2);
596: if(ds < 0) prf("Creat failed:"), prf(cp);
597: if (ds<0) prf("Can't divert %s",cp+1);
598: }
599:
600:
601: /*
602: * rd: read from remote: line -> 1
603: * catch: diversion caught by interrupt routine
604: */
605:
606: #define ORDIN 0
607: #define SAWCR 1
608: #define EOL 2
609: #define SAWTL 3
610: #define DIVER 4
611:
612: rd()
613: {
614: extern int ds,slnt;
615: char rb[600], lb[600], *rlim, *llim, c;
616: register char *p,*q;
617: int cnt, state = 0, mustecho, oldslnt;
618:
619: ds=(-1);
620: p = lb; llim = lb+600;
621: agin:
622: while((cnt = read(ln,rb,600)) > 0) {
623: if(!slnt) write(1,rb,cnt);
624: if(ds < 0) continue;
625: oldslnt = slnt;
626: for( q=rb, rlim = rb + cnt - 1; q <= rlim; ) {
627: c = *q++ & 0177;
628: if(p < llim) *p++ = c;
629: switch(state) {
630: case ORDIN:
631: if(c=='\r') state = SAWCR;
632: break;
633: case SAWCR:
634: if(c=='\n') {
635: state = EOL;
636: p--;
637: p[-1] = '\n';
638: } else state = ORDIN;
639: break;
640: case EOL:
641: state = (c=='~' ? SAWTL :
642: (c=='\r' ? SAWCR : ORDIN));
643: break;
644: case SAWTL:
645: state = (c=='>' ? DIVER :
646: (c=='\r' ? SAWCR : ORDIN));
647: break;
648: case DIVER:
649: if(c=='\r') {
650: p--;
651: } else if (c=='\n') {
652: state = ORDIN;
653: p[-1] = 0;
654: dodiver(lb+2);
655: c = 0; p = lb;
656: }
657: }
658: if(slnt==0 && oldslnt) {
659: if(c=='\n') {
660: write(ln,lb,p-lb-1);
661: write(ln,CRLF,sizeof(CRLF));
662: } else if(q==rlim) {
663: write(ln,lb,p-lb);
664: c = '\n'; /*force flush to file*/
665: }
666: }
667: if(c=='\n') {
668: if(ds >= 0)
669: write(ds,lb,p-lb);
670: p = lb;
671: }
672: }
673: }
674: if(justrung) {
675: justrung = 0;
676: goto agin;
677: }
678: }
679:
680: struct {char lobyte; char hibyte;};
681: mode(f)
682: {
683: struct sgttyb stbuf;
684: if (dout) return;
685: ioctl(0, TIOCGETP, &stbuf);
686: tkill = stbuf.sg_kill;
687: terase = stbuf.sg_erase;
688: if (f == 0) {
689: stbuf.sg_flags &= ~RAW;
690: stbuf.sg_flags |= ECHO|CRMOD;
691: }
692: if (f == 1) {
693: stbuf.sg_flags |= RAW;
694: stbuf.sg_flags &= ~(ECHO|CRMOD);
695: }
696: if (f == 2) {
697: stbuf.sg_flags &= ~RAW;
698: stbuf.sg_flags &= ~(ECHO|CRMOD);
699: }
700: ioctl(0, TIOCSETP, &stbuf);
701: }
702:
703: echo(s)
704: char *s;
705: {
706: char *p;
707: for (p=s;*p;p++);
708: if (p>s) write(0,s,p-s);
709: write(0,CRLF, sizeof(CRLF));
710: }
711:
712: prf(f, s)
713: char *f;
714: char *s;
715: {
716: fprintf(stderr, f, s);
717: fprintf(stderr, CRLF);
718: }
719:
720: exists(devname)
721: char *devname;
722: {
723: if (access(devname, 0)==0)
724: return(1);
725: prf("%s does not exist", devname);
726: return(0);
727: }
728:
729: cleanup(code)
730: {
731: rmlock(NULL);
732: exit(code);
733: }
734:
735: /*
736: * This code is taken directly from uucp and follows the same
737: * conventions. This is important since uucp and cu should
738: * respect each others locks.
739: */
740:
741: /* ulockf 3.2 10/26/79 11:40:29 */
742: /* #include "uucp.h" */
743: #include <sys/types.h>
744: #include <sys/stat.h>
745:
746:
747:
748: /*******
749: * ulockf(file, atime)
750: * char *file;
751: * time_t atime;
752: *
753: * ulockf - this routine will create a lock file (file).
754: * If one already exists, the create time is checked for
755: * older than the age time (atime).
756: * If it is older, an attempt will be made to unlink it
757: * and create a new one.
758: *
759: * return codes: 0 | FAIL
760: */
761:
762: ulockf(file, atime)
763: char *file;
764: time_t atime;
765: {
766: struct stat stbuf;
767: time_t ptime;
768: int ret;
769: static int pid = -1;
770: static char tempfile[NAMESIZE];
771:
772: if (pid < 0) {
773: pid = getpid();
774: sprintf(tempfile, "/usr/spool/uucp/LTMP.%d", pid);
775: }
776: if (onelock(pid, tempfile, file) == -1) {
777: /* lock file exists */
778: /* get status to check age of the lock file */
779: ret = stat(file, &stbuf);
780: if (ret != -1) {
781: time(&ptime);
782: if ((ptime - stbuf.st_ctime) < atime) {
783: /* file not old enough to delete */
784: return(FAIL);
785: }
786: }
787: ret = unlink(file);
788: ret = onelock(pid, tempfile, file);
789: if (ret != 0)
790: return(FAIL);
791: }
792: stlock(file);
793: return(0);
794: }
795:
796:
797: #define MAXLOCKS 10 /* maximum number of lock files */
798: char *Lockfile[MAXLOCKS];
799: int Nlocks = 0;
800:
801: /***
802: * stlock(name) put name in list of lock files
803: * char *name;
804: *
805: * return codes: none
806: */
807:
808: stlock(name)
809: char *name;
810: {
811: char *p;
812: extern char *calloc();
813: int i;
814:
815: for (i = 0; i < Nlocks; i++) {
816: if (Lockfile[i] == NULL)
817: break;
818: }
819: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS %d", i);
820: if (i >= Nlocks)
821: i = Nlocks++;
822: p = calloc(strlen(name) + 1, sizeof (char));
823: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR %s", name);
824: strcpy(p, name);
825: Lockfile[i] = p;
826: return;
827: }
828:
829:
830: /***
831: * rmlock(name) remove all lock files in list
832: * char *name; or name
833: *
834: * return codes: none
835: */
836:
837: rmlock(name)
838: char *name;
839: {
840: int i;
841:
842: for (i = 0; i < Nlocks; i++) {
843: if (Lockfile[i] == NULL)
844: continue;
845: if (name == NULL
846: || strcmp(name, Lockfile[i]) == SAME) {
847: unlink(Lockfile[i]);
848: free(Lockfile[i]);
849: Lockfile[i] = NULL;
850: }
851: }
852: return;
853: }
854:
855:
856: /* this stuff from pjw */
857: /* /usr/pjw/bin/recover - check pids to remove unnecessary locks */
858: /* isalock(name) returns 0 if the name is a lock */
859: /* unlock(name) unlocks name if it is a lock*/
860: /* onelock(pid,tempfile,name) makes lock a name
861: on behalf of pid. Tempfile must be in the same
862: file system as name. */
863: /* lock(pid,tempfile,names) either locks all the
864: names or none of them */
865: isalock(name) char *name;
866: {
867: struct stat xstat;
868: if(stat(name,&xstat)<0) return(0);
869: if(xstat.st_size!=sizeof(int)) return(0);
870: return(1);
871: }
872: unlock(name) char *name;
873: {
874: if(isalock(name)) return(unlink(name));
875: else return(-1);
876: }
877: onelock(pid,tempfile,name) char *tempfile,*name;
878: { int fd;
879: fd=creat(tempfile,0444);
880: if(fd<0) return(-1);
881: write(fd,(char *) &pid,sizeof(int));
882: close(fd);
883: if(link(tempfile,name)<0)
884: { unlink(tempfile);
885: return(-1);
886: }
887: unlink(tempfile);
888: return(0);
889: }
890: lock(pid,tempfile,names) char *tempfile,**names;
891: { int i,j;
892: for(i=0;names[i]!=0;i++)
893: { if(onelock(pid,tempfile,names[i])==0) continue;
894: for(j=0;j<i;j++) unlink(names[j]);
895: return(-1);
896: }
897: return(0);
898: }
899:
900: #define LOCKPRE "/usr/spool/uucp/LCK."
901:
902: /***
903: * delock(s) remove a lock file
904: * char *s;
905: *
906: * return codes: 0 | FAIL
907: */
908:
909: delock(s)
910: char *s;
911: {
912: char ln[30];
913:
914: sprintf(ln, "%s.%s", LOCKPRE, s);
915: rmlock(ln);
916: }
917:
918:
919: /***
920: * mlock(sys) create system lock
921: * char *sys;
922: *
923: * return codes: 0 | FAIL
924: */
925:
926: mlock(sys)
927: char *sys;
928: {
929: char lname[30];
930: sprintf(lname, "%s.%s", LOCKPRE, sys);
931: return(ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
932: }
933:
934:
935:
936: /***
937: * ultouch() update access and modify times for lock files
938: *
939: * return code - none
940: */
941:
942: ultouch()
943: {
944: time_t time();
945: int i;
946: struct ut {
947: time_t actime;
948: time_t modtime;
949: } ut;
950:
951: ut.actime = time(&ut.modtime);
952: for (i = 0; i < Nlocks; i++) {
953: if (Lockfile[i] == NULL)
954: continue;
955: utime(Lockfile[i], &ut);
956: }
957: return;
958: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.