1 /*
2  * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *	nifmon - background process handling
28  *	------------------------------------
29  *
30  *      last edit-date: [Wed May  2 16:29:24 2001]
31  *
32  *---------------------------------------------------------------------------*/
33 
34 #include "nifmon.h"
35 
36 /*---------------------------------------------------------------------------*
37  *	check if another instance of us is already running
38  *---------------------------------------------------------------------------*/
39 void
check_pid(char * pidfn)40 check_pid(char *pidfn)
41 {
42 	FILE *fp;
43 
44 	/* check if another lock-file already exists */
45 
46 	if ((fp = fopen(pidfn, "r")) != NULL)
47 	{
48 		/* lockfile found, check */
49 
50 		int oldpid;
51 
52 		/* read pid from file */
53 
54 		if ((fscanf(fp, "%d", &oldpid)) != 1)
55 		{
56 			perror
57 				("ERROR, reading pid from lockfile failed, terminating!");
58 			exit(1);
59 		}
60 
61 		/* check if process got from file is still alive */
62 
63 		if ((kill(oldpid, 0)) != 0)
64 		{
65 			/* process does not exist */
66 
67 			/* close file */
68 
69 			fclose(fp);
70 
71 			/* remove file */
72 
73 			unlink(pidfn);
74 		}
75 		else
76 		{
77 			/* process is still alive */
78 
79 			fprintf(stderr,
80 				"ERROR, another daemon is already running, pid = %d, terminating!",
81 				oldpid);
82 			exit(1);
83 		}
84 	}
85 }
86 
87 /*---------------------------------------------------------------------------*
88  *	establish and init process lock file
89  *---------------------------------------------------------------------------*/
90 void
write_pid(char * pidfn)91 write_pid(char *pidfn)
92 {
93 	FILE *fp;
94 
95 	/* write my pid into lock-file */
96 
97 	if ((fp = fopen(pidfn, "w")) == NULL)
98 	{
99 		perror("ERROR, can't open lockfile for writing, terminating");
100 		do_exit(1);
101 	}
102 
103 	if ((fprintf(fp, "%d", (int) getpid())) == EOF)
104 	{
105 		perror("ERROR, can't write pid to lockfile, terminating");
106 		do_exit(1);
107 	}
108 
109 	fsync(fileno(fp));
110 
111 	fclose(fp);
112 }
113 
114 /*---------------------------------------------------------------------------*
115  *	become a daemon
116  *---------------------------------------------------------------------------*/
117 void
daemonize(void)118 daemonize(void)
119 {
120 	int fd;
121 	char *tp;
122 
123 	switch (fork())
124 	{
125 		case -1:	/* error */
126 			perror("ERROR, daemonize/fork");
127 			exit(1);
128 		case 0:	/* child */
129 			break;
130 		default:	/* parent */
131 			exit(0);
132 	}
133 
134 	chdir("/");	/* go away from mounted dir */
135 
136 	/* new session / no control tty */
137 
138 	if (setsid() == -1)
139 	{
140 		perror("ERROR, setsid");
141 		exit(1);
142 	}
143 
144 	if ((fd = open(rdev, O_RDWR, 0)) != -1)
145 	{
146 		if (!isatty(fd))
147 		{
148 			perror("ERROR, device is not a tty!");
149 			exit(1);
150 		}
151 		if ((dup2(fd, STDIN_FILENO)) == -1)
152 		{
153 			perror("ERROR, dup2 stdin");
154 			exit(1);
155 		}
156 		if ((dup2(fd, STDOUT_FILENO)) == -1)
157 		{
158 			perror("ERROR, dup2 stdout");
159 			exit(1);
160 		}
161 		if ((dup2(fd, STDERR_FILENO)) == -1)
162 		{
163 			perror("ERROR, dup2 stderr");
164 			exit(1);
165 		}
166 	}
167 	else
168 	{
169 		perror("ERROR, cannot open redirected device");
170 		exit(1);
171 	}
172 
173 	if (fd > 2)
174 	{
175 		if ((close(fd)) == -1)
176 		{
177 			perror("ERROR, close in daemonize");
178 			exit(1);
179 		}
180 	}
181 
182 	/* curses output && fork NEEDS controlling tty */
183 
184 	if ((ioctl(STDIN_FILENO, TIOCSCTTY, (char *) NULL)) < 0)
185 	{
186 		perror
187 			("ERROR, cannot setup tty as controlling terminal");
188 		exit(1);
189 	}
190 
191 	/* in case there is no environment ... */
192 
193 	if (((tp = getenv("TERM")) == NULL) || (*tp == '\0'))
194 	{
195 		if (has_term == 0)
196 		{
197 			perror
198 				("ERROR, no environment variable TERM found and -t not specified!");
199 			exit(1);
200 		}
201 
202 		if ((setenv("TERM", term, 1)) != 0)
203 		{
204 			perror("ERROR, setenv TERM failed");
205 			exit(1);
206 		}
207 	}
208 }
209 
210 /* EOF */
211