OSDN Git Service

804c6317484e97382154f04a8154eb7c2773deb2
[opengate/opengate.git] / opengate / opengatesrv / utilities.c
1 /**************************************************
2 opengate server
3  utility routines
4
5 Copyright (C) 1999 Opengate Project Team
6 Written by Yoshiaki Watanabe
7 Modified Katsuhiko Eguchi, 2005 
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 Email: watanaby@is.saga-u.ac.jp
24 **************************************************/
25
26 #include "opengatesrv.h"
27
28 /*************************************************/
29 /* formated write                                */
30 /* fd : file descriptor                          */
31 /* fmt : format to write                         */
32 /* ... : terms to write                          */
33 /*************************************************/
34 void Writefmt(int fd, const char *fmt, ...)
35 {
36   char  buff[BUFFMAXLN];
37   va_list     ap;
38   int nchar, nwrt;
39
40   va_start(ap, fmt);
41   vsnprintf(buff, BUFFMAXLN, fmt, ap);  
42   va_end(ap);
43
44   nchar=strlen(buff);
45   nwrt=write(fd, buff, nchar);
46
47   return;
48 }
49
50
51 void WritefmtSSL(SSL *fd, const char *fmt, ...)
52 {
53   char  buff[BUFFMAXLN];
54   va_list     ap;
55   int nchar, nwrt;
56
57   va_start(ap, fmt);
58   vsnprintf(buff, BUFFMAXLN, fmt, ap);  
59   va_end(ap);
60
61   nchar=strlen(buff);
62   nwrt=SSL_write(fd, buff, nchar);
63
64   return;
65 }
66
67
68 /******************************************************/
69 /* Read one line                                      */
70 /*   fd: file descriptor                              */
71 /*   vptr: input buffer pointer                       */
72 /*   maxlen: buffer length                            */
73 /*                                                    */
74 /* the chars terminated with EOL or EOF is read in    */
75 /* ## this function assumes two EOL chars [CR LF]     */ 
76 /*  CRLF is not read in and skipped                   */
77 /* [abcdCRLFefghCRLF] => read[abcd],left[efghCRLF]    */
78 /*                                                    */
79 /* return value                                       */
80 /*    plus value means the count of chars to read     */
81 /*    value 0 means NULL line (no-chars & CRLF)       */
82 /*    value -1 means error (errno is set)             */
83 /*    value -2 means EOF (no-chars & EOF)             */ 
84 /******************************************************/
85 ssize_t
86 readln(int fd, void *vptr, size_t maxlen)
87 {
88   ssize_t       n, rc;
89   char  *ptr,c;
90
91   ptr=vptr;
92
93   /* pre read */
94   rc = read(fd, &c, 1);
95   if(rc==0) return(-2); /* EOF */
96   if(rc<0) return(-1);  /* ERR */
97
98   /* get char loop */
99   n=0;
100   while(n < maxlen-1) {
101     if ( rc == 1) {      /* get some char */
102       if (iscntrl(c)){         /* get control char (means EOL) */
103         rc = read(fd, &c, 1);  /* skip second EOL char */
104         break;
105       }
106       *ptr++ = c;
107       n++;
108     }else if (rc == 0) { /* EOF (but some chars are read already) */
109       break;
110     } else {             /* ERR */
111       return(-1);
112     }
113     rc = read(fd, &c, 1);
114   }
115   /* null terminate string */  
116   *ptr++ = 0;
117
118   return(n);
119 }
120
121
122 ssize_t
123 readlnSSL(SSL *fd, void *vptr, size_t maxlen)
124 {
125   ssize_t       n, rc;
126   char  *ptr,c;
127
128   ptr=vptr;
129
130   /* pre read */
131   rc = SSL_read(fd, &c, 1);
132   if(rc==0) return(-2); /* EOF */
133   if(rc<0) return(-1);  /* ERR */
134
135   /* get char loop */
136   n=0;
137   while(n < maxlen-1) {
138     if ( rc == 1) {      /* get some char */
139       if (iscntrl(c)){      /* get control char (means EOL) */
140           rc = SSL_read(fd, &c, 1); /* skip second EOL char */
141           break;
142       }
143       *ptr++ = c;
144       n++;
145     }else if (rc == 0) { /* EOF (but some char are read already */
146       break;
147     } else {             /* ERR */
148       return(-1);
149     }
150     rc = SSL_read(fd, &c, 1);
151   }
152   /* null terminate string */  
153   *ptr++ = 0;
154   return(n);
155 }
156
157
158 /******************************/
159 /* lock functions using fcntl */
160 /******************************/
161 int lock(int fd)
162 {
163   struct flock lck;
164   
165   lck.l_type=F_WRLCK;
166   lck.l_whence=SEEK_SET;
167   lck.l_start=0;
168   lck.l_len=0;
169   return fcntl(fd, F_SETLKW, &lck);
170 }
171   
172 /********************************/
173 /* unlock functions using fcntl */
174 /********************************/
175 int unlock(int fd)
176 {
177   struct flock lck;
178
179   lck.l_type=F_UNLCK;
180   lck.l_whence=SEEK_SET;
181   lck.l_start=0;
182   lck.l_len=0;
183   return fcntl(fd, F_SETLK, &lck);
184 }
185
186 /**************************************/
187 /* check NULL or point to null string */
188 /**************************************/
189 int isNull(const char *pStr)
190 {
191   if(pStr==NULL) return TRUE;
192   if(*pStr=='\0') return TRUE;
193   return FALSE;
194 }
195
196
197
198 /**************************************************/
199 /* popen with argument list                       */
200 /* type : open type "r" or "w"                    */
201 /* path : command path to fork/exec               */
202 /* ... : command arguments. last must be (char*)0 */
203 /*  DO NOT SET user entered string in args        */
204 /**************************************************/
205 FILE *Popenl(const char *type, const char *path, ...)
206 {
207   char  commandLine[BUFFMAXLN];
208   va_list     ap;
209   char *pStr;
210   FILE *file;
211
212   /* insert command path */
213   strncpy(commandLine, path, BUFFMAXLN);
214
215   /* insert command arguments */
216   va_start(ap, path);
217   
218   while((pStr=va_arg(ap, char *))!=(char *)0){
219     strcat(commandLine, " ");
220     strncat(commandLine, pStr, BUFFMAXLN);
221   }
222
223   va_end(ap);
224
225   /* open the pipe to the program  */
226   if(debug>1) err_msg("DEBUG:=>popen(%s, %s)", commandLine, type);
227   file=popen(commandLine, type);
228   if(debug>1) err_msg("DEBUG:(%x)<=popen( )",file);  
229
230   return file;
231 }
232
233
234 /**************************************************/
235 /* system with argument list                      */
236 /* path : command path to fork/exec               */
237 /* ... : command arguments. last must be (char*)0 */
238 /*  DO NOT SET user entered string in args        */
239 /**************************************************/
240 int Systeml(const char *path, ...)
241 {
242   char  commandLine[BUFFMAXLN];
243   va_list     ap;
244   char *pStr;
245   int ret;
246
247   /* insert command path */
248   strncpy(commandLine, path, BUFFMAXLN);
249
250   /* insert command arguments */
251   va_start(ap, path);
252   
253   while((pStr=va_arg(ap, char *))!=(char *)0){
254     strcat(commandLine, " ");
255     strncat(commandLine, pStr, BUFFMAXLN);
256   }
257
258   va_end(ap);
259
260   /* execute shell  */
261   if(debug>1) err_msg("DEBUG:=>system(%s)", commandLine);
262   ret=system(commandLine);
263   if(debug>1) err_msg("DEBUG:<=system()");
264
265   return ret;
266 }
267
268 /*******************************************/
269 /* get port number string in /etc/services */
270 /*******************************************/
271 char *getServicePortStr(char *servName)
272 {
273   struct servent *pServEnt;
274   static char portStr[WORDMAXLN];
275
276   /* get service info from service name */
277   pServEnt = getservbyname(servName, NULL);
278
279   if(pServEnt==NULL){
280     err_msg("ERR at %s#%d: cannot find /etc/services entry for %s",
281             __FILE__,__LINE__,servName);
282     return "";
283   }
284
285   /* convert service port number to string form */
286   snprintf(portStr, sizeof(portStr),"%d",ntohs(pServEnt->s_port));
287
288   return portStr;
289 }
290
291 /*******************************************/
292 /* create random session id                */
293 /*  simple but might be overlapped         */
294 /*  change logic, if you need identical id */ 
295 /*******************************************/
296 void createSessionId(char *sessionId)
297 {
298   srandom(getpid()+time(NULL));
299   snprintf(sessionId, BUFFMAXLN, "%ld", random() );
300 }
301 /*************************************************/
302 /* calc MD5 in hex form                          */
303 /*  str: plain text to convert                   */
304 /*  hexdigest: converted hex string              */
305 /*      prepare buff more or equal to 33chars    */
306 /*  len: length of hexdigest buffer              */
307 /*************************************************/
308 char *md5hex(char *hexdigest, int len, char *str)
309 {
310   char unsigned digest[16];
311   char hexcode[16]="0123456789abcdef";
312   int i;
313   
314   /* if not enough buffer, exit */
315   if(len<33){
316     *hexdigest='\0';
317     return hexdigest;
318   }
319
320   /* calc MD5 digest */
321   MD5(str, strlen(str), digest);
322
323   /* convert to HEX string */
324   for(i=0;i<16;i++){
325     hexdigest[2*i]=hexcode[digest[i]/16];
326     hexdigest[2*i+1]=hexcode[digest[i]%16];
327   }
328   hexdigest[2*16]='\0';
329
330   return hexdigest;
331 }
332
333 /****************************************/
334 /****************************************/
335 int Pclose(FILE *stream)
336 {
337   int ret;
338
339   if(debug>1) err_msg("DEBUG:=>pclose( )");
340   ret = pclose(stream);
341   if(debug>1) err_msg("DEBUG:<=pclose( )");  
342
343   return ret;
344 }
345
346 char *GetServicePortStr(char *servName)
347 {
348   char *ret;
349
350   if(debug>1) err_msg("DEBUG:=>getServicePortStr(%s)", servName);
351   ret = getServicePortStr(servName);
352   if(debug>1) err_msg("DEBUG:(%s)<=getServicePortStr( )", ret);  
353
354   return ret;
355 }
356
357 ssize_t Readln(int fd, void *ptr, size_t maxlen)
358 {
359   ssize_t               n;
360
361   if(debug>1) err_msg("DEBUG:=>readln( )");
362   if ( (n = readln(fd, ptr, maxlen)) < 0){
363     err_msg("ERR at %s#%d: readln error",__FILE__,__LINE__);
364   }
365   if(debug>1) err_msg("DEBUG:(%d)<=readln( )",n);
366
367   return(n);
368 }
369
370 int Lock(int fd)
371 {
372   int ret;
373
374   if(debug>1) err_msg("DEBUG:=>lock( )");
375   ret=lock(fd);
376   if(debug>1) err_msg("DEBUG:(%d)<=lock( )",ret);
377
378   return ret;
379 }
380
381
382 int Unlock(int fd)
383 {
384   int ret;
385
386   if(debug>1) err_msg("DEBUG:=>unlock( )");
387   ret=unlock(fd);
388   if(debug>1) err_msg("DEBUG:(%d)<=unlock( )",ret);
389
390   return ret;
391 }
392
393
394 void CreateSessionId(char *sessionId){
395   if(debug>1) err_msg("DEBUG:=>createSessionId( )");
396   createSessionId(sessionId);
397   if(debug>1) err_msg("DEBUG:<=createSessionId(%s)",sessionId);
398 }