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