|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <string.h> ! 3: #include <malloc.h> ! 4: #include <pwd.h> ! 5: ! 6: #define OPTS "a:m:o:q:wxyDSVdef:mpr#" ! 7: #define MAILX "/bin/mail" ! 8: #define UPDATE path("update") ! 9: #define DBINFO path("dbinfo") ! 10: #define DELPAP "del=p" ! 11: #define ALLYES "all=y" ! 12: #define ASKYES "ask=y" ! 13: ! 14: #define PREMA(e) printf("%s%s", e, yflg ? ", " : "\n") ! 15: #define PRMULT(m, p) PREMA(m[*m[EMAIL] && !p ? EMAIL : PAPER]) ! 16: ! 17: #define WHO 0 ! 18: #define EMAIL 1 ! 19: #define PAPER 2 ! 20: #define NARGS 3 ! 21: #define MULT 10 ! 22: ! 23: typedef char *strings[512]; ! 24: typedef char buffer[BUFSIZ]; ! 25: ! 26: char usage[] = "usage:\ ! 27: post [-a attr] [-m mods] [-o fmt] [-q query]\n\ ! 28: [-w] [mail options] [addresses...]\n\ ! 29: [-D] [-S] [-V]\n"; ! 30: ! 31: strings qdef; ! 32: strings postattr; ! 33: buffer postofmt; ! 34: int postetc; ! 35: int wflg, xflg, yflg; ! 36: int askyes = 0; ! 37: int exitval = 0; ! 38: char *mult[MULT][NARGS]; ! 39: char *pq; ! 40: void resolve(); ! 41: ! 42: extern char emp_fmt[], ema_fmt[], who_fmt[]; ! 43: extern char emp_def[], emp_seq[], emp_uni[]; ! 44: extern char *pq_open(); ! 45: extern char *getenv(), *strdup(); ! 46: struct passwd *getpwnam(); ! 47: ! 48: char *ofmt = emp_fmt, *attr = emp_def, *mods = "", *qopt = ""; ! 49: ! 50: main(argc, argv) ! 51: int argc; ! 52: char *argv[]; ! 53: { ! 54: extern char *optarg; ! 55: extern int optind; ! 56: strings args; ! 57: buffer buf; ! 58: char **ap = args; ! 59: int c; ! 60: ! 61: *ap++ = argv[0]; ! 62: ! 63: while ((c = getopt(argc, argv, OPTS)) != EOF) ! 64: switch (c) { ! 65: case 'a': ! 66: attr = optarg; ! 67: break; ! 68: case 'm': ! 69: mods = optarg; ! 70: break; ! 71: case 'o': ! 72: ofmt = optarg; ! 73: break; ! 74: case 'q': ! 75: qopt = optarg; ! 76: break; ! 77: case 'w': ! 78: wflg++; ! 79: break; ! 80: case 'x': ! 81: xflg++; ! 82: break; ! 83: case 'y': ! 84: yflg++; ! 85: break; ! 86: case 'D': ! 87: execvp(DBINFO, argv); ! 88: perror(DBINFO); ! 89: return 1; ! 90: case 'S': ! 91: execvp(UPDATE, argv); ! 92: perror(UPDATE); ! 93: return 1; ! 94: case 'V': ! 95: puts("research post 4.0 9/1/88"); ! 96: return 1; ! 97: case '?': ! 98: fputs(usage, stderr); ! 99: return 1; ! 100: default: ! 101: sprintf(*ap++ = malloc(3), "-%c", c); ! 102: if (optarg) ! 103: *ap++ = optarg; ! 104: } ! 105: ! 106: if (!wflg && !xflg && !yflg) { ! 107: while (optind < argc) ! 108: *ap++ = argv[optind++]; ! 109: *ap++ = 0; ! 110: execv(MAILX, args); ! 111: perror(MAILX); ! 112: return 1; ! 113: } ! 114: if (xflg || yflg) { ! 115: strcpy(buf, ofmt); ! 116: strcat(buf, ema_fmt); ! 117: ofmt = buf; ! 118: } ! 119: ! 120: postetc = !!getenv("POSTETC"); ! 121: strvec(attr, postattr, "/:"); ! 122: fmtcomp(postofmt, ofmt, qdef); ! 123: smerge(getenv("POSTQUAL"), qdef); ! 124: smerge(qopt, qdef); ! 125: ! 126: if (option(ASKYES, qdef)) ! 127: askyes++; ! 128: if (xflg || yflg) ! 129: smerge(emp_uni, qdef); ! 130: ! 131: if (wflg && optind == argc) ! 132: argv[argc++] = ""; ! 133: while (optind < argc) { ! 134: resolve(argv[optind++]); ! 135: if (yflg) ! 136: putchar('\n'); ! 137: } ! 138: if (pq && pq_close(pq) == -1) ! 139: pqerr("pq"); ! 140: return yflg ? 0 : exitval; ! 141: } ! 142: ! 143: void ! 144: resolve(name) ! 145: char *name; ! 146: { ! 147: strings q, n, rec; ! 148: int delpap, allyes; ! 149: int c, r; ! 150: char *p; ! 151: buffer out; ! 152: ! 153: p = strpbrk(name, "!@%/:="); ! 154: if (*name && strchr("+|", *name) || p && !strchr("/:=", *p) ! 155: || !p && !strpbrk(name, "._") && postetc && getpwnam(name)) { ! 156: PREMA(name); ! 157: return; ! 158: } ! 159: ! 160: if (!dodef(name, n, postattr)) { ! 161: eomatch(0, 0, 0, name); ! 162: return; ! 163: } ! 164: for (c = 0; q[c] = qdef[c]; c++); ! 165: merge(n, q); ! 166: delpap = option(DELPAP, q); ! 167: allyes = option(ALLYES, q); ! 168: if (option(ASKYES, q)) ! 169: askyes++; ! 170: ! 171: c = 0; ! 172: if ((r = pqowrite(q)) != -1) { ! 173: while ((r = pq_read(pq, rec)) > 0) { ! 174: fmtexec(out, postofmt, rec); ! 175: if (match(c++, out, delpap, allyes, name, q)) ! 176: return; ! 177: } ! 178: if (r == -1) ! 179: pqerr(name); ! 180: } else ! 181: pqerr(name); ! 182: ! 183: if (c == 0 && r == 0) ! 184: fprintf(stderr, "post: %s: Not found\n", name); ! 185: eomatch(c, delpap, allyes, name); ! 186: } ! 187: ! 188: dodef(name, vars, defs) ! 189: char *name; ! 190: strings vars, defs; ! 191: { ! 192: static buffer tmp, buf; ! 193: register char *bp = buf; ! 194: register int m, i, c; ! 195: ! 196: strcpy(tmp, name); ! 197: strvec(tmp, vars, "/:"); ! 198: for (m = 0; defs[m]; m++); ! 199: ! 200: for (i = 0; vars[i]; i++) ! 201: if (!strchr(vars[i], '=')) ! 202: if (i < m) { ! 203: c = sprintf(bp, "%s=%s", defs[i], vars[i]); ! 204: vars[i] = bp; ! 205: bp += c + 1; ! 206: } else { ! 207: fprintf(stderr, "post: %s: %s: No attribute\n", ! 208: name, vars[i]); ! 209: return 0; ! 210: } ! 211: return 1; ! 212: } ! 213: ! 214: match(c, out, delpap, allyes, name, q) ! 215: int c; ! 216: char *out; ! 217: int delpap, allyes; ! 218: char *name; ! 219: strings q; ! 220: { ! 221: buffer buf; ! 222: int i, m = c % MULT; ! 223: char *s; ! 224: ! 225: if (wflg) { ! 226: fputs(out, stdout); ! 227: return 0; ! 228: } ! 229: ! 230: s = strdup(out); ! 231: for (i = 0; i < NARGS && (mult[m][i] = s); i++) ! 232: if (s = strchr(s, '|')) ! 233: *s++ = 0; ! 234: skname(mult[m][PAPER]); ! 235: if (s = strchr(mult[m][EMAIL], '(')) ! 236: if (xflg) ! 237: *--s = 0; ! 238: else ! 239: prname(s); ! 240: ! 241: if (allyes) { ! 242: if (xflg) { ! 243: PRMULT(mult[m], delpap); ! 244: return 0; ! 245: } ! 246: if (yflg) { ! 247: s = buf; ! 248: s += sprintf(s, "!"); ! 249: for (i = 0; q[i]; i++) ! 250: if (strchr(q[i], '=') && strcmp(q[i], emp_uni)) ! 251: s += sprintf(s, "%s:", q[i]); ! 252: if (delpap) ! 253: s += sprintf(s, "%s:", DELPAP); ! 254: strcpy(s, ALLYES); ! 255: PREMA(buf); ! 256: return 1; ! 257: } ! 258: } ! 259: if (++m < MULT) ! 260: return 0; ! 261: return session(c, m, delpap, name); ! 262: } ! 263: ! 264: eomatch(c, delpap, allyes, name) ! 265: int c, delpap, allyes; ! 266: char *name; ! 267: { ! 268: if (wflg || (xflg && allyes && c > 0)) ! 269: return 1; ! 270: if (c == 1) { ! 271: PRMULT(mult[0], delpap); ! 272: return 1; ! 273: } ! 274: session(c, c % MULT, delpap, name); ! 275: } ! 276: ! 277: session(c, m, delpap, name) ! 278: int c, m, delpap; ! 279: char *name; ! 280: { ! 281: strings addr; ! 282: buffer ans; ! 283: int i; ! 284: ! 285: if (c > 0 && c < MULT) ! 286: fprintf(stderr, "post: %s: Ambiguous\n", name); ! 287: for (i = 0; i < m; i++) ! 288: fprintf(stderr, "%d %s\n", i, mult[i][WHO]); ! 289: if (xflg || !isatty(0)) ! 290: exit(1); ! 291: ! 292: for (;;) { ! 293: fprintf(stderr, "Which one? ["); ! 294: if (m > 0) ! 295: fprintf(stderr, "0-%d, ", m-1); ! 296: if (m == MULT) ! 297: fprintf(stderr, "CR(more), "); ! 298: fprintf(stderr, "o(mit), new address(es), q(uit)] "); ! 299: ! 300: if (!fgets(ans, sizeof ans, stdin)) ! 301: exit(1); ! 302: ans[strlen(ans)-1] = 0; ! 303: if (strlen(ans) <= 1) ! 304: switch (*ans) { ! 305: case 'o': ! 306: return 1; ! 307: case 'q': ! 308: exit(1); ! 309: case 0: ! 310: if (m == MULT) ! 311: return 0; ! 312: else ! 313: continue; ! 314: default: ! 315: i = *ans - '0'; ! 316: if (i >= 0 && i < m) { ! 317: PRMULT(mult[i], delpap); ! 318: return 1; ! 319: } ! 320: } ! 321: ! 322: strvec(ans, addr, " \t\n"); ! 323: for (i = 0; addr[i]; i++) ! 324: resolve(addr[i]); ! 325: return 1; ! 326: } ! 327: } ! 328: ! 329: merge(qs, qd) ! 330: strings qs, qd; ! 331: { ! 332: int i, j, l, m; ! 333: char *s; ! 334: ! 335: for (l = m = 0; qd[l]; l++, m++); ! 336: for (i = 0; qs[i]; i++) { ! 337: for (j = 0; j < l; j++) ! 338: if ((s = strchr(qd[j], '=')) ! 339: && !strncmp(qs[i], qd[j], s-qd[j]+1)) { ! 340: qd[j--] = qd[--l]; ! 341: qd[l] = qd[--m]; ! 342: } ! 343: qd[m++] = qs[i]; ! 344: } ! 345: qd[m] = 0; ! 346: } ! 347: ! 348: smerge(s, qd) ! 349: char *s; ! 350: strings qd; ! 351: { ! 352: strings qs; ! 353: ! 354: if (s) { ! 355: strvec(s, qs, "/:"); ! 356: merge(qs, qd); ! 357: } ! 358: } ! 359: ! 360: option(a, q) ! 361: char *a; ! 362: strings q; ! 363: { ! 364: char *s = strchr(a, '='); ! 365: int i, m, rv = 0; ! 366: ! 367: for (m = 0; q[m]; m++); ! 368: for (i = 0; i < m; i++) ! 369: if (!strncmp(q[i], a, s-a+1)) { ! 370: if (!strncmp(q[i], a, strlen(a))) ! 371: rv++; ! 372: q[i--] = q[--m]; ! 373: } ! 374: q[m] = 0; ! 375: return rv; ! 376: } ! 377: ! 378: pqowrite(q) ! 379: strings q; ! 380: { ! 381: static tried = 0; ! 382: strings argv; ! 383: ! 384: if (!tried++) { ! 385: strvec(mods, argv, " \t\n"); ! 386: pq = pq_open(argv); ! 387: } ! 388: return pq ? pq_write(pq, q) : -1; ! 389: } ! 390: ! 391: pqerr(msg) ! 392: char *msg; ! 393: { ! 394: extern char pq_error[]; ! 395: fprintf(stderr, "post: %s: %s\n", msg, pq_error); ! 396: exitval++; ! 397: } ! 398: ! 399: prname(s) ! 400: char *s; ! 401: { ! 402: for (; *s; s++) ! 403: if (*s == '_') { ! 404: if (s[1] == '_') ! 405: *s++ = ','; ! 406: *s = ' '; ! 407: } ! 408: } ! 409: ! 410: skname(s) ! 411: char *s; ! 412: { ! 413: char *ns; ! 414: ! 415: for (ns = s; *s; s++) ! 416: if (*s != ' ' && *s != '\'') ! 417: *ns++ = *s; ! 418: *ns = 0; ! 419: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.