home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / ppp / dp-2.3 / dpd / uucplock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-11  |  6.0 KB  |  245 lines

  1. /*
  2.  * Copyright (c) 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19. /*
  20.  * Copyright (c) 1992 Purdue University
  21.  * All rights reserved.
  22.  *
  23.  * Redistribution and use in source and binary forms are permitted
  24.  * provided that the above copyright notice and this paragraph are
  25.  * duplicated in all such forms and that any documentation,
  26.  * advertising materials, and other materials related to such
  27.  * distribution and use acknowledge that the software was developed
  28.  * by Purdue University.  The name of the University may not be used
  29.  * to endorse or promote products derived * from this software without
  30.  * specific prior written permission.
  31.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  32.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  33.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  34.  *
  35.  * Note: this copyright applies to portions of this software developed
  36.  * at Purdue beyond the software covered by the original copyright.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)uucplock.c    5.5 (Berkeley) 6/1/90";
  41. #endif /* not lint */
  42.  
  43. #include <sys/types.h>
  44. #include <sys/file.h>
  45. #include <sys/dir.h>
  46. #include <errno.h>
  47.  
  48. extern char *sprintf();
  49.  
  50. /* 
  51.  * uucp style locking routines
  52.  * return: 0 - success
  53.  *       -1 - failure
  54.  */
  55. #if    1
  56. #define    _PATH_LOCKDIRNAME    "/var/spool/locks"
  57.  
  58. static int uu_dolock(), uu_lockactive(), chown_uucp();
  59.  
  60. /*
  61.  * These versions of uu_lock and uu_unlock are designed to be compatible
  62.  * with the way that the Sun uucp does locking..
  63.  */
  64. #define    MAXPIDLEN    10
  65. uu_lock(ttyname)
  66.     char *ttyname;
  67. {
  68.     char pid[MAXPIDLEN+2],
  69.          tfile[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN],
  70.          lfile[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
  71.         
  72.     (void)sprintf(pid, "%*d\n", MAXPIDLEN, getpid());
  73.     (void)sprintf(tfile, "%s/LTMP.%d", _PATH_LOCKDIRNAME, getpid());
  74.     (void)sprintf(lfile, "%s/LCK..%s", _PATH_LOCKDIRNAME, ttyname);
  75.  
  76.     /*
  77.      * If the lock fails, check to see if it is currently locked
  78.      * by a valid process.  If not, try the lock again.
  79.      */
  80.     if (uu_dolock(pid, tfile, lfile)) {
  81.         if (uu_lockactive(lfile))
  82.         return -1;
  83.         else if (uu_dolock(pid, tfile, lfile))
  84.         return -1;
  85.     }
  86.     return 0;
  87. }
  88.  
  89. static
  90. uu_lockactive(lfile)
  91. char *lfile;
  92. {
  93.     int lf;
  94.     char pid_str[MAXPIDLEN+2];
  95.     int pid, r;
  96.  
  97.     /*
  98.      * Make sure the file is readable and contains a valid PID.
  99.      * If not, and we can unlink it, then return success.
  100.      */
  101.     lf = open(lfile, O_RDONLY);
  102.     if (lf < 0)
  103.     return (errno == ENOENT) ? 0 : unlink(lfile);
  104.  
  105.     r = read(lf, pid_str, MAXPIDLEN+1);
  106.     (void)close(lf);
  107.     if (r != MAXPIDLEN+1)
  108.     return unlink(lfile);
  109.     pid = atoi(pid_str);
  110.     if (pid <= 0)
  111.     return unlink(lfile);
  112.  
  113.     /*
  114.      * We have a found a seemingly valid pid.
  115.      * Make sure the process is still around.
  116.      */
  117.     return (kill(pid, 0) == 0 || errno == EPERM) ? -1 : unlink(lfile);
  118. }
  119.  
  120. #define    DEFUUCPUID    4
  121. #define    DEFUUCPGID    8
  122.  
  123. #include <pwd.h>
  124. static
  125. chown_uucp(fd)
  126. int fd;
  127. {
  128.     static int uuid = -1, ugid;
  129.     struct passwd *pw;
  130.  
  131.     if (uuid < 0)
  132.     if (pw = getpwnam("uucp")) {
  133.         uuid = pw->pw_uid;
  134.         ugid = pw->pw_gid;
  135.     }
  136.     else {
  137.         uuid = DEFUUCPUID;
  138.         uuid = DEFUUCPGID;
  139.     }
  140.     return fchown(fd, uuid, ugid);
  141. }
  142.  
  143. static
  144. uu_dolock(pid, tfile, lfile)
  145. char *pid,
  146.      *tfile,
  147.      *lfile;
  148. {
  149.     int tf;
  150.  
  151.     tf = open(tfile, O_WRONLY|O_CREAT|O_TRUNC, 0444);
  152.     if (tf < 0) {
  153.     (void)unlink(tfile);
  154.     return -1;
  155.     }
  156.  
  157.     (void)write(tf, pid, MAXPIDLEN+1);
  158.     (void)fchmod(tf, 0444);
  159.     (void)chown_uucp(tf);
  160.     (void)close(tf);
  161.  
  162.     if (link(tfile, lfile) < 0) {
  163.     (void)unlink(tfile);
  164.     return -1;
  165.     }
  166.     (void)unlink(tfile);
  167.     return 0;
  168. }
  169.  
  170. uu_unlock(ttyname)
  171. char *ttyname;
  172. {
  173.     char lfile[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
  174.  
  175.     (void)sprintf(lfile, "%s/LCK..%s", _PATH_LOCKDIRNAME, ttyname);
  176.     return unlink(lfile);
  177. }
  178. #else
  179. #define    _PATH_LOCKDIRNAME    "/usr/spool/uucp/LCK..%s"
  180.  
  181. /*
  182.  * These routines must be for older style UUCP's.
  183.  */
  184. uu_lock(ttyname)
  185.     char *ttyname;
  186. {
  187.     extern int errno;
  188.     int fd, pid;
  189.     char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
  190.     long lseek();
  191.  
  192.     (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname);
  193.     fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660);
  194.     if (fd < 0) {
  195.         /*
  196.          * file is already locked
  197.          * check to see if the process holding the lock still exists
  198.          */
  199.         fd = open(tbuf, O_RDWR, 0);
  200.         if (fd < 0) {
  201.             /*perror("lock open");*/
  202.             return(-1);
  203.         }
  204.         if (read(fd, (char *)&pid, sizeof pid) != sizeof pid) {
  205.             (void)close(fd);
  206.             /*perror("lock read");*/
  207.             return(-1);
  208.         }
  209.  
  210.         if (kill(pid, 0) == 0 || errno != ESRCH) {
  211.             (void)close(fd);    /* process is still running */
  212.             return(-1);
  213.         }
  214.         /*
  215.          * The process that locked the file isn't running, so
  216.          * we'll lock it ourselves
  217.          */
  218.         if (lseek(fd, 0L, L_SET) < 0) {
  219.             (void)close(fd);
  220.             /*perror("lock lseek");*/
  221.             return(-1);
  222.         }
  223.         /* fall out and finish the locking process */
  224.     }
  225.     pid = getpid();
  226.     if (write(fd, (char *)&pid, sizeof(pid)) != sizeof(pid)) {
  227.         (void)close(fd);
  228.         (void)unlink(tbuf);
  229.         /*perror("lock write");*/
  230.         return(-1);
  231.     }
  232.     (void)close(fd);
  233.     return(0);
  234. }
  235.  
  236. uu_unlock(ttyname)
  237.     char *ttyname;
  238. {
  239.     char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
  240.  
  241.     (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname);
  242.     return(unlink(tbuf));
  243. }
  244. #endif
  245.