root/fwknop/tags/fwknop-0.9.7-pre1/fwknop_funcs.c

Revision 437, 6.1 kB (checked in by mbr, 3 years ago)

replaced multiple strlcat() calls with single snprintf()

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2 ********************************************************************************
3 *
4 *  File: fwknop_funcs.c
5 *
6 *  Purpose: fwknop_funcs.c contains several functions that are needed by
7 *           the fwkmd and fwkwd daemons, so putting these functions in
8 *           a single file make sense.
9 *
10 *  Author: Michael Rash (mbr@cipherdyne.org)
11 *
12 *  Version: 0.1
13 *
14 *  Copyright (C) 2004 Michael Rash (mbr@cipherdyne.org)
15 *
16 *  License (GNU Public License):
17 *
18 *     This program is distributed in the hope that it will be useful,
19 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *     GNU General Public License for more details.
22 *
23 *     You should have received a copy of the GNU General Public License
24 *     along with this program; if not, write to the Free Software
25 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
26 *     USA
27 *
28 ********************************************************************************
29 *
30 *  $Id$
31 */
32
33 /* includes */
34 #include "fwknop.h"
35
36 /* shared functions */
37 void slogr(const char *ident, const char *msg) {
38     openlog(ident, LOG_DAEMON, LOG_LOCAL7);
39     syslog(LOG_INFO, "%s", msg);
40     closelog();
41     return;
42 }
43
44 void check_unique_pid(const char *pid_file, const char *prog_name)
45 {
46     FILE *pidfile_ptr;
47     pid_t pid;
48     char pid_line[MAX_PID_SIZE+1];
49
50 #ifdef DEBUG
51     fprintf(stderr,
52         "[+] check_unique_pid(): opening pid file %s\n", pid_file);
53 #endif
54
55     if ((pidfile_ptr = fopen(pid_file, "r")) == NULL) {
56         /* the pid file must not exist (or we can't read it), so
57          * return... write_pid() will create it */
58         return;
59     }
60
61     /* read the first line of the pid_file, which will contain the
62      * process id of any running fwkmd process */
63     if (fgets(pid_line, MAX_PID_SIZE+1, pidfile_ptr) == NULL) {
64         return;
65     }
66
67     /* turn the pid_line into an integer */
68     pid = atoi(pid_line);
69
70     /* close the pid_file now that we have read it */
71     fclose(pidfile_ptr);
72
73 #ifdef DEBUG
74     fprintf(stderr,
75         "[+] check_unique_pid(): checking pid: %d with kill 0\n", pid);
76 #endif
77
78     if (kill(pid, 0) == 0) {  /* another prog_name is already running */
79         fprintf(stderr, "[*] %s is already running as pid: %d\n",
80             prog_name, pid);
81         exit(EXIT_FAILURE);
82     } else {
83         return;
84     }
85
86     return; /* for completness */
87 }
88
89 void write_pid(const char *pid_file, const pid_t pid)
90 {
91     FILE *pidfile_ptr;
92
93     if ((pidfile_ptr = fopen(pid_file, "w")) == NULL) {
94         /* could not open the pid file */
95         fprintf(stderr, "[*] Could not open the pid file: %s", pid_file);
96         exit(EXIT_FAILURE);
97     }
98
99     /* write the pid to the pid file */
100     if (fprintf(pidfile_ptr, "%d\n", pid) == 0) {
101         fprintf(stderr, "[*] pid: %d could not be written to pid file: %s",
102                 pid, pid_file);
103         exit(EXIT_FAILURE);
104     }
105
106     /* the pid_file now that we have read it */
107     fclose(pidfile_ptr);
108
109     return;
110 }
111
112 int find_char_var(char *search_str, char *charvar, char *line)
113 {
114     char *index_tmp;
115     int char_ctr = 0, i;
116
117     index_tmp = line;
118
119     /* look for specific variables in the config
120      * file that match the search_str */
121
122     for (i=0; i < strlen(search_str); i++)
123         if (index_tmp[i] != search_str[i])
124             return 0;
125
126 #ifdef DEBUG
127     fprintf(stderr, "[+] find_char_var(): found %s in line: %s",
128             search_str, line);
129 #endif
130
131     /* increment the pointer past the variable name */
132     while (*index_tmp != ' ') index_tmp++;
133
134     /* increment the pointer past the whitespace
135      * before the variable value */
136     while (*index_tmp == ' ') index_tmp++;
137
138     /* make sure that the variable has a semicolon
139      * at the end of the line */
140
141     /* get the number of characters in the variable
142      * before the ending semicolon */
143     while (index_tmp[char_ctr] != ';' && index_tmp[char_ctr] != '\0' &&
144            index_tmp[char_ctr] != '\n')
145         char_ctr++;
146
147     if (index_tmp[char_ctr] != ';') {
148         fprintf(stderr,
149             "[*] find_char_var(): No ending semicolon found for: %s.\n",
150             search_str);
151         exit(EXIT_FAILURE);
152     }
153
154     if (char_ctr > MAX_GEN_LEN-1) {
155         fprintf(stderr,
156                 "[*] find_char_var(): the config line for %s is too long.  Exiting.\n",
157                 search_str);
158         exit(EXIT_FAILURE);
159     }
160
161     strncpy(charvar, index_tmp, char_ctr);
162     charvar[char_ctr] = '\0'/* replace the ';' with the NULL character */
163     return 1;
164 }
165
166 /*
167  * Do everything required to cleanly become a daemon: fork(), start
168  * a new session, chdir "/", and close un-needed standard filehandles.
169  */
170 void daemonize_process(const char *pid_file)
171 {
172     pid_t child_pid, sid;
173
174     if ((child_pid = fork()) < 0) {
175         fprintf(stderr, "[*] Could not fork()");
176         exit(EXIT_FAILURE);
177     }
178
179     if (child_pid > 0) {
180 #ifdef DEBUG
181         fprintf(stderr, "[+] writing pid: %d to pid file: %s\n",
182                 child_pid, pid_file);
183 #endif
184         write_pid(pid_file, child_pid);
185         exit(EXIT_SUCCESS);   /* exit the parent process */
186     }
187
188     /*
189      * Now we are in the child process
190      */
191
192     /* start a new session */
193     if ((sid = setsid()) < 0) {
194         fprintf(stderr, "[*] setsid() Could not start a new session");
195         exit(EXIT_FAILURE);
196     }
197
198     /* make "/" the current directory */
199     if ((chdir("/")) < 0) {
200         fprintf(stderr, "[*] Could not chdir() to /");
201         exit(EXIT_FAILURE);
202     }
203
204     /* reset the our umask (for completeness) */
205     umask(0);
206
207     /* close un-needed file handles */
208     close(STDIN_FILENO);
209     close(STDOUT_FILENO);
210     close(STDERR_FILENO);
211
212     return;
213 }
214
215 void send_alert_email(const char *shCmd, const char *mailCmd,
216         const char *mail_str)
217 {
218     char mail_line[MAX_MSG_LEN] = "";
219     pid_t child_pid;
220
221     snprintf(mail_line, MAX_MSG_LEN, "%s %s",
222             mailCmd, mail_str);
223     mail_line[MAX_MSG_LEN-1] = '\0';
224     if ((child_pid = fork()) < 0)
225         /* could not fork */
226         exit(EXIT_FAILURE);
227     else if (child_pid > 0)
228         wait(NULL);  /* mail better work */
229     else
230         execle(shCmd, shCmd, "-c", mail_line, NULL, NULL);  /* don't use env */
231     return;
232 }
Note: See TracBrowser for help on using the browser.