1 /*
2   util.c
3 
4   $Id: util.cc,v 1.11 2005/05/30 02:13:28 evertonm Exp $
5  */
6 
7 #include <stdarg.h>
8 #include <string.h>
9 #include <time.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #include <sys/file.h>
19 #include <sys/socket.h>
20 #include <errno.h>
21 #include <stdio.h>
22 #include <syslog.h>
23 #include <stdlib.h>
24 
25 #include "util.h"
26 
27 /* Solaris */
28 #ifdef HAVE_SYS_TERMIOS_H
29 #include <sys/termios.h>
30 #endif
31 
32 int verbose_mode = 0; /* See ONVERBOSE in util.h */
33 
34 const char *prog_name = 0;
35 
set_prog_name(const char * name)36 void set_prog_name(const char *name)
37 {
38   prog_name = name;
39 }
40 
get_prog_name()41 const char *get_prog_name()
42 {
43   return prog_name ? prog_name : "?";
44 }
45 
safe_strdup(const char * str)46 char* safe_strdup(const char* str)
47 {
48   const char* fmt  = "%s: %s\n";
49   const char* func = "safe_strdup";
50 
51   if (!str) {
52     syslog(LOG_EMERG, fmt, func, "null string pointer");
53     exit(1);
54   }
55   char* s = strdup(str);
56   if (!s) {
57     syslog(LOG_EMERG, fmt, func, "could not allocate string");
58     exit(1);
59   }
60 
61   return s;
62 }
63 
safe_strcpy(char * trg,const char * src,int trg_buf_size)64 void safe_strcpy(char *trg, const char *src, int trg_buf_size)
65 {
66   for (char *past_end = trg + trg_buf_size - 1; trg < past_end; ++src, ++trg)
67     {
68       char c = *src;
69       *trg = c;
70       if (!c)
71         return;
72     }
73   *trg = '\0';
74 }
75 
cd_root()76 int cd_root() {
77 
78   if (chdir("/") == -1) {
79     syslog(LOG_WARNING, "cd_root(): can't chdir to / (root): %m");
80     return -1;
81   }
82 
83   return 0;
84 }
85 
std_to_null()86 int std_to_null() {
87   /*
88    * Conecta stdin, stdout e stderr a /dev/null.
89    */
90   const char *dev_null = "/dev/null";
91   int fd = open(dev_null, O_RDWR);
92   if (fd) {
93     if (fd < 0)
94       syslog(LOG_ERR, "std_to_null(): error opening %s: %m", dev_null);
95     else
96       syslog(LOG_ERR, "std_to_null(): opening %s: expected fd 0, got %d", dev_null, fd);
97     return -1;
98   }
99 
100   fd = dup(0);
101   if (fd != 1) {
102     if (fd < 0)
103       syslog(LOG_ERR, "std_to_null(): dup(0) failed: %m");
104     else
105       syslog(LOG_ERR, "std_to_null(): dup(0) expected fd 1, got %d", fd);
106     return -1;
107   }
108 
109   fd = dup(0);
110   if (fd != 2) {
111     if (fd < 0)
112       syslog(LOG_ERR, "std_to_null(): dup(0) failed: %m");
113     else
114       syslog(LOG_ERR, "std_to_null(): dup(0) expected fd 2, got %d", fd);
115     return -1;
116   }
117 
118   return 0;
119 }
120 
daemonize()121 int daemonize()
122 {
123   ONVERBOSE(syslog(LOG_INFO, "Daemonizing"));
124 
125   /*
126    * Tenta desconectar terminal de controle.
127    */
128   const char *tty_path = "/dev/tty";
129   int tty = open(tty_path, O_NOCTTY);
130   if (tty == -1)
131     syslog(LOG_WARNING, "daemonize(): can't open tty: %s: %m", tty_path);
132   else {
133     if (ioctl(tty, TIOCNOTTY))
134       syslog(LOG_WARNING, "daemonize(): can't detach terminal: %m");
135     if (close(tty))
136       syslog(LOG_WARNING, "daemonize(): can't close tty: %s: %m", tty_path);
137   }
138 
139   /*
140    * Garante que futuros open()s nao vao alocar um terminal de controle.
141    */
142   pid_t pid = fork();
143   if (pid) {
144     if (pid < 0) {
145       syslog(LOG_ERR, "daemonize(): fork() failed");
146       return -1;
147     }
148 
149     /*
150      * Parent exits
151      */
152     exit(0);
153   }
154   /*
155    * Child proceeds
156    */
157 
158   setsid();
159 
160   return 0;
161 }
162 
socket_close(int fd)163 void socket_close(int fd)
164 {
165   DEBUGFD(syslog(LOG_DEBUG, "socket_close() on socket FD %d", fd));
166   if (close(fd))
167     syslog(LOG_ERR, "socket_close(): close() on socket FD %d failed: %m", fd);
168 }
169 
170 /* eof: util.c */
171