/[LeafOK_CVS]/pvpgn-1.7.4/src/common/util.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/common/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.1 /*
2     * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu)
3     * Copyright (C) 1998,1999,2000,2001 Ross Combs (rocombs@cs.nmsu.edu)
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version 2
8     * of the License, or (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18     */
19     #include "common/setup_before.h"
20     #include <stdio.h>
21     #ifdef HAVE_STDDEF_H
22     # include <stddef.h>
23     #else
24     # ifndef NULL
25     # define NULL ((void *)0)
26     # endif
27     #endif
28     #ifdef STDC_HEADERS
29     # include <stdlib.h>
30     #else
31     # ifdef HAVE_MALLOC_H
32     # include <malloc.h>
33     # endif
34     #endif
35     #include "compat/strtoul.h"
36     #ifdef HAVE_STRING_H
37     # include <string.h>
38     #else
39     # ifdef HAVE_STRINGS_H
40     # include <strings.h>
41     # endif
42     #endif
43     #include "compat/strcasecmp.h"
44     #include "compat/strncasecmp.h"
45     #include "common/xalloc.h"
46     #include <ctype.h>
47     #include "common/util.h"
48     #include "common/setup_after.h"
49    
50    
51     extern int strstart(char const * full, char const * part)
52     {
53     size_t strlen_full, strlen_part;
54     if (!full || !part)
55     return 1;
56     strlen_full = strlen(full);
57     strlen_part = strlen(part);
58     if (strlen_full<strlen_part)
59     return 1;
60     /* If there is more than the command, make sure it is separated */
61     if (strlen_full>strlen_part && full[strlen_part]!=' ' && full[strlen_part]!='\0')
62     return 1;
63     return strncasecmp(full,part,strlen_part);
64     }
65    
66    
67     #define DEF_LEN 64
68     #define INC_LEN 16
69    
70     extern char * file_get_line(FILE * fp)
71     {
72     static char * line = NULL;
73     static unsigned int len = 0;
74     unsigned int pos = 0;
75     int prev_char,curr_char;
76    
77     // use file_get_line with NULL argument to clear the buffer
78     if (!(fp))
79     {
80     len = 0;
81     if ((line))
82     xfree((void *)line);
83     line = NULL;
84     return NULL;
85     }
86    
87     if (!(line))
88     {
89     line = xmalloc(DEF_LEN);
90     len = DEF_LEN;
91     }
92    
93     prev_char = '\0';
94     while ((curr_char = fgetc(fp))!=EOF)
95     {
96     if (((char)curr_char)=='\r')
97     continue; /* make DOS line endings look Unix-like */
98     if (((char)curr_char)=='\n')
99     {
100     if (pos<1 || ((char)prev_char)!='\\')
101     break;
102     pos--; /* throw away the backslash */
103     prev_char = '\0';
104     continue;
105     }
106     prev_char = curr_char;
107    
108     line[pos++] = (char)curr_char;
109     if ((pos+1)>=len)
110     {
111     len += INC_LEN;
112     line = xrealloc(line,len);
113     }
114     }
115    
116     if (curr_char==EOF && pos<1) /* not even an empty line */
117     {
118     return NULL;
119     }
120    
121     line[pos] = '\0';
122    
123     return line;
124     }
125    
126    
127     extern char * strreverse(char * str)
128     {
129     unsigned int i;
130     unsigned int len;
131     char temp;
132    
133     if (!str)
134     return NULL;
135    
136     len = strlen(str);
137    
138     /* swap leftmost and rightmost chars until we hit center */
139     for (i=0; i<len/2; i++)
140     {
141     temp = str[i];
142     str[i] = str[len-1-i];
143     str[len-1-i] = temp;
144     }
145    
146     return str;
147     }
148    
149    
150     extern int str_to_uint(char const * str, unsigned int * num)
151     {
152     unsigned int pos;
153     unsigned int i;
154     unsigned int val;
155     unsigned int pval;
156    
157     if (!str || !num)
158     return -1;
159     for (pos=0; str[pos]==' ' || str[pos]=='\t'; pos++);
160     if (str[pos]=='+')
161     pos++;
162    
163     val = 0;
164     for (i=pos; str[i]!='\0'; i++)
165     {
166     pval = val;
167     val *= 10;
168     if (val/10!=pval) /* check for overflow */
169     return -1;
170    
171     pval = val;
172     switch (str[i])
173     {
174     case '0':
175     break;
176     case '1':
177     val += 1;
178     break;
179     case '2':
180     val += 2;
181     break;
182     case '3':
183     val += 3;
184     break;
185     case '4':
186     val += 4;
187     break;
188     case '5':
189     val += 5;
190     break;
191     case '6':
192     val += 6;
193     break;
194     case '7':
195     val += 7;
196     break;
197     case '8':
198     val += 8;
199     break;
200     case '9':
201     val += 9;
202     break;
203     default:
204     return -1;
205     }
206     if (val<pval) /* check for overflow */
207     return -1;
208     }
209    
210     *num = val;
211     return 0;
212     }
213    
214    
215     extern int str_to_ushort(char const * str, unsigned short * num)
216     {
217     unsigned int pos;
218     unsigned int i;
219     unsigned short val;
220     unsigned short pval;
221    
222     if (!str || !num)
223     return -1;
224     for (pos=0; str[pos]==' ' || str[pos]=='\t'; pos++);
225     if (str[pos]=='+')
226     pos++;
227    
228     val = 0;
229     for (i=pos; str[i]!='\0'; i++)
230     {
231     pval = val;
232     val *= 10;
233     if (val/10!=pval) /* check for overflow */
234     return -1;
235    
236     pval = val;
237     switch (str[i])
238     {
239     case '0':
240     break;
241     case '1':
242     val += 1;
243     break;
244     case '2':
245     val += 2;
246     break;
247     case '3':
248     val += 3;
249     break;
250     case '4':
251     val += 4;
252     break;
253     case '5':
254     val += 5;
255     break;
256     case '6':
257     val += 6;
258     break;
259     case '7':
260     val += 7;
261     break;
262     case '8':
263     val += 8;
264     break;
265     case '9':
266     val += 9;
267     break;
268     default:
269     return -1;
270     }
271     if (val<pval) /* check for overflow */
272     return -1;
273     }
274    
275     *num = val;
276     return 0;
277     }
278    
279    
280     /* This routine assumes ASCII like control chars.
281     If len is zero, it will print all characters up to the first NUL,
282     otherwise it will print exactly that many characters. */
283     int str_print_term(FILE * fp, char const * str, unsigned int len, int allow_nl)
284     {
285     unsigned int i;
286    
287     if (!fp)
288     return -1;
289     if (!str)
290     return -1;
291    
292     if (len==0)
293     len = strlen(str);
294     for (i=0; i<len; i++)
295     if ((str[i]=='\177' || (str[i]>='\000' && str[i]<'\040')) &&
296     (!allow_nl || (str[i]!='\r' && str[i]!='\n')))
297     fprintf(fp,"^%c",str[i]+64);
298     else
299     fputc((int)str[i],fp);
300    
301     return 0;
302     }
303    
304    
305     extern int str_get_bool(char const * str)
306     {
307     if (!str)
308     return -1;
309    
310     if (strcasecmp(str,"true")==0 ||
311     strcasecmp(str,"yes")==0 ||
312     strcasecmp(str,"on")==0 ||
313     strcmp(str,"1")==0)
314     return 1;
315    
316     if (strcasecmp(str,"false")==0 ||
317     strcasecmp(str,"no")==0 ||
318     strcasecmp(str,"off")==0 ||
319     strcmp(str,"0")==0)
320     return 0;
321    
322     return -1;
323     }
324    
325    
326     extern char const * seconds_to_timestr(unsigned int totsecs)
327     {
328     static char temp[256];
329     int days;
330     int hours;
331     int minutes;
332     int seconds;
333    
334     days = totsecs/(24*60*60);
335     hours = totsecs/(60*60) - days*24;
336     minutes = totsecs/60 - days*24*60 - hours*60;
337     seconds = totsecs - days*24*60*60 - hours*60*60 - minutes*60;
338    
339     if (days>0)
340     sprintf(temp,"%d day%s %d hour%s %d minute%s %d second%s",
341     days,days==1 ? "" : "s",
342     hours,hours==1 ? "" : "s",
343     minutes,minutes==1 ? "" : "s",
344     seconds,seconds==1 ? "" : "s");
345     else if (hours>0)
346     sprintf(temp,"%d hour%s %d minute%s %d second%s",
347     hours,hours==1 ? "" : "s",
348     minutes,minutes==1 ? "" : "s",
349     seconds,seconds==1 ? "" : "s");
350     else if (minutes>0)
351     sprintf(temp,"%d minute%s %d second%s",
352     minutes,minutes==1 ? "" : "s",
353     seconds,seconds==1 ? "" : "s");
354     else
355     sprintf(temp,"%d second%s.",
356     seconds,seconds==1 ? "" : "s");
357    
358     return temp;
359     }
360    
361    
362     extern int clockstr_to_seconds(char const * clockstr, unsigned int * totsecs)
363     {
364     unsigned int i,j;
365     unsigned int temp;
366    
367     if (!clockstr)
368     return -1;
369     if (!totsecs)
370     return -1;
371    
372     for (i=j=temp=0; j<strlen(clockstr); j++)
373     {
374     switch (clockstr[j])
375     {
376     case ':':
377     temp *= 60;
378     temp += strtoul(&clockstr[i],NULL,10);
379     i = j+1;
380     break;
381     case '0':
382     case '1':
383     case '2':
384     case '3':
385     case '4':
386     case '5':
387     case '6':
388     case '7':
389     case '8':
390     case '9':
391     break;
392     default:
393     return -1;
394     }
395     }
396     if (i<j)
397     {
398     temp *= 60;
399     temp += strtoul(&clockstr[i],NULL,10);
400     }
401    
402     *totsecs = temp;
403     return 0;
404     }
405    
406    
407     extern char * escape_fs_chars(char const * in, unsigned int len)
408     {
409     char * out;
410     unsigned int inpos;
411     unsigned int outpos;
412    
413     if (!in)
414     return NULL;
415     out = xmalloc(len*3+1); /* if all turn into %XX */
416    
417     for (inpos=0,outpos=0; inpos<len; inpos++)
418     {
419     if (in[inpos]=='\0' || in[inpos]=='%' || in[inpos]=='/' ||
420     in[inpos]=='\\' || in[inpos]==':') /* FIXME: what other characters does Windows not allow? */
421     {
422     out[outpos++] = '%';
423     /* always 00 through FF hex */
424     sprintf(&out[outpos],"%02X",(unsigned int)(unsigned char)in[inpos]);
425     outpos += 2;
426     }
427     else
428     out[outpos++] = in[inpos];
429     }
430     /* if outpos >= len*3+1 then the buffer was overflowed */
431     out[outpos] = '\0';
432    
433     return out;
434     }
435    
436    
437     extern char * escape_chars(char const * in, unsigned int len)
438     {
439     char * out;
440     unsigned int inpos;
441     unsigned int outpos;
442    
443     if (!in)
444     return NULL;
445     out = xmalloc(len*4+1); /* if all turn into \xxx */
446    
447     for (inpos=0,outpos=0; inpos<len; inpos++)
448     {
449     if (in[inpos]=='\\')
450     {
451     out[outpos++] = '\\';
452     out[outpos++] = '\\';
453     }
454     else if (in[inpos]=='"')
455     {
456     out[outpos++] = '\\';
457     out[outpos++] = '"';
458     }
459     else if (isascii((int)in[inpos]) && isprint((int)in[inpos]))
460     out[outpos++] = in[inpos];
461     else if (in[inpos]=='\a')
462     {
463     out[outpos++] = '\\';
464     out[outpos++] = 'a';
465     }
466     else if (in[inpos]=='\b')
467     {
468     out[outpos++] = '\\';
469     out[outpos++] = 'b';
470     }
471     else if (in[inpos]=='\t')
472     {
473     out[outpos++] = '\\';
474     out[outpos++] = 't';
475     }
476     else if (in[inpos]=='\n')
477     {
478     out[outpos++] = '\\';
479     out[outpos++] = 'n';
480     }
481     else if (in[inpos]=='\v')
482     {
483     out[outpos++] = '\\';
484     out[outpos++] = 'v';
485     }
486     else if (in[inpos]=='\f')
487     {
488     out[outpos++] = '\\';
489     out[outpos++] = 'f';
490     }
491     else if (in[inpos]=='\r')
492     {
493     out[outpos++] = '\\';
494     out[outpos++] = 'r';
495     }
496     else
497     {
498     out[outpos++] = '\\';
499     /* always 001 through 377 octal */
500     sprintf(&out[outpos],"%03o",(unsigned int)(unsigned char)in[inpos]);
501     outpos += 3;
502     }
503     }
504     /* if outpos >= len*4+1 then the buffer was overflowed */
505     out[outpos] = '\0';
506    
507     return out;
508     }
509    
510    
511     extern char * unescape_chars(char const * in)
512     {
513     char * out;
514     unsigned int inpos;
515     unsigned int outpos;
516     unsigned int inlen;
517    
518     if (!in)
519     return NULL;
520    
521     inlen = strlen(in);
522     out = xmalloc(inlen+1);
523    
524     for (inpos=0,outpos=0; inpos<inlen; inpos++)
525     {
526     if (in[inpos]!='\\')
527     out[outpos++] = in[inpos];
528     else
529     switch (in[++inpos])
530     {
531     case '\\':
532     out[outpos++] = '\\';
533     break;
534     case '"':
535     out[outpos++] = '"';
536     break;
537     case 'a':
538     out[outpos++] = '\a';
539     break;
540     case 'b':
541     out[outpos++] = '\b';
542     break;
543     case 't':
544     out[outpos++] = '\t';
545     break;
546     case 'n':
547     out[outpos++] = '\n';
548     break;
549     case 'v':
550     out[outpos++] = '\v';
551     break;
552     case 'f':
553     out[outpos++] = '\f';
554     break;
555     case 'r':
556     out[outpos++] = '\r';
557     break;
558     default:
559     {
560     char temp[4];
561     unsigned int i;
562     unsigned int num;
563    
564     for (i=0; i<3; i++)
565     {
566     if (in[inpos]!='0' &&
567     in[inpos]!='1' &&
568     in[inpos]!='2' &&
569     in[inpos]!='3' &&
570     in[inpos]!='4' &&
571     in[inpos]!='5' &&
572     in[inpos]!='6' &&
573     in[inpos]!='7')
574     break;
575     temp[i] = in[inpos++];
576     }
577     temp[i] = '\0';
578     inpos--;
579    
580     num = strtoul(temp,NULL,8);
581     if (i<3 || num<1 || num>255) /* bad escape (including \000), leave it as-is */
582     {
583     out[outpos++] = '\\';
584     strcpy(&out[outpos],temp);
585     outpos += strlen(temp);
586     }
587     else
588     out[outpos++] = (unsigned char)num;
589     }
590     }
591     }
592     out[outpos] = '\0';
593    
594     return out;
595     }
596    
597    
598     extern void str_to_hex(char * target, char * data, int datalen)
599     {
600     unsigned char c;
601     int i;
602     for (i = 0; i < datalen; i++)
603     {
604     c = (data[i]) & 0xff;
605    
606     sprintf(target + i*3, "%02X ", c);
607     target[i*3+3] = '\0';
608    
609     /* fprintf(stderr, "str_to_hex %d | '%02x' '%s'\n", i, c, target); */
610     }
611     }
612    
613    
614     extern int hex_to_str(char const * source, char * data, int datalen)
615     {
616     /*
617     * TODO: We really need a more robust function here,
618     * for now, I'll just use this hack for a quick evaluation
619     */
620     char byte;
621     char c;
622     int i;
623    
624     for (i = 0; i < datalen; i++)
625     {
626     byte = 0;
627    
628     /* fprintf(stderr, "hex_to_str %d | '%02x'", i, byte); */
629    
630     c = source [i*3 + 0];
631     byte += 16 * ( c > '9' ? (c - 'A' + 10) : (c - '0'));
632    
633     /* fprintf(stderr, " | '%c' '%02x'", c, byte); */
634    
635     c = source [i*3 + 1];
636     byte += 1 * ( c > '9' ? (c - 'A' + 10) : (c - '0'));
637    
638     /* fprintf(stderr, " | '%c' '%02x'", c, byte); */
639    
640     /* fprintf(stderr, "\n"); */
641    
642     data[i] = byte;
643     }
644    
645     /* fprintf(stderr, "finished, returning %d from '%s'\n", i, source); */
646    
647     return i;
648     }
649    
650     extern char * buildpath(char const *root, const char *suffix)
651     {
652     char *result;
653    
654     result = (char*) xmalloc(strlen(root) + 1 + strlen(suffix) + 1);
655    
656     strcpy(result,root); strcat(result,"/"); strcat(result,suffix);
657     return result;
658     }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1