12
12
/* Define the globals that are declared in eb.h. */
13
13
/* See eb.h for descriptive comments. */
15
const char *version = "3.2.1";
15
const char *version = "3.3.1";
16
16
char *userAgents[10], *currentAgent, *currentReferrer;
17
17
const char eol[] = "\r\n";
18
18
char EMPTYSTRING[] = "";
20
20
int webTimeout = 20, mailTimeout = 0;
21
21
bool ismc, browseLocal, zapMail, unformatMail, passMail, errorExit;
22
22
bool isInteractive, intFlag, inInput;
23
const char opint[] = "operation interrupted";
24
23
int fileSize, maxFileSize = 50000000;
25
24
int localAccount, maxAccount;
26
25
struct MACCOUNT accounts[MAXACCOUNT];
187
185
for(s = t = v = buf; s < buf + buflen; ++s) {
190
errorPrint("1.ebrc: null characters at line %d", ln);
188
i_printfExit(MSG_ERBC_Nulls, ln);
191
189
if(c == '\r' && s[1] == '\n')
288
286
(last[8] == '+' || last[8] == ':')) {
290
288
if(*q == 0 || *q == '{' || *q == '(')
291
errorPrint("1.ebrc: missing function name at line %d", ln);
289
i_printfExit(MSG_ERBC_NoFnName, ln);
292
290
if(isdigitByte(*q))
294
("1.ebrc: function name at line %d begins with a digit",
291
i_printfExit(MSG_ERBC_FnDigit, ln);
296
292
while(isalnumByte(*q))
298
294
if(q - last - 9 > 10)
300
("1.ebrc: function name at line %d is too long, limit ten characters",
295
i_printfExit(MSG_ERBC_FnTooLong, ln);
302
296
if(*q != '{' || q[1])
304
("1.ebrc: improper function definition syntax at line %d",
297
i_printfExit(MSG_ERBC_SyntaxErr, ln);
307
299
last[6] = '\x81';
308
300
strcpy(v, last + 6);
345
337
if(mailblock > 1 && !strchr("\x81\x82\x83", *s)) {
346
338
v = strchr(s, '>');
348
errorPrint("1.ebrc: line %d, \"condition > file\" expected",
340
i_printfExit(MSG_ERBC_NoCondFile, ln);
350
341
while(v > s && (v[-1] == ' ' || v[-1] == '\t'))
353
errorPrint(".ebrc: line %d, filter rule has no match string",
344
i_printfExit(MSG_ERBC_NoMatchStr, ln);
355
345
c = *v, *v++ = 0;
361
351
while(*v == ' ' || *v == '\t')
364
errorPrint("1.ebrc: line %d, match on %s is set nowhere", ln,
354
i_printfExit(MSG_ERBC_MatchNowh, ln, s);
366
355
if(n_filters == MAXFILTER - 1)
367
errorPrint("1.ebrc: line %d, too many mail filters", ln);
356
i_printfExit(MSG_ERBC_Filters, ln);
368
357
filters[n_filters].redirect = v;
369
358
if(mailblock >= 2) {
370
359
long exp = strtol(s, &v, 10);
404
393
n = stringInList(keywords, s);
407
errorPrint("1.ebrc: unrecognized keyword %s at line %d", s, ln);
396
i_printfExit(MSG_ERBC_BadKeyword, s, ln);
408
397
*v = c; /* put it back */
412
401
if(n < 8 && mailblock != 1)
414
("1.ebrc: line %d, attribute %s canot be set outside of a mail descriptor",
402
i_printfExit(MSG_ERBC_MailAttrOut, ln, s);
417
404
if(n >= 8 && n < 13 && mimeblock != 1)
419
("1.ebrc: line %d, attribute %s canot be set outside of a mime descriptor",
405
i_printfExit(MSG_ERBC_MimeAttrOut, ln, s);
422
407
if(n >= 13 && n < 17 && tabblock != 1)
424
("1.ebrc: line %d, attribute %s canot be set outside of a table descriptor",
408
i_printfExit(MSG_ERBC_TableAttrOut, ln, s);
427
410
if(n >= 8 && mailblock)
429
("1.ebrc: line %d, attribute %s canot be set inside a mail descriptor or filter block",
411
i_printfExit(MSG_ERBC_MailAttrIn, ln, s);
432
413
if((n < 8 || n >= 13) && mimeblock)
434
("1.ebrc: line %d, attribute %s canot be set inside a mime descriptor",
414
i_printfExit(MSG_ERBC_MimeAttrIn, ln, s);
437
416
if((n < 13 || n >= 17) && tabblock)
439
("1.ebrc: line %d, attribute %s canot be set inside a table descriptor",
417
i_printfExit(MSG_ERBC_TableAttrIn, ln, s);
442
419
/* act upon the keywords */
449
426
while(*v == ' ' || *v == '\t')
452
errorPrint("1.ebrc: line %d, attribute %s is set to nothing", ln,
429
i_printfExit(MSG_ERBC_NoAttr, ln, s);
520
496
if(td->ncols == MAXTCOLS)
521
errorPrint("1.ebrc: line %d, too many columns, limit %d",
497
i_printfExit(MSG_ERBC_ManyCols, ln, MAXTCOLS);
523
498
td->cols[td->ncols++] = v;
524
499
q = strchr(v, ',');
533
508
if(!isdigitByte(*v))
535
("1.ebrc: line %d, keycol should be number or number,number",
509
i_printfExit(MSG_ERBC_KeyNotNb, ln);
537
510
td->key1 = strtol(v, &v, 10);
538
511
if(*v == ',' && isdigitByte(v[1]))
539
512
td->key2 = strtol(v + 1, &v, 10);
540
513
if(td->key1 > td->ncols || td->key2 > td->ncols)
542
("1.ebrc: line %d, keycol is out of range; only %d columns specified",
514
i_printfExit(MSG_ERBC_KeyOutRange, ln, td->ncols);
548
519
ftype = fileTypeByName(v, false);
549
520
if(ftype && ftype != 'f')
550
errorPrint("1.ebrc: address book %s is not a regular file", v);
521
i_printfExit(MSG_ERBC_AbNotFile, v);
555
526
ftype = fileTypeByName(v, false);
556
527
if(ftype && ftype != 'f')
557
errorPrint("1.ebrc: ip blacklist %s is not a regular file", v);
528
i_printfExit(MSG_ERBC_IPNotFile, v);
562
533
if(fileTypeByName(v, false) != 'd')
563
errorPrint("1.ebrc: %s is not a directory", v);
534
i_printfExit(MSG_ERBC_NotDir, v);
578
548
ftype = fileTypeByName(v, false);
579
549
if(ftype && ftype != 'f')
580
errorPrint("1.ebrc: cookie jar %s is not a regular file", v);
550
i_printfExit(MSG_ERBC_JarNotFile, v);
581
551
j = open(v, O_WRONLY | O_APPEND | O_CREAT, 0600);
583
errorPrint("1.ebrc: cannot %s cookie jar %s",
584
ftype ? "create" : "write to", v);
553
i_printfExit(MSG_ERBC_JarNoWrite, v);
589
558
if(javaDisCount == MAXNOJS)
590
errorPrint("1.ebrc: too many no js directives, limit %d",
559
i_printfExit(MSG_ERBC_NoJS, MAXNOJS);
594
562
q = strchr(v, '.');
595
563
if(!q || q[1] == 0)
596
errorPrint("1.ebrc: line %d, domain %s does not contain a dot",
564
i_printfExit(MSG_ERBC_DomainDot, ln, v);
598
565
javaDis[javaDisCount++] = v;
603
570
ftype = fileTypeByName(v, false);
604
571
if(ftype && ftype != 'f')
605
errorPrint("1.ebrc: mail trash can %s is not a regular file",
572
i_printfExit(MSG_ERBC_TrashNotFile, v);
619
585
ftype = fileTypeByName(v, false);
620
586
if(ftype && ftype != 'f')
622
("1.ebrc: SSL certificate file %s is not a regular file", v);
587
i_printfExit(MSG_ERBC_SSLNoFile, v);
623
588
j = open(v, O_RDONLY);
626
("1.ebrc: SSL certificate file %s does not exist or is not readable.",
590
i_printfExit(MSG_ERBC_SSLNoRead, v);
656
errorPrint("1.ebrc: line %d, keyword %s is not yet implemented", ln,
619
i_printfExit(MSG_ERBC_KeywordNYI, ln, s);
676
errorPrint("1.ebrc: missing inserver at line %d", ln);
638
i_printfExit(MSG_ERBC_NoInserver, ln);
678
errorPrint("1.ebrc: missing outserver at line %d", ln);
640
i_printfExit(MSG_ERBC_NoOutserver, ln);
680
errorPrint("1.ebrc: missing login at line %d", ln);
642
i_printfExit(MSG_ERBC_NoLogin, ln);
681
643
if(!act->password)
682
errorPrint("1.ebrc: missing password at line %d", ln);
644
i_printfExit(MSG_ERBC_NPasswd, ln);
684
errorPrint("1.ebrc: missing from at line %d", ln);
646
i_printfExit(MSG_ERBC_NoFrom, ln);
686
errorPrint("1.ebrc: missing reply at line %d", ln);
648
i_printfExit(MSG_ERBC_NoReply, ln);
688
650
act->inport = 110;
689
651
if(!act->outport)
703
errorPrint("1.ebrc: missing type at line %d", ln);
665
i_printfExit(MSG_ERBC_NoType, ln);
705
errorPrint("1.ebrc: missing description at line %d", ln);
667
i_printfExit(MSG_ERBC_NDesc, ln);
706
668
if(!mt->suffix && !mt->prot)
708
("1.ebrc: missing suffix or protocol list at line %d",
669
i_printfExit(MSG_ERBC_NoSuffix, ln);
711
errorPrint("1.ebrc: missing program at line %d", ln);
671
i_printfExit(MSG_ERBC_NoProgram, ln);
719
errorPrint("1.ebrc: missing table name at line %d", ln);
679
i_printfExit(MSG_ERBC_NoTblName, ln);
720
680
if(!td->shortname)
721
errorPrint("1.ebrc: missing short name at line %d", ln);
681
i_printfExit(MSG_ERBC_NoShortName, ln);
723
errorPrint("1.ebrc: missing columns at line %d", ln);
683
i_printfExit(MSG_ERBC_NColumns, ln);
728
errorPrint("1.ebrc: unexpected } at line %d", ln);
688
i_printfExit(MSG_ERBC_UnexpBrace, ln);
731
691
/* This ends the function */
738
698
/* Does else make sense here? */
739
699
c = toupper(stack[nest]);
742
("1.ebrc: else at line %d is not part of an if statement",
701
i_printfExit(MSG_ERBC_UnexElse, ln);
747
705
if(*s != '\x81') {
749
errorPrint("1.ebrc: garbled text at line %d", ln);
707
i_printfExit(MSG_ERBC_GarblText, ln);
760
718
curblock = "a filter block";
762
720
curblock = "a mime descriptor";
764
("1.ebrc: line %d, cannot start a function, mail/mime descriptor, or filter block inside %s",
721
i_printfExit(MSG_ERBC_FnNotStart, ln, curblock);
768
724
if(!strchr("fmertsb", c) && !nest)
770
("1.ebrc: statement at line %d must appear inside a function",
725
i_printfExit(MSG_ERBC_StatNotInFn, ln);
775
729
if(maxAccount == MAXACCOUNT)
777
("1too many email accounts in your config file, limit %d",
730
i_printfExit(MSG_ERBC_ManyAcc, MAXACCOUNT);
779
731
act = accounts + maxAccount;
785
737
if(maxMime == MAXMIME)
787
("1too many mime types in your config file, limit %d",
738
i_printfExit(MSG_ERBC_ManyTypes, MAXMIME);
789
739
mt = mimetypes + maxMime;
795
745
if(maxTables == MAXDBT)
797
("1too many sql tables in your config file, limit %d",
746
i_printfExit(MSG_ERBC_ManyTables, MAXDBT);
799
747
td = dbtables + maxTables;
819
767
stack[++nest] = c;
820
768
if(sn == MAXEBSCRIPT)
821
errorPrint("1too many functions in your config file, limit %d",
769
i_printfExit(MSG_ERBC_ManyFn, sn);
823
770
ebScriptName[sn] = s + 2;
825
772
ebScript[sn] = t;
829
776
if(++nest >= sizeof (stack))
831
("1.ebrc: line %d, control structures are nested too deeply",
777
i_printfExit(MSG_ERBC_TooDeeply, ln);
837
782
} /* loop over lines */
840
errorPrint("1.ebrc: function %s is not closed at eof",
785
i_printfExit(MSG_ERBC_FnNotClosed, ebScriptName[sn]);
843
787
if(mailblock | mimeblock)
844
errorPrint("1.ebrc: mail or mime block is not closed at EOF");
788
i_printfExit(MSG_ERBC_MNotClosed);
985
printf("interrupt, type qt to quit completely\n");
929
i_puts(MSG_EnterInterrupt);
986
930
/* If we were reading from a file, or socket, this signal should
987
931
* cause the read to fail. Check for intFlag, so we know it was
988
932
* interrupted, and not an io failure.
1031
977
/* I require this, though I'm not sure what this means for non-Unix OS's */
1033
errorPrint("1home directory not defined by $HOME.");
979
i_printfExit(MSG_NotHome);
1034
980
if(fileTypeByName(home, false) != 'd')
1035
errorPrint("1%s is not a directory", home);
981
i_printfExit(MSG_NotDir, home);
1037
983
/* See sample.ebrc in this directory for a sample config file. */
1038
984
configFile = allocMem(strlen(home) + 7);
1100
1046
++s, passMail = true;
1101
1047
if(*s == 'm' && isdigitByte(s[1])) {
1102
1048
if(!maxAccount)
1104
("1no mail accounts specified, please check your .ebrc config file");
1049
i_printfExit(MSG_NoMailAcc);
1105
1050
account = strtol(s + 1, &s, 10);
1106
1051
if(account == 0 || account > maxAccount)
1107
errorPrint("1invalid account number, please use 1 through %d",
1052
i_printfExit(MSG_BadAccNb, maxAccount);
1110
1054
ismc = true; /* running as a mail client */
1111
1055
allowJS = false; /* no javascript in mail client */
1118
errorPrint("1edbrowse -v (show version)\n\
1119
edbrowse -h (this message)\n\
1120
edbrowse -c (edit config file)\n\
1121
edbrowse [-e] [-d?] -[u|p]m? (read your mail) \n\
1122
edbrowse [-e] [-d?] -m? address1 address2 ... file [+attachments]\n\
1123
edbrowse [-e] [-d?] file1 file2 ...");
1062
i_printfExit(MSG_Usage);
1124
1063
} /* options */
1126
1065
if(tcp_init() < 0)
1143
1082
fetchMail(account);
1146
("1please specify at least one recipient and the file to send");
1084
i_printfExit(MSG_MinOneRec);
1147
1085
/* I don't know that argv[argc] is 0, or that I can set it to 0,
1148
1086
* so I back everything up by 1. */
1149
1087
reclist = argv - 1;
1158
1096
atlist = argv + argc - nat - 1;
1159
1097
if(atlist <= argv)
1161
("1please specify at least one recipient and the file to send, before your attachments");
1098
i_printfExit(MSG_MinOneRecBefAtt);
1162
1099
body = *atlist;
1164
1101
memcpy(atlist, atlist + 1, sizeof (char *) * nat);
1235
1171
pst p = inputLine();
1236
1172
copyPstring(saveline, p);
1237
1173
if(perl2c((char *)p))
1239
("entered command line contains nulls; you can use \\0 in a search/replace string to indicate null\n");
1174
i_puts(MSG_EnterNull);
1241
1176
edbrowseCommand((char *)p, false);
1242
1177
copyPstring(linePending, saveline);
1295
1230
/* Separate function name and arguments */
1296
1231
spaceCrunch(linecopy, true, false);
1297
1232
if(linecopy[0] == 0) {
1298
setError("no function specified");
1233
setError(MSG_NoFunction);
1301
1236
memset(args, 0, sizeof (args));
1307
1242
for(s = linecopy; *s; ++s)
1308
1243
if(!isalnumByte(*s)) {
1309
setError("function name should only contain letters and numbers");
1244
setError(MSG_BadFunctionName);
1312
1247
for(j = 0; ebScript[j]; ++j)
1313
1248
if(stringEqual(linecopy, ebScriptName[j] + 1))
1315
1250
if(!ebScript[j]) {
1316
setError("no such function %s", linecopy);
1251
setError(MSG_NoSuchFunction, linecopy);
1474
1414
/* pipe the buffer into the program */
1475
1415
f = popen(cmd, "w");
1477
setError("could not spawn subcommand %s, errno %d", cmd, errno);
1417
setError(MSG_NoSpawn, cmd, errno);
1480
1420
if(!unfoldBuffer(context, false, &buf, &buflen)) {
1494
1434
f = fopen(edbrowseTempFile, "w");
1496
setError("could not create temp file %s, errno %d",
1497
edbrowseTempFile, errno);
1436
setError(MSG_TempNoCreate2, edbrowseTempFile, errno);
1530
1469
struct DBTABLE *td;
1531
1470
if(maxTables == MAXDBT) {
1532
setError("too many sql tables in cache, limit %d", MAXDBT);
1471
setError(MSG_ManyTables, MAXDBT);
1535
1474
td = dbtables + maxTables++;