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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
no message

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