00001
00009 load_path += ";/afs/athena/user/c/a/cat/project/vt/hacks;/mit/dmaze/vtc";
00010 Load("rmtio");
00011 Load("disp");
00012 Load("cquote");
00013 Load("fquote");
00014 Load("filter");
00015 Load("shell");
00016 Load("bimap");
00017 Load("color");
00018 line_numbers = 1;
00019 default_pager_state = 0;
00020 zfieldregex = regcomp("^([0-9]+): (.*)$");
00021 rndseed(time);
00022
00023 Load("zephyr-core");
00024 Load("zaway");
00025 Load("zclassmap");
00026 Load("zdefout");
00027 Load("zformat");
00028 Load("zpunt");
00029 Load("zreplay");
00030 Load("zsend");
00031 Load("zsend-zcrypt");
00032 Load("zsend-zwrite");
00033 Load("zsig-random");
00034 Load("zsig-responses");
00035 Load("zsig-t");
00036 Load("zwindow");
00037
00045 func zauth_letter(z)
00046 {
00047 if (is_webzephyr(z))
00048 return '&';
00049 else if (stricmp(z->auth, "yes") == 0)
00050 {
00051 if (stricmp(z->opcode, "crypt") == 0)
00052 return '*';
00053 else
00054 return'+';
00055 }
00056 else if (stricmp(z->auth, "no") == 0)
00057 return '-';
00058 else if (stricmp(z->auth, "forged") == 0)
00059 return '?';
00060 else
00061 return ' ';
00062 }
00063
00071 func should_wrap(body) [count, indent, do_wrap, s]
00072 {
00073 indent = -1;
00074 do_wrap = 1;
00075 for (s = explode(body, "\n") + 1; *s; s++)
00076 {
00077 count = 0;
00078 for (; **s == ' ' || **s == '\t'; (*s)++)
00079 count++;
00080 if (indent == -1)
00081 {
00082 indent = count;
00083 }
00084 else if (count - indent > 1 || count - indent < -1)
00085 {
00086 do_wrap = 0;
00087 break;
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00096 return do_wrap;
00097 }
00098
00106 func zephyr_output() [z, line, fields, i, s, p, ival, cval, do_wrap,
00107 annot, win, body, sig, pipe, style, auth2, front,
00108 wz]
00109 {
00110
00111 z = cur_rmt->zephyr;
00112 cur_rmt->zephyr = new_zgram();
00113
00114
00115 zapply(.chop, z);
00116
00117
00118 fields = alloc(z->numfields);
00119 for (i = 0; i < z->numfields; ++i)
00120 {
00121 fields[i] = chop(z->fields[i] ?: "");
00122 }
00123
00124
00125 line = bprintf("%s\n%s\n%s\n{%s}\n<%s>\n[%s]\n%s:",
00126 z->fromhost, z->ztime, z->auth, z->opcode,
00127 z->class, z->instance, z->sender);
00128 for (i = 0; i < z->numfields; ++i)
00129 {
00130 line += "\n/\n" + fields[i];
00131 }
00132 add_hist(line, S_NORM);
00133
00134
00135
00136
00137 if (z->numfields == 2)
00138 {
00139 sig = fields[0];
00140 body = fields[1];
00141 }
00142 else
00143 {
00144 sig = "";
00145 body = "";
00146 for(i = 0; i < z->numfields; ++i)
00147 {
00148 body += fields[i];
00149 if (i != z->numfields - 1)
00150 body += " / ";
00151 }
00152 }
00153
00154
00155 zapply(.fold_newlines, z);
00156 zapply(.clean_string, z);
00157 sig = fold_newlines(sig);
00158 sig = clean_string(sig);
00159
00160
00161
00162 auth2 = zauth_letter(z);
00163
00164
00165 note_zsig_responses(z, sig);
00166
00167
00168 win = find_win(z);
00169
00170
00171
00172 do_wrap = should_wrap(body);
00173
00174
00175 style = style_of_zephyr(z);
00176
00177
00178 if (stricmp(z->opcode, "user_login") == 0)
00179 style = find_style("green");
00180 else if (stricmp(z->opcode, "user_logout") == 0)
00181 style = find_style("red");
00182 if (z->personal && (stricmp(z->class, "mail") != 0))
00183 style = S_HILITE;
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 cval = mapped_class(z->class);
00194 ival = mapped_instance(z->class, z->instance);
00195
00196 if (cval)
00197 s = bprintf("%s/%s", cval, z->instance);
00198 else
00199 s = bprintf("<%s>/%s", z->class, z->instance);
00200
00201
00202
00203 xrealm = 0;
00204 if (z->sender[strcspn(z->sender, "@")] != 0)
00205 xrealm = 1;
00206
00207
00208
00209
00210 if (is_noc(z))
00211 {
00212 front = bprintf("%c%22s %5s %12s ", auth2, z->sender,
00213 z->ztime, fields[1]);
00214 body = z->instance + ":";
00215 for (i = 2; i < z->numfields; i++)
00216 {
00217 body += " " + fields[i];
00218 }
00219 do_wrap = 1;
00220 }
00221 else if (is_wz_personal(z))
00222 {
00223 front = bprintf("%c%22s %5s %12s ", auth2, z->instance, z->ztime,
00224 "wz/...");
00225 }
00226 else
00227 {
00228 if (xrealm || is_rcmd(z))
00229 front = bprintf("%c%22s %5s ", auth2, z->sender, z->ztime);
00230 else
00231 front = bprintf("%c%8s %13s %5s ", auth2,
00232 z->sender, z->fromhost, z->ztime);
00233
00234 if (strlen(s) <= 12)
00235 front += bprintf("%12s ", s);
00236 else
00237 front += s + " ";
00238 }
00239
00240
00241 if (stricmp(z->class, "login") == 0)
00242 {
00243 front = bprintf("%c%8s %13s %5s %12s ", auth2,
00244 z->sender, z->fromhost, z->ztime, "");
00245 if (stricmp(z->opcode, "user_login") == 0)
00246 {
00247 body = "Logged in on ";
00248 }
00249 else if (stricmp(z->opcode, "user_logout") == 0)
00250 {
00251 body = "Logged out from ";
00252 }
00253 else
00254 {
00255 body = opcode + ": ";
00256 }
00257 body += fields[0];
00258 if (fields[2])
00259 body += " (" + fields[2] + ")";
00260 do_wrap = 1;
00261 sig = "";
00262 opcode = "";
00263 }
00264
00265
00266 if (is_noc(z))
00267 opcode = "";
00268 annot = ((*sig) ? "-- " + sig : "") + ((*sig && *(z->opcode)) ? " " : "") +
00269 ((*(z->opcode)) ? "{" + z->opcode + "}" : "");
00270 annot += ((*annot) ? " " : "") + bprintf("(%d)", lineno - 1);
00271
00272 line = make_line(front, body, annot, do_wrap);
00273
00274
00275 zaway_respond(z, sig);
00276
00277
00278 if (cur_rmt->logfile)
00279 {
00280 fwrite(cur_rmt->logfile, line);
00281 fflush(cur_rmt->logfile);
00282 }
00283
00284
00285 if (is_zpunted(z))
00286 return;
00287
00288
00289 if ((stricmp(z->class, "mail") == 0) && z->personal)
00290 {
00291 if (stristr(fields[1], "debian") && !stristr(fields[1], "dmaze@debian"))
00292 {
00293 return;
00294 }
00295 }
00296
00297 output(line, style, win);
00298 }
00299
00307 func is_rcmd(z) [sender2, n]
00308 {
00309 if (stricmp(z->sender, "rcmd.", 5) == 0)
00310 {
00311 sender2 = z->sender;
00312 sender2 += 5;
00313 n = strlen(sender2);
00314 if (stricmp(z->fromhost, sender2, n-1) == 0)
00315 {
00316 return 1;
00317 }
00318 }
00319
00320 return 0;
00321 }
00322
00331 func is_noc(z)
00332 {
00333 if (is_rcmd(z) &&
00334 stricmp(z->class, "noc") == 0 &&
00335 stricmp(z->opcode, "echo") == 0)
00336 return 1;
00337 return 0;
00338 }
00339
00346 func is_webzephyr(z)
00347 {
00348 if (stricmp(z->sender, "daemon.webzephyr") == 0)
00349 return 1;
00350 return 0;
00351 }
00352
00360 func is_wz_personal(z)
00361 {
00362 if (is_webzephyr(z) &&
00363 stricmp(z->class, "webzephyr") == 0 &&
00364 z->personal)
00365 return 1;
00366 return 0;
00367 }
00368
00380 func make_line(front, body, annot, do_wrap) [line, fbody, s, p, col, spaces]
00381 {
00382 line = front;
00383
00384
00385
00386 body = clean_string(body);
00387 if (do_wrap)
00388 {
00389 fbody = fold_newlines(body);
00390 line += wrap(fbody, cols - 1, 43, strlen(line));
00391 }
00392 else
00393 {
00394 s = explode(body, "\n") + 1;
00395 if (*s)
00396 {
00397
00398
00399
00400 if (strlen(front) <= 43)
00401 {
00402 line += wrap(*s, cols - 1, 43, strlen(front));
00403 if (s[1])
00404 line += bprintf("%43s", "");
00405 s++;
00406 }
00407 for (; *s; s++)
00408 {
00409 line += wrap(*s, cols - 1, 43, 43);
00410 if (s[1])
00411 line += bprintf("%43s", "");
00412 }
00413 }
00414 }
00415
00416 line[strlen(line) - 1] = 0;
00417 p = strrchr(line, '\n');
00418 col = (p) ? line + strlen(line) - (p + 1) : strlen(line);
00419 if (col + 1 + strlen(annot) > cols - 1)
00420 {
00421 line = bprintf("%s\n%43s%s", line, "",
00422 wrap(annot, cols - 1, 46, 43));
00423 }
00424 else
00425 {
00426 spaces = cols - 1 - (col + strlen(annot));
00427 line += cfield("", spaces) + annot + "\n";
00428 }
00429 return line;
00430 }
00431
00438 func zephyr_outbound(rmt, line) [zout]
00439 {
00440
00441
00442 if (zout_pipe)
00443 {
00444 zout = zout_pipe;
00445 if (strcmp(line, ".") != 0)
00446 {
00447
00448 zout->body += line + "\n";
00449 return;
00450 }
00451
00452 zout_pipe = NULL;
00453 }
00454 else
00455 {
00456 zout = outbound_parse(rmt, line);
00457 if (!zout) return;
00458 zout->body = softwrap(zout->body, 60);
00459 }
00460
00461
00462 if (zout && !zout_pipe)
00463 {
00464 generate_signature(zout);
00465 zout_send(zout);
00466 }
00467 }
00468 ZEPHYR->outbound = .zephyr_outbound;
00469
00473 func Nopipe()
00474 {
00475 zout_pipe = NULL;
00476 }
00477 add_cmd("nopipe", 0, .Nopipe, "/nopipe");
00478
00485 func generate_signature(zout)
00486 {
00487
00488 if (((!zout->class || (stricmp(zout->class, "message") == 0))) &&
00489 (zout->instance && (stricmp(zout->instance, "6.035", 5) == 0)))
00490 zout->sig = "Give me the brain...I forgot what lattice is.";
00491
00492 if (!zout->sig)
00493 zout->sig = get_zsig_response(zout->class, zout->instance);
00494
00495
00496
00497
00498
00499
00500
00501 if (!zout->sig)
00502 zout->sig = "Quantum singularity on the front stairs";
00503 }
00504
00505
00506 zreg1 = regcomp("^(>([^ ]+)) *(.*)$");
00507
00508
00509 zreg2 = regcomp("^(-([^ -][^ ]*)) *(.*)$");
00510
00511
00512 zreg3 = regcomp("^(<([^>]+)>/?([^ ]*)) *(.*)$");
00513
00514
00515 zreg4 = regcomp("^(([^/ ]*)/([^ ]*)) *(.*)$");
00516
00517
00518 zreg5 = regcomp("^(([^/ ]*)) *(.*)$");
00519
00520
00521 zreg6 = regcomp("^(&([^ ]+)) +(.*)$");
00522
00532 func outbound_parse(rmt, line) [multi, crypt, a, zout, ival,
00533 used_default_instance, default]
00534 {
00535
00536 multi = 0;
00537 crypt = 0;
00538
00539
00540 while (*line == ' ')
00541 line++;
00542
00543
00544 if (strchr(">-", *line) && line[1] == ' ')
00545 {
00546 default = get_default_recip(rmt);
00547 if (!default)
00548 {
00549 printf("No default set.\n");
00550 return;
00551 }
00552 if (*line == '>' && *default != '>')
00553 {
00554 printf("Default is not a personal.\n");
00555 return;
00556 }
00557 line = bprintf("%s%s", default, line + 1);
00558 }
00559
00560
00561 while(*line)
00562 {
00563 if (*line == '|')
00564 multi = 1;
00565 else if (*line == '*')
00566 crypt = 1;
00567 else
00568 break;
00569 line++;
00570 }
00571
00572
00573 if (!*line)
00574 return;
00575
00576
00577 zout = new_zoutgoing();
00578 if (crypt)
00579 zout->sender = .zsend_zcrypt;
00580 else
00581 zout->sender = .zsend_zwrite;
00582
00583
00584
00585
00586 if (regexec(zreg1, line))
00587 {
00588 a = regmatch_array(zreg1);
00589 zout->recip = a[2];
00590 zout->body = a[3];
00591 }
00592 else if (regexec(zreg2, line))
00593 {
00594 a = regmatch_array(zreg2);
00595 zout->instance = a[2];
00596 zout->body = a[3];
00597 }
00598 else if (regexec(zreg3, line))
00599 {
00600 a = regmatch_array(zreg3);
00601 zout->class = a[2];
00602 zout->instance = a[3];
00603 zout->body = a[4];
00604 }
00605 else if (regexec(zreg6, line))
00606 {
00607 a = regmatch_array(zreg6);
00608 zout->class = "webzephyr";
00609 zout->instance = a[2];
00610 zout->recip = "daemon.webzephyr";
00611 zout->body = a[3];
00612 }
00613 else if (regexec(zreg4, line))
00614 {
00615 a = regmatch_array(zreg4);
00616 zout->class = unmapped_class(a[2]);
00617 if (!zout->class) zout->class = a[2];
00618 zout->instance = a[3];
00619 zout->body = a[4];
00620 }
00621 else if (regexec(zreg5, line))
00622 {
00623 a = regmatch_array(zreg5);
00624
00625 ival = unmapped_instance(a[2]);
00626 if (ival)
00627 {
00628 zout->class = ival[0];
00629 zout->instance = ival[1];
00630 }
00631 if (!zout->class)
00632 zout->class = unmapped_class(a[2]);
00633 if (!zout->class)
00634 {
00635 printf("Unknown class \"%s\".\n", a[2]);
00636 return;
00637 }
00638 zout->body = a[3];
00639 }
00640 else
00641 {
00642 printf("Illegal zephyr input.\n");
00643 return;
00644 }
00645
00646
00647 used_default_instance = use_default_instance(rmt, zout);
00648
00649
00650 if (cur_win)
00651 {
00652 default = bprintf("%s%s", crypt ? "*" : "", a[1]);
00653 while (*default && default[strlen(default) - 1] == ' ')
00654 default[strlen(default) - 1] = 0;
00655 if (zout->class && *zout->class && used_default_instance)
00656 strcat(default, bprintf("/%s", zout->instance));
00657 set_default_recip(rmt, default);
00658 }
00659
00660
00661
00662 if (multi)
00663 {
00664 if (zout->body && *zout->body)
00665 zout->body += "\n";
00666 else
00667 zout->body = "";
00668 zout_pipe = zout;
00669 return zout;
00670 }
00671
00672
00673 if (!zout->body || !*zout->body)
00674 return;
00675
00676 return zout;
00677 }
00678
00679
00680
00681 [win] if (!windows_inited) {
00682 windows_inited = 1;
00683 win = std_split(active, 3);
00684 set_class_output("noc", win);
00685 set_class_output("filsrv", win);
00686 set_class_output("moira", win);
00687 }
00688
00689
00690
00691
00692
00693 func shrink_active() { resize(active, win_bottom(active)); }
00694 func enlarge_active() { resize(active, win_bottom(active) + 2); }
00695 bind(ctrl("^[<"), .shrink_active);
00696 bind(ctrl("^[>"), .enlarge_active);
00697 bind(ctrl("^[^H"), K_BWORD);
00698 bind(ctrl("^b"), .prev_win);
00699 bind(ctrl("^f"), .next_win);
00700
00701 bind(ctrl("^[[A") , .prevline);
00702 bind(ctrl("^[[B") , .nextline);
00703 bind(ctrl("^[OA") , .prevline);
00704 bind(ctrl("^[OB") , .nextline);
00705 bind(ctrl("^[^H"), K_BWORD);
00706 bind(ctrl("^[[C") , K_CRIGHT);
00707 bind(ctrl("^[[D") , K_CLEFT);
00708 bind(ctrl("^[OC") , K_CRIGHT);
00709 bind(ctrl("^[OD") , K_CLEFT);
00710 bind(ctrl("^[[E") , K_CWRIGHT);
00711 bind(ctrl("^[^[[C") , K_CWRIGHT);
00712 bind(ctrl("^[^[OC") , K_CWRIGHT);
00713 bind(ctrl("^[[F") , K_CWLEFT);
00714 bind(ctrl("^[^B") , K_CWLEFT);
00715 bind(ctrl("^[^[[D") , K_CWLEFT);
00716 bind(ctrl("^[^[OD") , K_CWLEFT);
00717 bind(ctrl("^[^[^[") , K_MODE);
00718 bind(ctrl("^[[G") , K_CUP);
00719 bind(ctrl("^[[H") , K_CDOWN);
00720 bind(ctrl("^[^[[A") , K_CUP);
00721 bind(ctrl("^[^[[B") , K_CDOWN);
00722 bind(ctrl("^[^[OA") , K_CUP);
00723 bind(ctrl("^[^[OB") , K_CDOWN);
00724
00725 [fp, line] if (!zephyr_initialized) {
00726 do_mailcheck = 0;
00727 zephyr_initialized = 1;
00728 resize(active, win_bottom(active) + 2);
00729 Load("~/.settings");
00730
00731 Load_zsigs("~/Private/zsigs-thesis");
00732 World("Zephyr");
00733 More("on");
00734
00735 }
00736
00737