1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All rights reserved. See COPYRIGHT.
4  *
5  * Copyright (c) 1990,1993 Regents of The University of Michigan.
6  * All Rights Reserved.  See COPYRIGHT.
7  */
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <termios.h>
19 #include <sys/ioctl.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <errno.h>
23 
24 #include <sys/time.h>
25 
26 #include <atalk/compat.h>
27 #include <atalk/util.h>
28 
29 static struct itimerval itimer;
30 
31 /* this creates an open lock file which hangs around until the program
32  * dies. it returns the pid. due to problems w/ solaris, this has
33  * been changed to do the kill() thing. */
server_lock(char * program,char * pidfile,int debug)34 pid_t server_lock(char *program, char *pidfile, int debug)
35 {
36 #ifndef SOLARIS
37   char buf[10];
38   FILE *pf;
39   pid_t pid;
40   int mask;
41 
42   if ( !debug ) {
43   mask = umask(022);
44   /* check for pid. this can get fooled by stale pid's. */
45   if ((pf = fopen(pidfile, "r"))) {
46     if (fgets(buf, sizeof(buf), pf) && !kill(pid = atol(buf), 0)) {
47       fprintf( stderr, "%s is already running (pid = %d), or the lock file is stale.\n",
48 	       program, pid);
49       fclose(pf);
50       return -1;
51     }
52     fclose(pf);
53   }
54 
55   if ((pf = fopen(pidfile, "w")) == NULL) {
56     fprintf(stderr, "%s: can't open lock file, \"%s\"\n", program,
57 	    pidfile);
58     return -1;
59   }
60   umask(mask);
61 
62   /*
63    * Disassociate from controlling tty.
64    */
65 
66     int		i;
67 
68     getitimer(ITIMER_PROF, &itimer);
69     switch (pid = fork()) {
70     case 0 :
71       setitimer(ITIMER_PROF, &itimer, NULL);
72       fclose(stdin);
73       fclose(stdout);
74       fclose(stderr);
75       i = open( "/dev/null", O_RDWR );
76       i = open( "/dev/null", O_RDWR );
77       i = open( "/dev/null", O_RDWR );
78 
79 #ifdef TIOCNOTTY
80       if (( i = open( "/dev/tty", O_RDWR )) >= 0 ) {
81 	(void)ioctl( i, TIOCNOTTY, 0 );
82 	setpgid( 0, getpid());
83 	(void) close(i);
84       }
85 #else
86       setpgid( 0, getpid());
87 #endif
88       break;
89     case -1 :  /* error */
90       perror( "fork" );
91     default :  /* server */
92       fclose(pf);
93       return pid;
94     }
95 
96   fprintf(pf, "%d\n", getpid());
97   fclose(pf);
98   }
99 #endif
100   return 0;
101 }
102 
103 /*!
104  * Check lockfile
105  */
check_lockfile(const char * program,const char * pidfile)106 int check_lockfile(const char *program, const char *pidfile)
107 {
108 #ifndef SOLARIS
109     char buf[10];
110     FILE *pf;
111     pid_t pid;
112 
113     /* check for pid. this can get fooled by stale pid's. */
114     if ((pf = fopen(pidfile, "r"))) {
115         if (fgets(buf, sizeof(buf), pf) && !kill(pid = atol(buf), 0)) {
116             fprintf(stderr, "%s is already running (pid = %d), or the lock file is stale.\n",
117                     program, pid);
118             fclose(pf);
119             return -1;
120         }
121         fclose(pf);
122     }
123 #endif
124     return 0;
125 }
126 
127 /*!
128  * Check and create lockfile
129  */
create_lockfile(const char * program,const char * pidfile)130 int create_lockfile(const char *program, const char *pidfile)
131 {
132 #ifndef SOLARIS
133     FILE *pf;
134     int mask;
135 
136     if (check_lockfile(program, pidfile) != 0)
137         return -1;
138 
139     /* Write PID to pidfile */
140     mask = umask(022);
141     if ((pf = fopen(pidfile, "w")) == NULL) {
142         fprintf(stderr, "%s: can't open lock file, \"%s\"\n", program,
143                 pidfile);
144         return -1;
145     }
146     umask(mask);
147     fprintf(pf, "%d\n", getpid());
148     fclose(pf);
149 #endif
150     return 0;
151 }
152