|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: #include "mail.h" ! 4: #include "string.h" ! 5: ! 6: /* imports */ ! 7: extern char *malloc(); ! 8: extern char *realloc(); ! 9: extern void exit(); ! 10: ! 11: /* global to this file */ ! 12: #define STRLEN 128 ! 13: #define STRALLOC 128 ! 14: #define MAXINCR 250000 ! 15: ! 16: /* buffer pool for allocating string structures */ ! 17: typedef struct { ! 18: string s[STRALLOC]; ! 19: int o; ! 20: } stralloc; ! 21: static stralloc *freep=NULL; ! 22: ! 23: /* pool of freed strings */ ! 24: static string *freed=NULL; ! 25: ! 26: void ! 27: s_free(sp) ! 28: string *sp; ! 29: { ! 30: if (sp != NULL) { ! 31: sp->ptr = (char *)freed; ! 32: freed = sp; ! 33: } ! 34: } ! 35: ! 36: /* allocate a string head */ ! 37: static string * ! 38: s_alloc() { ! 39: if (freep==NULL || freep->o >= STRALLOC) { ! 40: freep = (stralloc *)malloc(sizeof(stralloc)); ! 41: if (freep==NULL) { ! 42: perror("allocating string"); ! 43: exit(1); ! 44: } ! 45: freep->o = 0; ! 46: } ! 47: return &(freep->s[freep->o++]); ! 48: } ! 49: ! 50: /* create a new `short' string */ ! 51: extern string * ! 52: s_new() ! 53: { ! 54: string *sp; ! 55: ! 56: if (freed!=NULL) { ! 57: sp = freed; ! 58: freed = (string *)(freed->ptr); ! 59: sp->ptr = sp->base; ! 60: return sp; ! 61: } ! 62: sp = s_alloc(); ! 63: sp->base = sp->ptr = malloc(STRLEN); ! 64: if (sp->base == NULL) { ! 65: perror("allocating string"); ! 66: exit(1); ! 67: } ! 68: sp->end = sp->base + STRLEN; ! 69: s_terminate(sp); ! 70: return sp; ! 71: } ! 72: ! 73: /* grow a string's allocation by at least `incr' bytes */ ! 74: extern int ! 75: s_simplegrow(sp, incr) ! 76: string *sp; ! 77: int incr; ! 78: { ! 79: char *cp; ! 80: int size; ! 81: ! 82: /* ! 83: * take a larger increment to avoid mallocing too often ! 84: */ ! 85: if((sp->end-sp->base) < incr && MAXINCR < incr) ! 86: size = (sp->end-sp->base) + incr; ! 87: else if((sp->end-sp->base) > MAXINCR) ! 88: size = (sp->end-sp->base)+MAXINCR; ! 89: else ! 90: size = 2*(sp->end-sp->base); ! 91: ! 92: cp = realloc(sp->base, size); ! 93: if (cp == NULL) { ! 94: perror("string:"); ! 95: exit(1); ! 96: } ! 97: sp->ptr = (sp->ptr - sp->base) + cp; ! 98: sp->end = cp + size; ! 99: sp->base = cp; ! 100: } ! 101: ! 102: /* grow a string's allocation */ ! 103: extern int ! 104: s_grow(sp, c) ! 105: string *sp; ! 106: int c; ! 107: { ! 108: s_simplegrow(sp, 2); ! 109: s_putc(sp, c); ! 110: return c; ! 111: } ! 112: ! 113: /* return a string containing a character array (this had better not grow) */ ! 114: string * ! 115: s_array(cp, len) ! 116: char *cp; ! 117: int len; ! 118: { ! 119: string *sp = s_alloc(); ! 120: ! 121: sp->base = sp->ptr = cp; ! 122: sp->end = sp->base + len; ! 123: return sp; ! 124: } ! 125: ! 126: /* return a string containing a copy of the passed char array */ ! 127: extern string* ! 128: s_copy(cp) ! 129: char *cp; ! 130: { ! 131: string *sp; ! 132: int len; ! 133: ! 134: sp = s_alloc(); ! 135: len = strlen(cp)+1; ! 136: sp->base = malloc(len); ! 137: if (sp->base == NULL) { ! 138: perror("string:"); ! 139: exit(1); ! 140: } ! 141: sp->end = sp->base + len; /* point past end of allocation */ ! 142: strcpy(sp->base, cp); ! 143: sp->ptr = sp->end - 1; /* point to NULL terminator */ ! 144: return sp; ! 145: } ! 146: ! 147: /* convert string to lower case */ ! 148: extern int ! 149: s_tolower(sp) ! 150: string *sp; ! 151: { ! 152: char *cp; ! 153: ! 154: for(cp=sp->ptr; *cp; cp++) ! 155: if(isupper(*cp)) ! 156: *cp = tolower(*cp); ! 157: } ! 158: ! 159: /* append a char array to a string */ ! 160: extern string * ! 161: s_append(to, from) ! 162: register string *to; ! 163: register char *from; ! 164: { ! 165: int want, have; ! 166: ! 167: if (to == NULL) ! 168: to = s_new(); ! 169: if (from == NULL) ! 170: return to; ! 171: for(; *from; from++) ! 172: s_putc(to, *from); ! 173: s_terminate(to); ! 174: return to; ! 175: } ! 176: ! 177: /* append a char array ( of up to n characters) to a string */ ! 178: extern string * ! 179: s_nappend(to, from, n) ! 180: register string *to; ! 181: register char *from; ! 182: { ! 183: int want, have; ! 184: ! 185: if (to == NULL) ! 186: to = s_new(); ! 187: if (from == NULL) ! 188: return to; ! 189: for(; *from && n; from++, n--) ! 190: s_putc(to, *from); ! 191: s_terminate(to); ! 192: return to; ! 193: } ! 194: ! 195: /* Append a logical input sequence into a string. Ignore blank and ! 196: * comment lines. Backslash preceding newline indicates continuation. ! 197: * The `lineortoken' variable indicates whether the sequence to beinput ! 198: * is a whitespace delimited token or a whole line. ! 199: * ! 200: * Returns a pointer to the string (or NULL). Trailing newline is stripped off. ! 201: */ ! 202: extern string * ! 203: s_seq_read(fp, to, lineortoken) ! 204: FILE *fp; /* stream to read from */ ! 205: string *to; /* where to put token */ ! 206: int lineortoken; /* how the sequence terminates */ ! 207: { ! 208: register int c; ! 209: int done=0; ! 210: ! 211: if(feof(fp)) ! 212: return NULL; ! 213: ! 214: /* get rid of leading goo */ ! 215: do { ! 216: c = getc(fp); ! 217: switch(c) { ! 218: case EOF: ! 219: if (to != NULL) ! 220: s_terminate(to); ! 221: return NULL; ! 222: case '#': ! 223: while((c = getc(fp)) != '\n' && c != EOF); ! 224: break; ! 225: case ' ': ! 226: case '\t': ! 227: case '\n': ! 228: case '\r': ! 229: case '\f': ! 230: break; ! 231: default: ! 232: done = 1; ! 233: break; ! 234: } ! 235: } while (!done); ! 236: ! 237: if (to == NULL) ! 238: to = s_new(); ! 239: ! 240: /* gather up a sequence */ ! 241: for (;;) { ! 242: switch(c) { ! 243: case '\\': ! 244: c = getc(fp); ! 245: if (c != '\n') { ! 246: s_putc(to, '\\'); ! 247: s_putc(to, c); ! 248: } ! 249: break; ! 250: case EOF: ! 251: case '\r': ! 252: case '\f': ! 253: case '\n': ! 254: s_terminate(to); ! 255: return to; ! 256: case ' ': ! 257: case '\t': ! 258: if (lineortoken == TOKEN) { ! 259: s_terminate(to); ! 260: return to; ! 261: } ! 262: /* fall through */ ! 263: default: ! 264: s_putc(to, c); ! 265: break; ! 266: } ! 267: c = getc(fp); ! 268: } ! 269: } ! 270: ! 271: /* Append an input line to a string. ! 272: * ! 273: * Returns a pointer to the string (or NULL). ! 274: * Trailing newline is left on. ! 275: */ ! 276: extern char * ! 277: s_read_line(fp, to) ! 278: register FILE *fp; ! 279: register string *to; ! 280: { ! 281: register int c; ! 282: register int len=0; ! 283: ! 284: s_terminate(to); ! 285: ! 286: /* end of input */ ! 287: if (feof(fp) || (c=getc(fp)) == EOF) ! 288: return NULL; ! 289: ! 290: /* gather up a line */ ! 291: for(;;) { ! 292: len++; ! 293: switch(c) { ! 294: case EOF: ! 295: s_terminate(to); ! 296: return to->ptr-len; ! 297: case '\n': ! 298: s_putc(to, '\n'); ! 299: s_terminate(to); ! 300: return to->ptr-len; ! 301: default: ! 302: s_putc(to, c); ! 303: break; ! 304: } ! 305: c=getc(fp); ! 306: } ! 307: } ! 308: ! 309: /* ! 310: * Read till eof or some limit is passed. If the limit is passed, ! 311: * return a negative counr. ! 312: */ ! 313: extern int ! 314: s_read_to_lim(fp, to, lim) ! 315: register FILE *fp; ! 316: register string *to; ! 317: int lim; ! 318: { ! 319: register int c; ! 320: register int got; ! 321: register int have; ! 322: ! 323: s_terminate(to); ! 324: ! 325: for(;;){ ! 326: if(lim && to->ptr - to->base > lim){ ! 327: s_terminate(to); ! 328: return -(to->ptr - to->base); ! 329: } ! 330: if(feof(fp)) ! 331: break; ! 332: /* allocate room for a full buffer */ ! 333: have = to->end - to->ptr; ! 334: if(have<4096) ! 335: s_simplegrow(to, 4096); ! 336: ! 337: /* get a buffers worth */ ! 338: have = to->end - to->ptr; ! 339: got = fread(to->ptr, 1, have, fp); ! 340: if(got<=0) ! 341: break; ! 342: to->ptr += got; ! 343: } ! 344: ! 345: /* null terminate the line */ ! 346: s_terminate(to); ! 347: return to->ptr - to->base; ! 348: } ! 349: ! 350: /* ! 351: * read to eof ! 352: */ ! 353: extern int ! 354: s_read_to_eof(fp, to) ! 355: register FILE *fp; ! 356: register string *to; ! 357: { ! 358: return s_read_to_lim(fp, to, 0); ! 359: } ! 360: ! 361: /* Get the next field from a string. The field is delimited by white space, ! 362: * single or double quotes. ! 363: */ ! 364: extern string * ! 365: s_parse(from, to) ! 366: string *from; /* string to parse */ ! 367: string *to; /* where to put parsed token */ ! 368: { ! 369: while (isspace(*from->ptr)) ! 370: from->ptr++; ! 371: if (*from->ptr == '\0') ! 372: return NULL; ! 373: if (to == NULL) ! 374: to = s_new(); ! 375: if (*from->ptr == '\'') { ! 376: from->ptr++; ! 377: for (;*from->ptr != '\'' && *from->ptr != '\0'; from->ptr++) ! 378: s_putc(to, *from->ptr); ! 379: if (*from->ptr == '\'') ! 380: from->ptr++; ! 381: } else if (*from->ptr == '"') { ! 382: from->ptr++; ! 383: for (;*from->ptr != '"' && *from->ptr != '\0'; from->ptr++) ! 384: s_putc(to, *from->ptr); ! 385: if (*from->ptr == '"') ! 386: from->ptr++; ! 387: } else { ! 388: for (;!isspace(*from->ptr) && *from->ptr != '\0'; from->ptr++) ! 389: s_putc(to, *from->ptr); ! 390: } ! 391: s_terminate(to); ! 392: ! 393: return to; ! 394: } ! 395:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.