[9089] | 1 | #ifndef lint |
---|
| 2 | #define _NOTICE static char |
---|
| 3 | _NOTICE N1[] = "Copyright (c) 1992 Adobe Systems Incorporated"; |
---|
| 4 | _NOTICE N2[] = "GOVERNMENT END USERS: See Notice file in TranScript library directory"; |
---|
| 5 | _NOTICE N3[] = "-- probably /usr/lib/ps/Notice"; |
---|
| 6 | _NOTICE RCSID[]="$Header: /afs/dev.mit.edu/source/repository/third/transcript/src/psfax.c,v 1.1.1.1 1996-10-07 20:25:51 ghudson Exp $"; |
---|
| 7 | #endif |
---|
| 8 | /* psfax.c |
---|
| 9 | * |
---|
| 10 | * Copyright (C) 1992 Adobe Systems Incorporated. All |
---|
| 11 | * rights reserved. |
---|
| 12 | * GOVERNMENT END USERS: See Notice file in TranScript library directory |
---|
| 13 | * -- probably /usr/lib/ps/Notice |
---|
| 14 | * |
---|
| 15 | * $Log: not supported by cvs2svn $ |
---|
| 16 | * Revision 1.10 1993/11/22 21:28:44 snichols |
---|
| 17 | * only process list of keys once, and keep the zero'th entry of |
---|
| 18 | * faxopts for common keys on multicast; start multicast entries at 1. |
---|
| 19 | * |
---|
| 20 | * Revision 1.9 1993/05/18 21:37:48 snichols |
---|
| 21 | * fixed memory-smasher on Sparcs. |
---|
| 22 | * |
---|
| 23 | * Revision 1.8 1992/10/15 22:12:32 snichols |
---|
| 24 | * should be opening output file for writing, not reading. |
---|
| 25 | * |
---|
| 26 | * Revision 1.7 1992/08/21 16:26:32 snichols |
---|
| 27 | * Release 4.0 |
---|
| 28 | * |
---|
| 29 | * Revision 1.6 1992/07/14 22:00:50 snichols |
---|
| 30 | * Added copyright |
---|
| 31 | * |
---|
| 32 | */ |
---|
| 33 | #include <stdio.h> |
---|
| 34 | #ifdef XPG3 |
---|
| 35 | #include <stdlib.h> |
---|
| 36 | #else |
---|
| 37 | #include "compat.h" |
---|
| 38 | #endif |
---|
| 39 | #include <string.h> |
---|
| 40 | #include <sys/wait.h> |
---|
| 41 | |
---|
| 42 | #include "transcript.h" |
---|
| 43 | #include "config.h" |
---|
| 44 | |
---|
| 45 | #define TRUE 1 |
---|
| 46 | #define FALSE 0 |
---|
| 47 | |
---|
| 48 | |
---|
| 49 | extern char *optarg; |
---|
| 50 | extern int optind; |
---|
| 51 | |
---|
| 52 | extern char *lp; |
---|
| 53 | |
---|
| 54 | char list[100][50]; /* holder for parsing keys in list */ |
---|
| 55 | int numlist=0; |
---|
| 56 | |
---|
| 57 | FILE *db, *doc, *output; |
---|
| 58 | |
---|
| 59 | char *dbfile = NULL; |
---|
| 60 | char defdbfile[255]; |
---|
| 61 | char *infile = NULL; |
---|
| 62 | char *outfile = NULL; |
---|
| 63 | char *printername = NULL; |
---|
| 64 | char *dialcallee; |
---|
| 65 | char *toname; |
---|
| 66 | |
---|
| 67 | int fdin, fdout; |
---|
| 68 | |
---|
| 69 | struct entry{ |
---|
| 70 | char option[128]; |
---|
| 71 | char value[256]; |
---|
| 72 | int filename; |
---|
| 73 | }; |
---|
| 74 | |
---|
| 75 | struct listopts { |
---|
| 76 | int numopts; /* number of options for this entry */ |
---|
| 77 | int maxopts; /* number allocated */ |
---|
| 78 | struct entry **opts; /* list of options */ |
---|
| 79 | } **faxopts; /* a list, for multicast */ |
---|
| 80 | /* if not multicast, all options are in the |
---|
| 81 | zero'th entry; if multicast, zero'th |
---|
| 82 | entry contains the options in common |
---|
| 83 | among all the recipients */ |
---|
| 84 | |
---|
| 85 | int numfaxopts = 1; /* number of faxopts entries */ |
---|
| 86 | int maxfaxopts = 1; /* number allocated */ |
---|
| 87 | int multicast = FALSE; |
---|
| 88 | int sendps = FALSE; |
---|
| 89 | int usedb = TRUE; |
---|
| 90 | int treatasstrings=TRUE; |
---|
| 91 | |
---|
| 92 | char *comopts[20]; /* options from command line */ |
---|
| 93 | int ncomopts = 0; |
---|
| 94 | |
---|
| 95 | typedef enum {string, integer, boolean, procedure, arrayint, |
---|
| 96 | arraydict} valueTypes; |
---|
| 97 | #define NUMOPTS 30 |
---|
| 98 | |
---|
| 99 | struct _optionTypes { /* table for outputting various options */ |
---|
| 100 | char *name; |
---|
| 101 | valueTypes valueType; |
---|
| 102 | char *begin; |
---|
| 103 | char *end; |
---|
| 104 | } optionTypes[NUMOPTS] = { |
---|
| 105 | { "nooptionstr", string, "(", ")" }, |
---|
| 106 | { "nooptionlit", integer, "", "" }, |
---|
| 107 | { "DialCallee", string, "(", ")" }, |
---|
| 108 | { "RecipientName", string, "(", ")" }, |
---|
| 109 | { "RecipientPhone", string, "(", ")" }, |
---|
| 110 | { "RecipientOrg", string, "(", ")" }, |
---|
| 111 | { "RecipientMailStop", string, "(", ")" }, |
---|
| 112 | { "RecipientID", string, "(", ")" }, |
---|
| 113 | { "SenderName", string, "(", ")" }, |
---|
| 114 | { "SenderPhone", string, "(", ")" }, |
---|
| 115 | { "SenderOrg", string, "(", ")" }, |
---|
| 116 | { "SenderMailStop", string, "(", ")" }, |
---|
| 117 | { "SenderID", string, "(", ")" }, |
---|
| 118 | { "CallerID", string, "(", ")" }, |
---|
| 119 | { "CalleePhone", string, "(", ")" }, |
---|
| 120 | { "CallerPhone", string, "(", ")" }, |
---|
| 121 | { "FaxType", integer, "", "" }, |
---|
| 122 | { "ErrorCorrect", boolean, "", "" }, |
---|
| 123 | { "TrimWhite", boolean, "", "" }, |
---|
| 124 | { "PageCaption", procedure, "{", "}" }, |
---|
| 125 | { "MaxRetries", integer, "", "" }, |
---|
| 126 | { "RetryInterval", integer, "", "" }, |
---|
| 127 | { "MailingTime", arrayint, "[", "]" }, |
---|
| 128 | { "CoverSheet", procedure, "{", "}" }, |
---|
| 129 | { "Confirmation", procedure, "{", "}" }, |
---|
| 130 | { "nPages", integer, "", "" }, |
---|
| 131 | { "CoverSheetOnly", boolean, "", "" }, |
---|
| 132 | { "RevertToRaster", boolean, "", "" }, |
---|
| 133 | { "PostScriptPassword", string, "(", ")" }, |
---|
| 134 | { "Copies", arraydict, "[", "]" } |
---|
| 135 | }; |
---|
| 136 | |
---|
| 137 | /* forward dec'ls */ |
---|
| 138 | |
---|
| 139 | static struct listopts *NewFaxOpt(); |
---|
| 140 | static void AddOption(); |
---|
| 141 | static int FindOption(); |
---|
| 142 | static void HandleGroup(); |
---|
| 143 | static int FindEntry(); |
---|
| 144 | |
---|
| 145 | static char *myrealloc(ptr, size) |
---|
| 146 | char *ptr; |
---|
| 147 | int size; |
---|
| 148 | { |
---|
| 149 | char *ret; |
---|
| 150 | |
---|
| 151 | if (ptr == NULL) return malloc(size); |
---|
| 152 | ret = (char *)realloc(ptr, (unsigned) size); |
---|
| 153 | if (ret) return ret; |
---|
| 154 | fprintf(stderr, "realloc failed\n"); |
---|
| 155 | exit(1); |
---|
| 156 | return NULL; |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | static void HandleCommandLineOptions(opt) |
---|
| 160 | char *opt; |
---|
| 161 | { |
---|
| 162 | char *option, *value; |
---|
| 163 | |
---|
| 164 | option = opt; |
---|
| 165 | value = strchr(option, '='); |
---|
| 166 | if (value) { |
---|
| 167 | *value = '\0'; |
---|
| 168 | value++; |
---|
| 169 | AddOption(0, option, value, 0); |
---|
| 170 | } |
---|
| 171 | else { |
---|
| 172 | value = strchr(option, ':'); |
---|
| 173 | if (value) { |
---|
| 174 | *value = '\0'; |
---|
| 175 | value++; |
---|
| 176 | AddOption(0, option, value, 1); |
---|
| 177 | } |
---|
| 178 | } |
---|
| 179 | } |
---|
| 180 | |
---|
| 181 | static int LookupOpt(opt) |
---|
| 182 | char *opt; |
---|
| 183 | { |
---|
| 184 | int i; |
---|
| 185 | |
---|
| 186 | for (i = 0; i < NUMOPTS; i++) { |
---|
| 187 | if (strcmp(opt, optionTypes[i].name) == 0) |
---|
| 188 | return i; |
---|
| 189 | } |
---|
| 190 | if (treatasstrings) |
---|
| 191 | return 0; |
---|
| 192 | else |
---|
| 193 | return 1; |
---|
| 194 | } |
---|
| 195 | |
---|
| 196 | static void DumpOpts(out) |
---|
| 197 | FILE *out; |
---|
| 198 | { |
---|
| 199 | int i,j; |
---|
| 200 | FILE *fp; |
---|
| 201 | char buf[1024]; |
---|
| 202 | int ndex; |
---|
| 203 | |
---|
| 204 | for (j = 0; j < faxopts[0]->numopts; j++) { |
---|
| 205 | ndex = LookupOpt(faxopts[0]->opts[j]->option); |
---|
| 206 | if (faxopts[0]->opts[j]->filename) { |
---|
| 207 | if ((fp = fopen(faxopts[0]->opts[j]->value, "r")) == NULL) { |
---|
| 208 | fprintf(stderr, "Couldn't open file %s\n", |
---|
| 209 | faxopts[0]->opts[j]->value); |
---|
| 210 | exit(1); |
---|
| 211 | } |
---|
| 212 | fprintf(out, "/%s ", faxopts[0]->opts[j]->option); |
---|
| 213 | fprintf(out, "%s\n",optionTypes[ndex].begin); |
---|
| 214 | while (fgets(buf, 1024, fp)) |
---|
| 215 | fputs(buf, out); |
---|
| 216 | fprintf(out, "%s def\n", optionTypes[ndex].end); |
---|
| 217 | } |
---|
| 218 | else { |
---|
| 219 | fprintf(out, "/%s %s%s%s def\n", faxopts[0]->opts[j]->option, |
---|
| 220 | optionTypes[ndex].begin, faxopts[0]->opts[j]->value, |
---|
| 221 | optionTypes[ndex].end); |
---|
| 222 | } |
---|
| 223 | } |
---|
| 224 | if (multicast) { |
---|
| 225 | /* build copies array */ |
---|
| 226 | fprintf(out, "/Copies [\n"); |
---|
| 227 | for (i = 1; i < numfaxopts; i++) { |
---|
| 228 | if (i > 1) fprintf(out, "\n"); |
---|
| 229 | fprintf(out, "<<"); |
---|
| 230 | for (j = 0; j < faxopts[i]->numopts; j++) { |
---|
| 231 | if (j > 0) fprintf(out, "\n"); |
---|
| 232 | ndex = LookupOpt(faxopts[i]->opts[j]->option); |
---|
| 233 | if (faxopts[i]->opts[j]->filename) { |
---|
| 234 | if ((fp = fopen(faxopts[i]->opts[j]->value, "r")) == |
---|
| 235 | NULL) { |
---|
| 236 | fprintf(stderr, "Couldn't open file %s\n", |
---|
| 237 | faxopts[i]->opts[j]->value); |
---|
| 238 | exit(1); |
---|
| 239 | } |
---|
| 240 | fprintf(out, "/%s %s\n", faxopts[i]->opts[j]->option, |
---|
| 241 | optionTypes[ndex].begin); |
---|
| 242 | while (fgets(buf, 1024, fp)) |
---|
| 243 | fputs(buf, out); |
---|
| 244 | fprintf(out, "%s", optionTypes[ndex].end); |
---|
| 245 | } |
---|
| 246 | else { |
---|
| 247 | fprintf(out, "/%s %s%s%s", |
---|
| 248 | faxopts[i]->opts[j]->option, |
---|
| 249 | optionTypes[ndex].begin, |
---|
| 250 | faxopts[i]->opts[j]->value, |
---|
| 251 | optionTypes[ndex].end); |
---|
| 252 | } |
---|
| 253 | } |
---|
| 254 | fprintf(out, ">>\n"); |
---|
| 255 | } |
---|
| 256 | fprintf(out, "] def\n"); |
---|
| 257 | } |
---|
| 258 | } |
---|
| 259 | |
---|
| 260 | static void DumpPS(out) |
---|
| 261 | FILE *out; |
---|
| 262 | { |
---|
| 263 | |
---|
| 264 | fprintf(out, "currentfile %d dict dup begin\n", |
---|
| 265 | faxopts[0]->numopts+multicast+5); |
---|
| 266 | DumpOpts(out); |
---|
| 267 | fprintf(out, "end\n"); |
---|
| 268 | fprintf(out, "/FaxOps /ProcSet findresource /faxsendps get exec\n"); |
---|
| 269 | } |
---|
| 270 | |
---|
| 271 | static void DumpFax(out) |
---|
| 272 | FILE *out; |
---|
| 273 | { |
---|
| 274 | |
---|
| 275 | fprintf(out, "2 dict dup begin /OutputDevice (Fax) def\n"); |
---|
| 276 | fprintf(out, "/FaxOptions %d dict dup begin\n", |
---|
| 277 | faxopts[0]->numopts+multicast+5); |
---|
| 278 | DumpOpts(out); |
---|
| 279 | fprintf(out, "end def end setpagedevice\n"); |
---|
| 280 | } |
---|
| 281 | |
---|
| 282 | static void HandleList(s) |
---|
| 283 | char *s; |
---|
| 284 | { |
---|
| 285 | char *p, *q; |
---|
| 286 | |
---|
| 287 | p = s; |
---|
| 288 | while (*p == ' ') p++; |
---|
| 289 | |
---|
| 290 | q = p; |
---|
| 291 | while ((p = strchr(q, ',')) != NULL) { |
---|
| 292 | *p = '\0'; p++; |
---|
| 293 | while (*p == ' ') p++; |
---|
| 294 | strcpy(list[numlist++], q); |
---|
| 295 | q = p; |
---|
| 296 | } |
---|
| 297 | /* get last one */ |
---|
| 298 | strcpy(list[numlist++], q); |
---|
| 299 | } |
---|
| 300 | |
---|
| 301 | #define ARGS "P:k:d:f:s:p:n:tlc" |
---|
| 302 | |
---|
| 303 | main(argc, argv) |
---|
| 304 | int argc; |
---|
| 305 | char **argv; |
---|
| 306 | { |
---|
| 307 | char *key; |
---|
| 308 | char *p; |
---|
| 309 | char c; |
---|
| 310 | int i; |
---|
| 311 | char buf[1024]; |
---|
| 312 | int cnt; |
---|
| 313 | int dumped = FALSE; |
---|
| 314 | int fdpipe[2]; |
---|
| 315 | int spid; |
---|
| 316 | int status; |
---|
| 317 | char *tmp; |
---|
| 318 | |
---|
| 319 | while ((c = getopt(argc, argv, ARGS)) != EOF) { |
---|
| 320 | switch (c) { |
---|
| 321 | case 'k': |
---|
| 322 | key = optarg; |
---|
| 323 | if ((p = strchr(key, ',')) != NULL) { |
---|
| 324 | /* list of keys */ |
---|
| 325 | HandleList(key); |
---|
| 326 | key = NULL; |
---|
| 327 | } |
---|
| 328 | break; |
---|
| 329 | case 'f': |
---|
| 330 | dbfile = optarg; |
---|
| 331 | break; |
---|
| 332 | case 'd': |
---|
| 333 | /* DialCallee string */ |
---|
| 334 | dialcallee = optarg; |
---|
| 335 | break; |
---|
| 336 | case 'S': |
---|
| 337 | comopts[ncomopts++] = optarg; |
---|
| 338 | break; |
---|
| 339 | case 't': |
---|
| 340 | sendps = TRUE; |
---|
| 341 | break; |
---|
| 342 | case 'c': |
---|
| 343 | usedb = FALSE; |
---|
| 344 | break; |
---|
| 345 | case 'n': |
---|
| 346 | toname = optarg; |
---|
| 347 | break; |
---|
| 348 | case 'l': |
---|
| 349 | treatasstrings = FALSE; |
---|
| 350 | break; |
---|
| 351 | case 'P': |
---|
| 352 | printername = optarg; |
---|
| 353 | break; |
---|
| 354 | case 'p': |
---|
| 355 | outfile = optarg; |
---|
| 356 | break; |
---|
| 357 | } |
---|
| 358 | } |
---|
| 359 | |
---|
| 360 | if (argc > optind) |
---|
| 361 | infile = argv[optind]; |
---|
| 362 | else infile = NULL; |
---|
| 363 | faxopts = (struct listopts **)malloc(sizeof(struct listopts *)); |
---|
| 364 | faxopts[0] = (struct listopts *)NewFaxOpt(); |
---|
| 365 | if (usedb) { |
---|
| 366 | if (dbfile == NULL) { |
---|
| 367 | tmp = getenv("PSFAXDB"); |
---|
| 368 | if (tmp) { |
---|
| 369 | dbfile = tmp; |
---|
| 370 | } |
---|
| 371 | else { |
---|
| 372 | tmp = getenv("HOME"); |
---|
| 373 | if (tmp) { |
---|
| 374 | strcpy(defdbfile, tmp); |
---|
| 375 | strcat(defdbfile, "/.faxdb"); |
---|
| 376 | dbfile = defdbfile; |
---|
| 377 | } |
---|
| 378 | } |
---|
| 379 | } |
---|
| 380 | if ((db = fopen(dbfile, "r")) == NULL) { |
---|
| 381 | fprintf(stderr, "psfax: couldn't open fax database file %s.\n", |
---|
| 382 | dbfile); |
---|
| 383 | exit(1); |
---|
| 384 | } |
---|
| 385 | FindEntry(0, "always"); |
---|
| 386 | if (key) { |
---|
| 387 | if (!FindEntry(0, key)) { |
---|
| 388 | fprintf(stderr, "psfax: couldn't find entry for %s.\n", key); |
---|
| 389 | exit(1); |
---|
| 390 | } |
---|
| 391 | } |
---|
| 392 | } |
---|
| 393 | if (dialcallee) |
---|
| 394 | AddOption(0, "DialCallee", dialcallee, 0); |
---|
| 395 | if (toname) |
---|
| 396 | AddOption(0, "RecipientName", toname, 0); |
---|
| 397 | |
---|
| 398 | for (i = 0; i < ncomopts; i++) |
---|
| 399 | HandleCommandLineOptions(comopts[i]); |
---|
| 400 | |
---|
| 401 | if (numlist > 0) |
---|
| 402 | HandleGroup(); |
---|
| 403 | |
---|
| 404 | if (FindOption(0, "DialCallee") == -1) { |
---|
| 405 | if (!multicast) { |
---|
| 406 | fprintf(stderr, "psfax: Must specify DialCallee field!\n"); |
---|
| 407 | exit(1); |
---|
| 408 | } |
---|
| 409 | else { |
---|
| 410 | for (i = 1; i < numfaxopts; i++) { |
---|
| 411 | if (FindOption(i, "DialCallee") == -1) { |
---|
| 412 | fprintf(stderr, "psfax: Must specify DialCallee field!\n"); |
---|
| 413 | exit(1); |
---|
| 414 | } |
---|
| 415 | } |
---|
| 416 | } |
---|
| 417 | } |
---|
| 418 | |
---|
| 419 | if (sendps && FindOption(0, "PostScriptPassword") == -1) { |
---|
| 420 | fprintf(stderr, |
---|
| 421 | "psfax: password may be required when sending PostScript.\n"); |
---|
| 422 | } |
---|
| 423 | else doc = stdin; |
---|
| 424 | if (printername && !outfile) { |
---|
| 425 | /* set up pipe to spooler */ |
---|
| 426 | if (pipe(fdpipe)) { |
---|
| 427 | fprintf(stderr, "psfax: pipe to lpr failed.\n"); |
---|
| 428 | exit(1); |
---|
| 429 | } |
---|
| 430 | if ((spid = fork()) < 0) { |
---|
| 431 | fprintf(stderr, "psfax: fork failed.\n"); |
---|
| 432 | exit(1); |
---|
| 433 | } |
---|
| 434 | if (spid == 0) { |
---|
| 435 | /* child process */ |
---|
| 436 | if (close(0) || (dup(fdpipe[0]) != 0) || close(fdpipe[0]) || |
---|
| 437 | close(fdpipe[1])) { |
---|
| 438 | fprintf(stderr, "psfax: child failed.\n"); |
---|
| 439 | exit(1); |
---|
| 440 | } |
---|
| 441 | sprintf(buf, "-P%s", printername); |
---|
| 442 | execlp(lp, lp, buf, (char *) 0); |
---|
| 443 | fprintf(stderr, "psfax: exec of %s failed\n", lp); |
---|
| 444 | exit(1); |
---|
| 445 | } |
---|
| 446 | /* parent */ |
---|
| 447 | if (close(1) || (dup(fdpipe[1]) != 1) || close(fdpipe[0]) || |
---|
| 448 | close(fdpipe[1])) { |
---|
| 449 | fprintf(stderr, "psfax: parent failed.\n"); |
---|
| 450 | exit(1); |
---|
| 451 | } |
---|
| 452 | if ((output = fdopen(1, "w")) == NULL) { |
---|
| 453 | fprintf(stderr, "psfax: error opening pipe.\n"); |
---|
| 454 | exit(1); |
---|
| 455 | } |
---|
| 456 | } |
---|
| 457 | else { |
---|
| 458 | if (outfile) { |
---|
| 459 | if ((output = fopen(outfile, "w")) == NULL) { |
---|
| 460 | fprintf(stderr, |
---|
| 461 | "psfax: couldn't open output file %s.\n", outfile); |
---|
| 462 | exit(1); |
---|
| 463 | } |
---|
| 464 | } |
---|
| 465 | else output = stdout; |
---|
| 466 | } |
---|
| 467 | if (infile) { |
---|
| 468 | if ((doc = fopen(infile, "r")) == NULL) { |
---|
| 469 | fprintf(stderr, "psfax: couldn't open input file %s.\n", infile); |
---|
| 470 | exit(1); |
---|
| 471 | } |
---|
| 472 | } |
---|
| 473 | fgets(buf, 1024, doc); |
---|
| 474 | if (strncmp(buf, "%!", 2) != 0) { |
---|
| 475 | fprintf(stderr, "psfax: input is not PostScript file.\n"); |
---|
| 476 | exit(1); |
---|
| 477 | } |
---|
| 478 | fputs(buf, output); |
---|
| 479 | if (sendps) |
---|
| 480 | DumpPS(output); |
---|
| 481 | else |
---|
| 482 | DumpFax(output); |
---|
| 483 | while (fgets(buf, 1024, doc)) |
---|
| 484 | fputs(buf, output); |
---|
| 485 | fclose(output); |
---|
| 486 | wait(&status); |
---|
| 487 | } |
---|
| 488 | |
---|
| 489 | static struct entry *NewEntry() |
---|
| 490 | { |
---|
| 491 | struct entry *a; |
---|
| 492 | unsigned size; |
---|
| 493 | |
---|
| 494 | size = sizeof(struct entry); |
---|
| 495 | a = (struct entry *)malloc(size); |
---|
| 496 | if (a) { |
---|
| 497 | return a; |
---|
| 498 | } |
---|
| 499 | else { |
---|
| 500 | fprintf(stderr, "Error in malloc!"); |
---|
| 501 | perror(""); |
---|
| 502 | exit(1); |
---|
| 503 | } |
---|
| 504 | } |
---|
| 505 | |
---|
| 506 | static struct listopts *NewFaxOpt() |
---|
| 507 | { |
---|
| 508 | struct listopts *ptr; |
---|
| 509 | |
---|
| 510 | ptr = (struct listopts *)malloc(sizeof(struct listopts)); |
---|
| 511 | ptr->numopts = 0; |
---|
| 512 | ptr->maxopts = 0; |
---|
| 513 | ptr->opts = NULL; |
---|
| 514 | return ptr; |
---|
| 515 | } |
---|
| 516 | |
---|
| 517 | |
---|
| 518 | static void AddOption(ndex, option, value, name) |
---|
| 519 | int ndex; |
---|
| 520 | char *option; |
---|
| 521 | char *value; |
---|
| 522 | int name; |
---|
| 523 | { |
---|
| 524 | /* if option is already in list, replace with new value; |
---|
| 525 | else, add to list. */ |
---|
| 526 | int i; |
---|
| 527 | |
---|
| 528 | for (i = 0; i < faxopts[ndex]->numopts; i++) { |
---|
| 529 | if (!strcmp(faxopts[ndex]->opts[i]->option, option)) { |
---|
| 530 | strncpy(faxopts[ndex]->opts[i]->value, value, 256); |
---|
| 531 | faxopts[ndex]->opts[i]->filename = name; |
---|
| 532 | return; |
---|
| 533 | } |
---|
| 534 | } |
---|
| 535 | if (faxopts[ndex]->numopts >= faxopts[ndex]->maxopts) { |
---|
| 536 | /* need more space, get 20 more */ |
---|
| 537 | faxopts[ndex]->opts = |
---|
| 538 | (struct entry **)myrealloc((char *) faxopts[ndex]->opts, |
---|
| 539 | (faxopts[ndex]->maxopts * |
---|
| 540 | sizeof(struct entry *) + |
---|
| 541 | 20*sizeof(struct entry *))); |
---|
| 542 | faxopts[ndex]->maxopts += 20; |
---|
| 543 | } |
---|
| 544 | faxopts[ndex]->opts[faxopts[ndex]->numopts] = NewEntry(); |
---|
| 545 | strncpy(faxopts[ndex]->opts[faxopts[ndex]->numopts]->option, option, 128); |
---|
| 546 | strncpy(faxopts[ndex]->opts[faxopts[ndex]->numopts]->value, value, 256); |
---|
| 547 | faxopts[ndex]->opts[faxopts[ndex]->numopts]->filename = name; |
---|
| 548 | faxopts[ndex]->numopts++; |
---|
| 549 | } |
---|
| 550 | |
---|
| 551 | static int FindOption(ndex, str) |
---|
| 552 | int ndex; |
---|
| 553 | char *str; |
---|
| 554 | { |
---|
| 555 | int i; |
---|
| 556 | |
---|
| 557 | for (i = 0; i < faxopts[ndex]->numopts; i++) { |
---|
| 558 | if (strcmp(str, faxopts[ndex]->opts[i]->option) == 0) { |
---|
| 559 | return i; |
---|
| 560 | } |
---|
| 561 | } |
---|
| 562 | return -1;; |
---|
| 563 | } |
---|
| 564 | |
---|
| 565 | static void HandleOption(ndex, line) |
---|
| 566 | int ndex; |
---|
| 567 | char *line; |
---|
| 568 | { |
---|
| 569 | char *p; |
---|
| 570 | char *q; |
---|
| 571 | int filename = FALSE; |
---|
| 572 | char *ptr; |
---|
| 573 | |
---|
| 574 | p = strchr(line, '='); |
---|
| 575 | if (p == NULL) { |
---|
| 576 | p = strchr(line, ':'); |
---|
| 577 | if (p == NULL) { |
---|
| 578 | fprintf(stderr, "readfdb: ill-formed option line %s\n", line); |
---|
| 579 | exit(1); |
---|
| 580 | } |
---|
| 581 | filename = TRUE; |
---|
| 582 | } |
---|
| 583 | *p = '\0'; |
---|
| 584 | p++; |
---|
| 585 | while (*p == ' ') p++; |
---|
| 586 | if (line[0] == '/') { |
---|
| 587 | /* special keyword */ |
---|
| 588 | q = line; |
---|
| 589 | q++; |
---|
| 590 | if (strcmp(q, "list") == 0) { |
---|
| 591 | /* list of users */ |
---|
| 592 | } |
---|
| 593 | multicast = TRUE; |
---|
| 594 | q = p; |
---|
| 595 | while ((p = strchr(q, ',')) != NULL) { |
---|
| 596 | *p = '\0'; p++; |
---|
| 597 | while (*p == ' ') p++; |
---|
| 598 | strcpy(list[numlist++], q); |
---|
| 599 | q = p; |
---|
| 600 | } |
---|
| 601 | /* get last one */ |
---|
| 602 | strcpy(list[numlist++], q); |
---|
| 603 | } |
---|
| 604 | else { |
---|
| 605 | AddOption(ndex, line, p, filename); |
---|
| 606 | } |
---|
| 607 | } |
---|
| 608 | |
---|
| 609 | static int MatchKey(line, key) |
---|
| 610 | char *line, *key; |
---|
| 611 | { |
---|
| 612 | char *p, *q; |
---|
| 613 | int foundit = FALSE; |
---|
| 614 | |
---|
| 615 | if (strcmp(line, key) == 0) |
---|
| 616 | return TRUE; |
---|
| 617 | q = line; |
---|
| 618 | while ((p = strchr(q, '|')) != NULL) { |
---|
| 619 | *p = '\0'; p++; |
---|
| 620 | if (strcmp(q, key) == 0) { |
---|
| 621 | return TRUE; |
---|
| 622 | } |
---|
| 623 | q = p; |
---|
| 624 | } |
---|
| 625 | if (strcmp(q, key) == 0) |
---|
| 626 | return TRUE; |
---|
| 627 | return FALSE; |
---|
| 628 | } |
---|
| 629 | |
---|
| 630 | static char *myfgets(buf, cnt, fp) |
---|
| 631 | char *buf; |
---|
| 632 | int cnt; |
---|
| 633 | FILE *fp; |
---|
| 634 | { |
---|
| 635 | char *ret; |
---|
| 636 | char *p; |
---|
| 637 | |
---|
| 638 | ret = fgets(buf, cnt, fp); |
---|
| 639 | |
---|
| 640 | if (ret) { |
---|
| 641 | p = strchr(buf, '\n'); |
---|
| 642 | if (p) *p = '\0'; |
---|
| 643 | } |
---|
| 644 | return ret; |
---|
| 645 | } |
---|
| 646 | |
---|
| 647 | static void HandleGroup() |
---|
| 648 | { |
---|
| 649 | int i; |
---|
| 650 | |
---|
| 651 | rewind(db); |
---|
| 652 | multicast = FALSE; /* for now, to avoid confusing FindEntry */ |
---|
| 653 | for (i = 0; i < numlist; i++) { |
---|
| 654 | if (numfaxopts >= maxfaxopts) { |
---|
| 655 | faxopts = |
---|
| 656 | (struct listopts **) myrealloc((char *)faxopts, |
---|
| 657 | (maxfaxopts * |
---|
| 658 | sizeof(struct listopts *) + |
---|
| 659 | 5*sizeof(struct listopts |
---|
| 660 | *))); |
---|
| 661 | maxfaxopts += 5; |
---|
| 662 | } |
---|
| 663 | faxopts[numfaxopts] = (struct listopts *) NewFaxOpt(); |
---|
| 664 | if (!FindEntry(numfaxopts, list[i])) { |
---|
| 665 | fprintf(stderr, "Couldn't find entry for group member %s.\n", |
---|
| 666 | list[i]); |
---|
| 667 | exit(1); |
---|
| 668 | } |
---|
| 669 | numfaxopts++; |
---|
| 670 | rewind(db); |
---|
| 671 | } |
---|
| 672 | multicast = TRUE; /* to notify DumpOptions */ |
---|
| 673 | } |
---|
| 674 | |
---|
| 675 | static int FindEntry(ndex, key) |
---|
| 676 | int ndex; |
---|
| 677 | char *key; |
---|
| 678 | { |
---|
| 679 | char buf[1024]; |
---|
| 680 | int match = FALSE; |
---|
| 681 | char *p, *q; |
---|
| 682 | |
---|
| 683 | while (myfgets(buf, 1024, db)) { |
---|
| 684 | if (buf[0] == '%') |
---|
| 685 | continue; |
---|
| 686 | p = strchr(buf, '\n'); |
---|
| 687 | if (p) *p = '\0'; |
---|
| 688 | if (MatchKey(buf, key)) { |
---|
| 689 | while (myfgets(buf, 1024, db)) { |
---|
| 690 | if (buf[0] == '%') |
---|
| 691 | continue; |
---|
| 692 | if (buf[0] == '.') { |
---|
| 693 | return TRUE; |
---|
| 694 | } |
---|
| 695 | HandleOption(ndex, buf); |
---|
| 696 | } |
---|
| 697 | } |
---|
| 698 | else { |
---|
| 699 | while (myfgets(buf, 1024, db)) { |
---|
| 700 | if (buf[0] == '.') |
---|
| 701 | break; |
---|
| 702 | } |
---|
| 703 | } |
---|
| 704 | } |
---|
| 705 | return FALSE; |
---|
| 706 | } |
---|
| 707 | |
---|
| 708 | |
---|