Cherry-picks the code from 0.1.x branch
[rahunas] / src / rh-utils.c
1 /**
2  * utility functions header
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2008-08-31
5  */
6
7 #include <string.h>
8 #include <syslog.h>
9 #include <glib.h>
10 #include <time.h>
11 #include <sys/stat.h>
12 #include <sys/wait.h>
13 #include <fcntl.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 #include "rahunasd.h"
18 #include "rh-utils.h"
19
20 void *rh_malloc(size_t size)
21 {
22   void *p;
23   
24   if (size == 0)
25     return NULL;
26
27   if ((p = malloc(size)) == NULL) {
28     syslog(LOG_ERR, "RahuNASd: not enough memory");
29     exit(EXIT_FAILURE);
30   } 
31
32   return p;
33 }
34
35 void rh_free(void **data)
36 {
37   if (*data == NULL)
38     return;
39
40   free(*data);
41   *data = NULL;
42 }
43
44 gchar *rh_string_get_sep(const char *haystack, const char *sep,
45                          unsigned short idx)
46 {
47   gchar *result = NULL;
48   const gchar *pStart = NULL;
49   const gchar *pEnd   = NULL;
50   const gchar *pLast  = NULL;
51   unsigned short current_idx = 0;
52   unsigned short isFound = 0;
53
54   if (!haystack) {
55     return NULL;
56   }
57
58   pEnd = haystack;
59   pLast = haystack + strlen(haystack);
60   while (!isFound) {
61     pStart = pEnd;
62     if (pStart == pLast) {
63       // Finding the separator fail
64       return NULL;
65     }
66
67     pEnd = g_strstr_len(pStart, strlen(pStart), sep);  
68     pEnd = pEnd == NULL ? pLast : pEnd;
69
70     current_idx++;
71
72     if (current_idx == idx) {
73       result = g_strndup(pStart, pEnd - pStart);
74       result = g_strchug (result);
75       result = g_strchomp (result);
76       return result;
77     } else {
78       pEnd++;
79     }
80   }
81 }
82
83 int rh_openlog(const char *filename)
84 {
85   return open(filename, O_WRONLY | O_APPEND | O_CREAT);
86 }
87
88 int rh_closelog(int fd)
89 {
90   if (close(fd) == 0)
91     return 1;
92   else
93     return 0;
94 }
95
96 int logmsg(int priority, const char *msg, ...) 
97 {
98   int n, size = 256;
99   va_list ap;
100   char *time_fmt = "%b %e %T";
101   char *p = NULL;
102   char *np = NULL;
103
104   if (priority < RH_LOG_LEVEL)
105     return 0;
106
107   if ((p = rh_malloc(size)) == NULL) {
108     return (-1);
109   }
110
111   while (1) {
112     va_start(ap, msg);
113     n = vsnprintf(p, size, msg, ap);
114     va_end(ap);
115
116     if (n > -1 && n < size)
117       break;
118  
119     if (n > -1)
120       size = n+1;
121     else
122       size *= 2;
123
124     if ((np = realloc(p, size)) == NULL) {
125       free(p);
126       p = NULL;
127       break;
128     } else {
129       p = np;
130     }
131   }
132
133   
134   if (!p)
135     return (-1);
136
137   fprintf(stderr, "%s : %s\n", timemsg(), p);
138
139   rh_free((void **) &p);
140   rh_free((void **) &np);
141 }
142
143
144 int rh_writepid(const char *pidfile, int pid)
145 {
146   int pidfd;
147
148   pidfd = open(DEFAULT_PID, O_WRONLY | O_TRUNC | O_CREAT);
149   if (pidfd) {
150     dup2(pidfd, STDOUT_FILENO);
151     fprintf(stdout, "%d\n", pid);
152     close(pidfd);
153   }
154 }
155
156 int rh_logselect(int fd)
157 {
158   dup2(fd, STDERR_FILENO);
159   return 0;
160 }
161
162 uint32_t iptoid(struct rahunas_map *map, const char *ip) {
163   uint32_t ret;
164   struct in_addr req_ip;
165
166   if (!map || !ip)
167     return (-1);
168
169   if (!(inet_aton(ip, &req_ip))) {
170     DP("Could not convert IP: %s", ip);
171     return (-1);  
172   }
173
174   DP("Request IP: %s", ip);
175   
176   ret = ntohl(req_ip.s_addr) - ntohl(map->first_ip);
177   if (ret < 0 || ret > (map->size - 1))
178     ret = (-1);
179
180   DP("Request Index: %lu", ret);
181   return ret; 
182 }
183
184 const char *idtoip(struct rahunas_map *map, uint32_t id) {
185   struct in_addr sess_addr;
186
187   if (!map)
188     return termstring;
189
190   if (id < 0)
191     return termstring;
192
193   sess_addr.s_addr = htonl((ntohl(map->first_ip) + id));
194
195   return inet_ntoa(sess_addr);
196 }
197
198