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