Codebase list axmail / a847c0d
New upstream version 2.13 Dave Hibberd 2 years ago
91 changed file(s) with 14154 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.12.2"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2021 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/lib/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 /* mailcmd.c - Mail commands */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <syslog.h>
7
8 #include "mailcmd.h"
9 #include "defines.h"
10 #include "config.h"
11 #include "mbox.h"
12 #include "utils.h"
13
14 /* List messages */
15
16 void printhead(int i, struct message *m) {
17 char ch = ' ';
18
19 if ((m->m_flag & (MREAD|MNEW)) == MNEW)
20 ch = 'N';
21 if ((m->m_flag & (MREAD|MNEW)) == 0)
22 ch = 'U';
23 if ((m->m_flag & (MDELETED)) == MDELETED)
24 ch = 'K';
25
26 printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n",
27 (current == i+1) ? '>' : ' ',
28 ch, i+1, m->from, m->subj, m->date ,m->m_size);
29 }
30
31 int do_list(int argc, char **argv)
32 {
33 int i;
34
35 if (!(messages)) {
36 printf("No messages.\n");
37 return 0;
38 }
39
40 printf("St Num From Subject Date Size\n");
41
42 for (i = 0; i < messages; i++) {
43 printhead(i, &message[i]);
44 }
45
46 return 0;
47 }
48
49 /* Read a message (xNOS-stylish parameters) */
50
51 int do_read(int argc, char **argv)
52 {
53 char *myargv[64];
54 int myargc, argsmine;
55 char *tmpbuf;
56 int i, j, k;
57 struct message *m;
58 int msg, maxmsg;
59 char line[2000];
60
61 // Automatic Receipt generator
62 FILE *f;
63 char str [LINESIZE + 1];
64
65 if (!(messages)) {
66 printf("You have no messages.\n");
67 return 0;
68 }
69
70 if (argc > 1) {
71 argsmine = 0;
72 for (i = 1; i < argc; i++)
73 myargv[i] = argv[i];
74 myargc = argc;
75 } else {
76 argsmine = 1;
77 if (current >= messages) {
78 printf("No more messages.\n");
79 return 0;
80 }
81 current++;
82 myargc = 2;
83 myargv[1] = malloc(17);
84 sprintf(myargv[1], "echo");
85 sprintf(myargv[1], "%i", current);
86 }
87
88 for (i = 1; i < myargc; i++) {
89 tmpbuf = strchr(myargv[i], '-');
90 msg = atoi(myargv[i]);
91 if (tmpbuf == NULL)
92 maxmsg = msg;
93 else
94 maxmsg = atoi(++tmpbuf);
95 if (maxmsg < msg) {
96 printf("Bad message number %i.\n", maxmsg);
97 continue;
98 }
99 for (; msg <= maxmsg; msg++) {
100 if (msg < 1 || msg > messages) {
101 printf("There's no message number %i.\n", msg);
102 continue;
103 }
104 readmesg(msg, (!strncmp(argv[0], "v", 1)));
105 printf("--- end of message #%i --- \n", msg);
106 if (dot->receipt != NULL) {
107 getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): ");
108 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
109 /* Let's try to automate the receipt generator more */
110 f = fopen(tempMesg, "w");
111 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
112 strncpy (str, dot->from, LINESIZE);
113 printf("Receipt going to: %s\n", str);
114 fprintf(f,"To: %s\n", str);
115 fprintf(f,"X-Mailer: %s\n",VERSION);
116 fprintf(f,"X-Origin: Amateur Radio Services\n");
117 fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj);
118 strncpy (str, dot->subj, LINESIZE);
119 fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj);
120 fprintf(f,"written on %s has been read.\n\n", dot->date);
121 fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n");
122 fclose(f);
123 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
124 system(str);
125 printf("Read receipt sent.\n");
126 }
127 }
128 }
129
130 }
131 if (argsmine)
132 for (i = 1; i < myargc; i++)
133 free(myargv[i]);
134 return 0;
135 }
136
137 /* Send a message (perhaps a reply) */
138
139 int do_send(int argc, char **argv)
140 {
141 FILE *f;
142 FILE *g;
143
144 char str[LINESIZE + 1];
145 char cc[LINESIZE + 1];
146 char bcc[LINESIZE + 1];
147 int i;
148
149 int reply = 0;
150
151 if (!strncmp(argv[0], "sr", 2)) {
152 reply = 1;
153 if (argc == 1) {
154 if (current == 0) {
155 printf("No current message to reply to.\n");
156 return 0;
157 }
158 i = current;
159 } else
160 i = atoi(argv[0]);
161
162 i--;
163 if ((i < 0) || (i >= messages)) {
164 printf("Just enter SR without a parameter or number.\n");
165 return 0;
166 }
167
168 dot = &message[i];
169 }
170
171 if ((f = fopen(tempMesg, "w")) == NULL) {
172 printf("Could not create temporary file.\n");
173 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
174 return 0;
175 }
176
177 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
178
179 str[0] = '\0';
180 if (argc != 1) /* Recipient on command line */
181 for (i = 1; i < argc; i++) {
182 if (i > 1)
183 strcat(str, " ");
184 strncat(str, argv[i], LINESIZE - strlen(str));
185 }
186 else {
187 if (reply) {
188 strncpy(str, dot->from, LINESIZE);
189 printf("To: %s\n", str);
190 } else {
191 mymain:
192 getstr(str, LINESIZE, "(? = help)\nTo: ");
193 if (!strcmp(str, "?")) {
194 printf("Enter the email address or addresses separated by commas on this line\n");
195 printf("You'll be asked if you want copies to others.\n");
196 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
197 goto mymain;
198 }
199
200 if (str[0] == '\0') {
201 printf("No recipients, message cancelled.\n");
202 fclose(f);
203 remove(tempMesg);
204 return 0;
205 }
206
207 }
208 }
209
210 fprintf( f, "To: %s\n", str);
211 /* adding a carbon copy feature */
212
213 copies:
214 getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): ");
215 if (!strcmp(str, "?")) {
216 printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n");
217 printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n");
218 goto copies;
219 } else {
220
221 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
222 goto carbon;
223 } else {
224 goto prio;
225 }
226 }
227 carbon:
228 getstr(cc, LINESIZE, "(? = help)\ncc: ");
229
230 if (!strcmp(cc, "?")) {
231 printf("Enter your carbon copied address(es) below. You will be prompted for\n");
232 printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n");
233 printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n");
234 goto carbon;
235 }
236 if (cc[0] == '\0') {
237 goto goblind;
238 }
239 fprintf( f, "cc: %s\n", cc);
240
241 goblind:
242 /* adding a blind carbon copy feature */
243 getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: ");
244
245 if (!strcmp(bcc, "?")) {
246 printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n");
247 printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n");
248 goto goblind;
249 }
250 if (bcc[0] == '\0') {
251 goto header;
252 }
253 fprintf( f, "bcc: %s\n", bcc);
254
255
256 header:
257 fprintf( f, "X-Mailer: %s\n", VERSION );
258 fprintf( f, "X-Origin: Amateur Radio Services\n" );
259 goto prio;;
260
261 /* adding priority receive rule */
262
263 prio:
264 getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): ");
265
266 /* try to bullet-proof end-user responces a bit... */
267
268 if (!strcmp(str, "?")) {
269 printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n");
270 printf("priority in nature and with most mail client software will present\n");
271 printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n");
272 printf("by hitting the enter key will send your mail message via normal delivery.\n\n");
273 goto prio;
274 }
275
276 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
277 fprintf( f, "X-Priority: 1 (Highest)\n" );
278 }
279 else
280 { fprintf( f,"X-Priority: 3 (Normal)\n" );
281 }
282
283 receipt:
284 getstr(str, LINESIZE, "Read receipt requested? (y/N/?): ");
285
286 if (!strcmp(str, "?")) {
287 printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n");
288 printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n");
289 printf("by hitting the enter key will not request a confirmation receipt.\n\n");
290 goto receipt;
291 }
292
293 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
294 fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname);
295 }
296 else
297 { fprintf( f,"" );
298 }
299
300 if (reply) {
301 if (strncasecmp(dot->subj, "Re: ", 3))
302 snprintf(str, LINESIZE, "Re: %s", dot->subj);
303 else
304 snprintf(str, LINESIZE, "%s", dot->subj);
305 printf("Subject: %s\n", str);
306 } else
307 getstr(str, LINESIZE, "Subject: ");
308
309 fprintf(f, "Subject: %s\n", str);
310
311 if (reply)
312 fprintf(f, "In-Reply-To: %s\n", dot->id);
313
314 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
315 fflush(stdout);
316
317 cont:
318 do {
319 fgets(str, LINESIZE, stdin);
320 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
321 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
322
323 retry:
324 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
325 if (!strcmp(str, "?")) {
326 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
327 printf("let you continue writing the message. Answering anything else will\n");
328 printf("proceed with delivering the message to the recipient.\n");
329 goto retry;
330 }
331 if (!strcasecmp(str, "c")) {
332 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
333 fflush(stdout);
334 goto cont;
335 }
336 /* append a signature file signature to the mail message */
337 FILE *stream;
338 FILE *streamm;
339 FILE *streammm;
340 char *line = NULL;
341 char *sig = NULL;
342 char buffer[79 + 1];
343 char bufferr[50 + 1];
344 char bufferrr[50 + 1];
345 size_t len = 0;
346 ssize_t read;
347
348 sprintf(buffer,"%s/.signature", homedir);
349 sprintf(bufferr,"/etc/clamsmtpd.conf");
350 sprintf(bufferrr,"/etc/clamav/clamav-milter.conf");
351 stream = fopen(buffer, "r");
352 streamm = fopen(bufferr, "r");
353 streammm = fopen(bufferrr, "r");
354 if (stream == NULL) {
355 printf("No signature file found, use the SIG command to make one.\n");
356 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
357 if ((streamm || streammm) == NULL) {
358 } else {
359 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
360 fclose(streamm);
361 fclose(streammm);
362 }
363
364 goto mailmsg;
365 } else {
366 while ((read = getline(&line, &len, stream)) != -1) {
367 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
368 if ((streamm || streammm) == NULL) {
369 } else {
370 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
371 fclose(streamm);
372 }
373 }
374
375 free(line);
376 fclose(stream);
377 }
378 mailmsg:
379
380
381 if (fclose(f)) {
382 printf("Ouch, could not close temporary file.\n");
383 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
384 return 0;
385 }
386
387 delrcpt:
388 if (strcasecmp(str, "n")) {
389 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
390 if (!strcasecmp(str, "?")) {
391 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
392 printf("it that you desire notification that your mail message not only was received but\n");
393 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
394 printf("if you need to log the fact that you sent a communication to a specific person\n");
395 printf("especially for emergency communication purposes and they do NOT send you a read\n");
396 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
397 printf("you infact did send a communication and the remote person did in fact received it.\n");
398 printf("This feature can ONLY be found in axMail-FAX.\n");
399 goto delrcpt;
400 }
401 if (!strcasecmp(str, "y")) {
402 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
403 system(str);
404 printf("Message sent, delivery notification activated.\n");
405 } else {
406 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
407 system(str);
408 printf("Message sent.\n");
409 }
410 } else
411 printf("Message canceled.\n");
412
413 if (remove(tempMesg)) {
414 printf("Ouch, could not remove temporary file.\n");
415 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
416 return 0;
417 }
418
419 return 0;
420 }
421
422 /* Send a personal message with no flags or copy prompts */
423
424 int do_psend(int argc, char **argv)
425 {
426 FILE *f;
427 FILE *g;
428
429 char str[LINESIZE + 1];
430 int i;
431
432 int reply = 0;
433
434 if (!strncmp(argv[0], "sr", 2)) {
435 reply = 1;
436 if (argc == 1) {
437 if (current == 0) {
438 printf("No current message to reply to.\n");
439 return 0;
440 }
441 i = current;
442 } else
443 i = atoi(argv[0]);
444
445 i--;
446 if ((i < 0) || (i >= messages)) {
447 printf("Just enter SR without a parameter or number.\n");
448 return 0;
449 }
450
451 dot = &message[i];
452 }
453
454 if ((f = fopen(tempMesg, "w")) == NULL) {
455 printf("Could not create temporary file.\n");
456 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
457 return 0;
458 }
459
460 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
461
462 str[0] = '\0';
463 if (argc != 1) /* Recipient on command line */
464 for (i = 1; i < argc; i++) {
465 if (i > 1)
466 strcat(str, " ");
467 strncat(str, argv[i], LINESIZE - strlen(str));
468 }
469 else {
470 if (reply) {
471 strncpy(str, dot->from, LINESIZE);
472 printf("To: %s\n", str);
473 } else {
474 mypmain:
475 getstr(str, LINESIZE, "(? = help)\nTo: ");
476 if (!strcmp(str, "?")) {
477 printf("Enter the email address or addresses separated by commas on this line\n");
478 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
479 goto mypmain;
480 }
481
482 if (str[0] == '\0') {
483 printf("No recipients, message cancelled.\n");
484 fclose(f);
485 remove(tempMesg);
486 return 0;
487 }
488
489 }
490 }
491
492 fprintf( f, "To: %s\n", str);
493 fprintf( f, "X-Mailer: %s\n", VERSION );
494 fprintf( f, "X-Origin: Amateur Radio Services\n" );
495 fprintf( f, "X-Priority: 1 (Highest)\n" );
496
497 if (reply) {
498 if (strncasecmp(dot->subj, "Re: ", 3))
499 snprintf(str, LINESIZE, "Re: %s", dot->subj);
500 else
501 snprintf(str, LINESIZE, "%s", dot->subj);
502 printf("Subject: %s\n", str);
503 } else
504 getstr(str, LINESIZE, "Subject: ");
505
506 fprintf(f, "Subject: %s\n", str);
507
508 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
509 fflush(stdout);
510
511 pcont:
512 do {
513 fgets(str, LINESIZE, stdin);
514 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
515 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
516
517 pretry:
518 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
519 if (!strcmp(str, "?")) {
520 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
521 printf("let you continue writing the message. Answering anything else will\n");
522 printf("proceed with delivering the message to the recipient.\n");
523 goto pretry;
524 }
525 if (!strcasecmp(str, "c")) {
526 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
527 fflush(stdout);
528 goto pcont;
529 }
530
531 /* append a signature file signature to the mail message */
532 FILE *stream;
533 FILE *streamm;
534 FILE *streammm;
535 char *line = NULL;
536 char *sig = NULL;
537 char buffer[79 + 1];
538 char bufferr[50 + 1];
539 char bufferrr[50 + 1];
540 size_t len = 0;
541 ssize_t read;
542
543 sprintf(buffer,"%s/.signature", homedir);
544 sprintf(bufferr,"/etc/clamsmtpd.conf");
545 sprintf(bufferrr,"/etc/clamav/clamav-milter.conf");
546 stream = fopen(buffer, "r");
547 streamm = fopen(bufferr, "r");
548 streammm= fopen(bufferrr, "r");
549 if (stream == NULL) {
550 printf("No signature file found, use the SIG command to make one.\n");
551 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
552 if ((streamm || streammm) == NULL) {
553 } else {
554 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
555 fclose(streamm);
556 }
557 goto pmailmsg;
558 } else {
559 while ((read = getline(&line, &len, stream)) != -1) {
560 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
561 if ((streamm || streammm) == NULL) {
562 } else {
563 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
564 fclose(streamm);
565 fclose(streammm);
566 }
567 }
568
569 free(line);
570 fclose(stream);
571 }
572
573 pmailmsg:
574
575 if (fclose(f)) {
576 printf("Ouch, could not close temporary file.\n");
577 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
578 return 0;
579 }
580 if (strcasecmp(str, "n")) {
581 pdelrcpt:
582 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
583 if (!strcasecmp(str, "?")) {
584 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
585 printf("it that you desire notification that your mail message not only was received but\n");
586 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
587 printf("if you need to log the fact that you sent a communication to a specific person\n");
588 printf("especially for emergency communication purposes and they do NOT send you a read\n");
589 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
590 printf("you infact did send a communication and the remote person did in fact received it.\n");
591 printf("This feature can ONLY be found in axMail-FAX.\n");
592 goto pdelrcpt;
593 }
594 if (!strcasecmp(str, "y")) {
595 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
596 system(str);
597 printf("Message sent, delivery notification activated.\n");
598 } else {
599 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
600 system(str);
601 printf("Message sent.\n");
602 }
603 } else
604 printf("Message canceled.\n");
605
606 if (remove(tempMesg)) {
607 printf("Ouch, could not remove temporary file.\n");
608 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
609 return 0;
610 }
611
612 return 0;
613 }
614
615 /* Kill a message */
616
617 int do_kill(int argc, char **argv)
618 {
619 int i, msg = 0, cnt = 0;
620 char *myargv[64];
621 int myargc, argsmine;
622
623 if (!(messages)) {
624 printf("You have no messages.\n");
625 return 0;
626 }
627
628 if (argc > 1) {
629 argsmine = 0;
630 for (i = 1; i < argc; i++)
631 myargv[i] = argv[i];
632 myargc = argc;
633 } else {
634 if (current == 0) {
635 printf("No current message to kill.\n");
636 return 0;
637 }
638 argsmine = 1;
639 myargc = 2;
640 myargv[1] = malloc(17);
641 sprintf(myargv[1], "%i", current);
642 }
643
644 for (i = 1; i < myargc; i++) {
645 msg = atoi(myargv[i]) - 1;
646
647 if ((msg < 0) || (msg >= messages)) {
648 printf("There's no message %s.\n", myargv[i]);
649 continue;
650 }
651
652 dot = &message[msg];
653
654 if ((dot->m_flag & MDELETED) == MDELETED) {
655 printf("Message %i is already dead.\n", msg + 1);
656 continue;
657 }
658
659 dot->m_flag |= MDELETED;
660 cnt++;
661 }
662
663 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
664 printf("Message %i killed.\n", msg + 1);
665 else if (cnt > 1)
666 printf("%i messages killed.\n", cnt);
667
668 if (argsmine)
669 for (i = 1; i < myargc; i++)
670 free(myargv[i]);
671
672 return 0;
673 }
674
675 /* Unkill a message */
676
677 int do_unkill(int argc, char **argv)
678 {
679 int i, msg = 0, cnt = 0;
680 char *myargv[64];
681 int myargc, argsmine;
682
683 if (!(messages)) {
684 printf("You have no messages.\n");
685 return 0;
686 }
687
688 if (argc > 1) {
689 argsmine = 0;
690 for (i = 1; i < argc; i++)
691 myargv[i] = argv[i];
692 myargc = argc;
693 } else {
694 if (current == 0) {
695 printf("No current message to unkill.\n");
696 return 0;
697 }
698 argsmine = 1;
699 myargc = 2;
700 myargv[1] = malloc(17);
701 sprintf(myargv[1], "%i", current);
702 }
703
704 for (i = 1; i < myargc; i++) {
705 msg = atoi(myargv[i]) - 1;
706
707 if ((msg < 0) || (msg >= messages)) {
708 printf("There's no message %s.\n", myargv[i]);
709 continue;
710 }
711
712 dot = &message[msg];
713
714 if ((dot->m_flag & MDELETED) != MDELETED) {
715 printf("Message %i is not dead.\n", msg + 1);
716 continue;
717 }
718
719 dot->m_flag ^= (dot->m_flag & MDELETED);
720 cnt++;
721 }
722
723 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
724 printf("Message %i unkilled.\n", msg + 1);
725 else if (cnt > 1)
726 printf("%i messages unkilled.\n", cnt);
727
728 if (argsmine)
729 for (i = 1; i < myargc; i++)
730 free(myargv[i]);
731
732 return 0;
733 }
734
735 /* Send a Fax */
736 int do_fax(int argc, char **argv)
737 {
738 FILE *f;
739 char str[LINESIZE + 1];
740 int i;
741
742 int reply = 0;
743
744 if (!strncmp(argv[0], "sr", 2)) {
745 reply = 1;
746 if (argc == 1) {
747 if (current == 0) {
748 printf("No current message to reply to.\n");
749 return 0;
750 }
751 i = current;
752 } else
753 i = atoi(argv[1]);
754
755 i--;
756 if ((i < 0) || (i >= messages)) {
757 printf("There's no message %s.\n", argv[1]);
758 return 0;
759 }
760
761 dot = &message[i];
762 }
763
764 if ((f = fopen(tempMesg, "w")) == NULL) {
765 printf("Could not create temporary file.\n");
766 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
767 return 0;
768 }
769
770 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
771
772 str[0] = '\0';
773 if (argc != 1) /* Recipient on command line */
774 for (i = 1; i < argc; i++) {
775 if (i > 1)
776 strcat(str, " ");
777 strncat(str, argv[i], LINESIZE - strlen(str));
778 }
779 else {
780 }
781
782 printf("To: Fax Gateway\n");
783 fprintf( f, "To: %s\n", faxgate );
784 fprintf( f, "X-Mailer: %s\n", VERSION );
785 fprintf( f, "X-Origin: Amateur Radio Services\n" );
786 goto prio;;
787
788 /* adding priority receive rule */
789
790 prio:
791 /* if (reply) {
792 if (strncasecmp(dot->subj, "Re: ", 3))
793 snprintf(str, LINESIZE, "Re: %s", dot->subj);
794 else
795 snprintf(str, LINESIZE, "%s", dot->subj);
796 printf("Subject: %s\n", str);
797 } else */
798 getstr(str, LINESIZE, "Enter a header <firstname@fullphone Brief note here>\nEx: john@16195551212 Hi From Packet\nHeader: ");
799
800 fprintf(f, "Subject: %s\n", str);
801
802 if (reply)
803 fprintf(f, "In-Reply-To: %s\n", dot->id);
804
805 printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n");
806 fflush(stdout);
807
808 cont:
809 do {
810 /* fprintf( f, "X-Mailer: %s\n", VERSION );
811 fprintf( f, "X-Origin: Amateur Radio Services\n" ); */
812 fgets(str, LINESIZE, stdin);
813 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
814 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
815
816 retry:
817 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
818 if (!strcmp(str, "?")) {
819 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
820 printf("let you continue writing the facsimile. Answering anything else will\n");
821 printf("proceed with delivering the facsimile to the recipient.\n");
822 goto retry;
823 }
824 if (!strcasecmp(str, "c")) {
825 printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n");
826 fflush(stdout);
827 goto cont;
828 }
829
830 if (fclose(f)) {
831 printf("Ouch, could not close temporary file.\n");
832 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
833 return 0;
834 }
835
836 if (strcasecmp(str, "n")) {
837 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
838 system(str);
839 printf("Facsimile sent.\n");
840 } else
841 printf("Facsimile canceled.\n");
842
843 if (remove(tempMesg)) {
844 printf("Ouch, could not remove temporary file.\n");
845 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
846 return 0;
847 }
848
849 return 0;
850 }
0 USAGE
1 kill [<message_number>]
2 delete [<message_number>]
3
4 DESCRIPTION
5 This command removes specified message from mailbox.
6 If no message number is entered, then command removes
7 last viewed message.
8
9
0
1 /* in command.c */
2 extern int do_status(int argc, char **argv);
3 extern int do_name(int argc, char **argv);
4 extern int do_help(int argc, char **argv);
5 extern int do_quit(int argc, char **argv);
6 extern int do_exit(int argc, char **argv);
7 extern int do_forward(int argc, char **argv);
8 extern int do_signature(int argc, char **argv);
9 /* extern int do_forward(void); */
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
4 675 Mass Ave, Cambridge, MA 02139, USA
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The licenses for most software are designed to take away your
11 freedom to share and change it. By contrast, the GNU General Public
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Library General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
26
27 To protect your rights, we need to make restrictions that forbid
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
54
55 The precise terms and conditions for copying, distribution and
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
59 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
60
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
72 covered by this License; they are outside its scope. The act of
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
91 distribute such modifications or work under the terms of Section 1
92 above, provided that you also meet all of these conditions:
93
94 a) You must cause the modified files to carry prominent notices
95 stating that you changed the files and the date of any change.
96
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
113 These requirements apply to the modified work as a whole. If
114 identifiable sections of that work are not derived from the Program,
115 and can be reasonably considered independent and separate works in
116 themselves, then this License, and its terms, do not apply to those
117 sections when you distribute them as separate works. But when you
118 distribute the same sections as part of a whole which is a work based
119 on the Program, the distribution of the whole must be on the terms of
120 this License, whose permissions for other licensees extend to the
121 entire whole, and thus to each and every part regardless of who wrote it.
122
123 Thus, it is not the intent of this section to claim rights or contest
124 your rights to work written entirely by you; rather, the intent is to
125 exercise the right to control the distribution of derivative or
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
130 a storage or distribution medium does not bring the other work under
131 the scope of this License.
132
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
169 compelled to copy the source along with the object code.
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
180 signed it. However, nothing else grants you permission to modify or
181 distribute the Program or its derivative works. These actions are
182 prohibited by law if you do not accept this License. Therefore, by
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
185 all its terms and conditions for copying, distributing or modifying
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
192 restrictions on the recipients' exercise of the rights granted herein.
193 You are not responsible for enforcing compliance by third parties to
194 this License.
195
196 7. If, as a consequence of a court judgment or allegation of patent
197 infringement or for any other reason (not limited to patent issues),
198 conditions are imposed on you (whether by court order, agreement or
199 otherwise) that contradict the conditions of this License, they do not
200 excuse you from the conditions of this License. If you cannot
201 distribute so as to satisfy simultaneously your obligations under this
202 License and any other pertinent obligations, then as a consequence you
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
205 all those who receive copies directly or indirectly through you, then
206 the only way you could satisfy both it and this License would be to
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
213
214 It is not the purpose of this section to induce you to infringe any
215 patents or other property right claims or to contest validity of any
216 such claims; this section has the sole purpose of protecting the
217 integrity of the free software distribution system, which is
218 implemented by public license practices. Many people have made
219 generous contributions to the wide range of software distributed
220 through that system in reliance on consistent application of that
221 system; it is up to the author/donor to decide if he or she is willing
222 to distribute software through any other system and a licensee cannot
223 impose that choice.
224
225 This section is intended to make thoroughly clear what is believed to
226 be a consequence of the rest of this License.
227
228 8. If the distribution and/or use of the Program is restricted in
229 certain countries either by patents or by copyrighted interfaces, the
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
256
257 NO WARRANTY
258
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
278
279 END OF TERMS AND CONDITIONS
280
281 Appendix: How to Apply These Terms to Your New Programs
282
283 If you develop a new program, and you want it to be of the greatest
284 possible use to the public, the best way to achieve this is to make it
285 free software which everyone can redistribute and change under these terms.
286
287 To do so, attach the following notices to the program. It is safest
288 to attach them to the start of each source file to most effectively
289 convey the exclusion of warranty; and each file should have at least
290 the "copyright" line and a pointer to where the full notice is found.
291
292 <one line to give the program's name and a brief idea of what it does.>
293 Copyright (C) 19yy <name of author>
294
295 This program is free software; you can redistribute it and/or modify
296 it under the terms of the GNU General Public License as published by
297 the Free Software Foundation; either version 2 of the License, or
298 (at your option) any later version.
299
300 This program is distributed in the hope that it will be useful,
301 but WITHOUT ANY WARRANTY; without even the implied warranty of
302 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303 GNU General Public License for more details.
304
305 You should have received a copy of the GNU General Public License
306 along with this program; if not, write to the Free Software
307 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
308
309 Also add information on how to contact you by electronic and paper mail.
310
311 If the program is interactive, make it output a short notice like this
312 when it starts in an interactive mode:
313
314 Gnomovision version 69, Copyright (C) 19yy name of author
315 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
316 This is free software, and you are welcome to redistribute it
317 under certain conditions; type `show c' for details.
318
319 The hypothetical commands `show w' and `show c' should show the appropriate
320 parts of the General Public License. Of course, the commands you use may
321 be called something other than `show w' and `show c'; they could even be
322 mouse-clicks or menu items--whatever suits your program.
323
324 You should also get your employer (if you work as a programmer) or your
325 school, if any, to sign a "copyright disclaimer" for the program, if
326 necessary. Here is a sample; alter the names:
327
328 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
329 `Gnomovision' (which makes passes at compilers) written by James Hacker.
330
331 <signature of Ty Coon>, 1 April 1989
332 Ty Coon, President of Vice
333
334 This General Public License does not permit incorporating your program into
335 proprietary programs. If your program is a subroutine library, you may
336 consider it more useful to permit linking proprietary applications with the
337 library. If this is what you want to do, use the GNU Library General
338 Public License instead of this License.
0
1 extern void prompt(void);
2
3 extern void getname(char *uname);
4 extern void getstr(char *str, int len, char *prompt);
5
6 extern char *strupr(char *s);
7 extern char *strlwr(char *s);
8 extern int anyof(char *s1, char *s2);
9 extern int anycntrls(char *s1);
10
11 extern void panic(const char *fmt, ...);
12 extern void syserr(const char *fmt, ...);
13 /* n1uro */
14 char callsign[20];
0 USAGE
1 unkill <msg #>
2
3 DESCRIPTION
4 The Unkill commmand allows you to reflag a killed message as
5 valid so that it may be retrieved later if you wish to reread
6 it. This comes in very handy in the event you accidentally kill
7 or delete a mail message. Mail does NOT get fully killed until
8 you exit the axMail-FAX mailbox, and your settings are changed
9 and saved.
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 axMail appears to work with most linux based MTAs (Mail Transport Agent)
3 but not all, and I haven't had a chance to test it with them all either,
4 nor do I honestly care to install every MTA available for linux to do such
5 so if you do run an MTA *not listed* below, please feel free to email me
6 at: <n1uro@n1uro.com> and I'll add your report to this list. Consider this
7 file a 'work in progress' as with the software itself. How to test is
8 listed at the bottom.
9
10 PostFix - tested fine
11 Exim - tested fine
12 Smail** - failed tests, and also causes a total loss of end user mail!
13 Sendmail* - <unknown>
14 Qmail*** - <unknown>
15
16 * - In theory, the sendmail MTA should be ok since both exim and postfix
17 have sendmail compatable binaries/symlinks/etc.
18
19 ** - I don't know what it is with the smail MTA, but for some reason *all*
20 mail gets lost during the internal transfers from the system mailbox
21 and back to the system mailbox. Since smail has basically been
22 abandoned in favor of exim, I don't personally foresee this as an
23 issue.
24
25 ***- I've never installed a qmail system before and honestly don't feel
26 like doing that now hi!.. so if you run qmail and it works ok, please
27 let me know and I'll change it's status
28
29 If there's an MTA that I have missed and you've tested it and it works
30 please inform me and I'll add your results here.
31
32
33 How to test axmail:
34
35 You can run axmail at a command prompt!.. all it requires is that you put
36 your callsign after it. BEFORE you run this via a commandline however I
37 strongly suggest you make a backup of your system mail spool file by
38 typing: cp /var/spool/mail/call /var/spool/mail/call.bak this way here if
39 there is an issue and you have mail waiting, you won't lose any mail.
40
41 I'll assume your account on your box is your callsign, so in my case I would
42 execute:
43 n1uro@nat-client0:~$ /usr/sbin/axmail n1uro
44 and the standard greetings should appear along with the prompt and any
45 mail waiting should appear listed.
46
47 Pending the above test worked ok and unread/undeleted mail was saved back
48 into the system mailbox, try it from the node as a user who doesn't have
49 an account on the box. Hopefully when you exit, it'll tell you that you
50 have new mail waiting! Go back in and you should see the welcome.txt file
51 from /etc/ax25 listed as a greeting email message.
52
53 Other quick FAQs:
54
55 axMail works by comparing the user's system mail spool file, and as well
56 as any existing axMail saved mail and merges them together 'offline' for
57 lack of a better word to use. It then takes this mail and allows the user
58 to read/reply/delete/save/etc.
59
60 axMail has *always* supported file attachments, after all a file attachment
61 is just an encoded file appended to the body of the email message... its just
62 that most every client now-a-day automatically encodes/decodes them for you
63 and you assume that a file attachment is a seperate entity. All you need to
64 do to send and receive attachments via a packet terminal is the following
65 (examples taken from a linux terminal);
66
67 Sending: First encode the file by using uuencode. To do this run
68 uuencode filename filename
69 or if you want to make a file of it run: uuencode file file > file1
70 then copy and paste that encoded text in it's full into the body of
71 the mail message and send it.
72
73 Receiving: copy and paste the output of your message into a temporary
74 file and then run "uudecode -o filename tempfile". You will now have
75 a pdf/doc/text/jpg file sent to you by someone.
76
77 axMail now supports sending of fax transmissions! To configure axMail to
78 be able to do such, configure an account with an online fax service such
79 as eFax where you can email faxes and put the email address you'd use to
80 send faxes to in a _new line_ called "FaxGate" inside /etc/ax25/axmail.conf.
81 When users attempt to send a fax, your account will be hidden from them and
82 all they'll see is that they're sending to "a" fax gateway system.
83
84 People have asked about why new incoming mail isn't seen until after the
85 user logs out of axMail. If axMail read directly off of the system
86 mailspool file, then it'd lock out any new incoming mail from being posted
87 to the user's mailbox as it'd have a lock on the spool file, and the
88 message numbers could also possibly change while the user goes to select a
89 message number to read. This would be very confusing to the end user.
90
91 If you wish to allow users to use the internet or packet TCP/IP to pop3
92 their mail from your system, they may do so... however keep in mind, any
93 mail they read or list manually within axMail will have it's status
94 changed from "new". As we all know about the pop3 protocol, mail not
95 flagged as "new" isn't popped but it's considered as if the client is
96 using a software package such as eudora or outlook (to name a couple...
97 notice which I listed first? hi!) and they have their options set to leave
98 a copy of their mail on the server. The user will have to log into your
99 node and retrieve their mail from there. After all, isn't part of running
100 packet node services is to encourage hams to actually use their radios to
101 get to such things? :) All you as sysop/root on the box need to do is
102 ensure that a pop3 daemon is installed and running, and that you configure
103 axMail.conf to give the end user proper permissions in their shell to be
104 able to use your pop3 daemon.
105
106 I've gone to many days worth of studying how most boxes are configured
107 I've taken it upon myself to try and get axMail as 'bullet proof' and as
108 simple a process as it can possibly be. Unfortunately the program can not
109 read your mind so you'll have to do *some* config work to it... but
110 otherwise it should be a nice low-ram low-resource system for you and your
111 users to enjoy.
112
113 Comments and questions are always welcomed!
114
115 73 de Brian N1URO
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axMail 2.11.1
27 Updated February 21, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
28 - removed the #ifdef CLAMSMTP routine from config.h
29 - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer
30 needs to be previously defined in config.h and auto senses now in mailcmd.c.
31 It dawned on me that the reason it was segfaulting if there was no .conf
32 file that trying to fclose() a file that did not exist was the reason that
33 it was causing axmail to segfault.
34 - made this version 2.11.1 in defines.h.
35 - updated INSTALL and README to reflect history and instructions.
36 - updated Makefile so make upgrade does not replace config files since
37 it's not required if you're simply upgrading from axmail-2.9 or greater.
38 axmail 2.11
39 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
40 - Figured out how to add ClamSMTP to the mail system's MTA. Details
41 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
42 This will scan for viri both IN and OUT bound mails! Very handy!
43 - Added a define routine in config.h now. You must #define or #undef
44 CLAMSMTP based on whether or not you're running clamsmtp and have
45 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
46 create a symlink to it and you'll be fine.
47 - added the fact when #defined where mails are tagged with the fact that
48 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
49 - upped the version to 2.11 in defines.h
50 - added notes in INSTALL in regards to the new #define in config.h
51 axmail 2.10
52 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
53 - added online help for the "Delivery Receipt" command. This keeps
54 it in line with all the other online helps.
55 - modified defines.h with this version number and also increased the
56 year that I'm still working on modifications to the project.
57 axmail 2.9
58 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
59 - Removed asking for password upon new user login, instead added a new
60 field to axmail.conf for "SysopMail". Now the sysop has to put in their
61 email address as to inform the end user to request their desired password
62 into the system, especially if the sysop is running pop/imap features on
63 their system. This will prevent users from entering in plain text passwords
64 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
65 a major security fix for axMail-FAX.
66 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
67 another program changed the user's mail spool file the warning displays
68 clearer.
69 - changed version number to 2.9 in defines.h and changed the end year of
70 maintenance from 2017 to 2018.
71
72 axmail 2.8
73 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
74 Changes:
75 - added SPers as a command per the suggestion of VE1JOT. This was done in
76 command.c and was actually quite simple to impliment. The logic behind
77 it is to match the mail send command sets with those of standard PBBS
78 messaging commands.
79 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
80 urged that flags, cc, and bcc options be supressed to make it more user
81 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
82 do have compassion for those on HF. Steve gave me a different idea than
83 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
84 and command.c. If one needs a read receipt or to send cc/bcc copies of
85 their message then S still is an option.
86 - added a "spers" .hlp file to the archive.
87 - changed defines.h to reflect version 2.8.
88 - updated welcome.txt to be more generic rather than be version specific.
89 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
90 mail. This allows for a duplicate of the message to be sent to the second
91 person one wishes to copy on the mail.
92 - edited this file.
93 - while I was at it, I decided to add a "blind carbon copy" feature.
94 This will send a copy of a message to the user specified HOWEVER,
95 they will NOT be listed in the recipient listings. For those using
96 raw terminals, it's possible to NOT enter a 'cc' but still enter a
97 'bcc' address.
98 - edited help files: send.hlp and spersonal.hlp to help guide users
99 on how to best send mail.
100 - created a bypass method so that if users did not wish to use cc or bcc
101 mail, they can bypass them instead of being prompted for them - suggested
102 by VE1JOT.
103 - added online help for send/sp|cc|bcc mail.
104 - added a new signature file function to the system in both command.c and in
105 mailcmd.c. If no signature file exists, it will instruct the user on this
106 fact and also inform them how to make one using the new SIgnature command.
107 Note: If no ~/.signature file exists mail will still be sent, just without
108 a 1 line siguature (max: 79 characters).
109 - bullet proofed both the autoforward and signature file routines in command.c
110 by insuring that a null string not only halts execution of both but also
111 removes both ~/.forward and ~/.signature files respectively.
112 - cleaned up the send signature a bit and added my little spam ad even if
113 there is no signature file present. This was done in mailcmd.c.
114 - added a string in the signature prompt which informs users how to clear
115 their signature if they desire such. This was done in utils.c
116 - Added special critical instructions to INSTALL. I didn't know if I had
117 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
118 - Fixed a bug that when the mailbox file(s) weren't found for the system
119 MTA (aka: postfix) axMail would segfault. Now not only does it not
120 segfault but also instructs the user to inform the sysop of this error.
121 This bug existed since version 0.0.1. I've been wanting to do something
122 about this for IONs but didn't get to it until now. This was done in quit.c
123 - Fixed a couple of typos in README. I have a very difficult keyboard!
124 - Per the suggestion of G4APL (who gives us many great ideas - and why do
125 I refer to myself in plural? I need a DIET!) I did two things:
126 1 - when listing mail there's no message date stamp within the listing.
127 added in mailcmd.c
128 2 - reordered the mail listing fields where I felt they'd make the most
129 sense. Message subject, then message date, then message size are
130 the last 3 fields listed. They should also be kept in a column
131 justified manner of sorts.
132 3 - added a (St)atus header so the user has a better definition of
133 the status of a specific message.
134
135 axmail 2.7
136 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
137 Changes:
138 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
139 the user entered a parameter such as a message number for example,
140 it wouldn't properly function. This has been fixed. Thanks Van!
141 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
142 - I know in the past I had a 'cc' command for sending mail, and it's
143 been suck in my craw to readd it since.
144
145 axmail 2.6
146 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
147 Changes:
148 - changed version number in defines.h
149 - fixed error message when a pop client has deleted mail from the
150 main mail spool file.
151 - removed excessive receipt warning spotted by a gent who identifies
152 himself as rigor. This was in mailcmd.c in do_readmsg()
153 - while looking at the end of that routine, it just gave me an itch that
154 said "if you can look for a warning about a requested receipt, then
155 numbnutz you can offer the reader a chance to just generate a receipt
156 without having to do "SR" as previously stated at the end of the mail.
157 So, with that said and to get feeling back in my genitals, I wrote a
158 routine that asks the reader if they wish to send a receipt, and it
159 also echos where it's destined and confirmation it was sent.
160 - added an "--- end of message #* ---" tag at the end of mail when it
161 as finished displaying. This was done in mailcmd.c
162 - fixed an existing bug in the message routines where for each message
163 it wasn't resetting the receipt pointer! This bug existed since I
164 introduced the receipt "finder" in the messages. I'm shocked that
165 it wasn't reported to me by someone earlier. Now *only* if a message
166 has requested a receipt will it show that a receipt has been asked
167 for... whew!
168 - So many missing online help files! Again I'm surprised no one brought
169 this to my attention. How did we get along with them? "Oh my!" - Sulu
170 - Updated this README file.
171
172 axmail v2.5.1
173 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
174 Changes:
175 - added axmail.8 man page as per spec of Debian downstream.
176 - modified Makefile to include axmail.8 manpage installation for both
177 new and upgrade options.
178 - modified defines.h and this document to reflect maintenance release.
179
180 axmail v2.5
181 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
182 Changes:
183 - added new delivery receipt function to the send routine. This
184 compliments the read receipt function in the event of high
185 priority mail. Typically the read receipt is an option generated
186 by the recipient who may not decide to generate one. At least this
187 modification ensures with an ESMTP delivery that the sender using
188 axMail will get a reciept from "MAILER-DAEMON" which will verify
189 the status of delivered mail. This change was done in mailcmd.c
190 and is designed with the sendmail binary included with postfix.
191 - updated this README file.
192 - updated version number in defines.h
193
194 axmail v2.4
195 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
196 Changes:
197 - cleaned up mbox.c where I had originally placed the receipt checker
198 routine in. This caused loops within the buffer that displayed the
199 message. The true routine lives in mailcmd.c
200 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
201 downstream compiles to make packages.
202 - changed version in defines.h
203 - major change in command.c, added a new Autofwd command to allow users to
204 auto-forward mail from a remote system to their "home" axMail-FAX base
205 system. Could also be used to forward mail to their internet accounts.
206 - added autofwd.hlp file.
207 - alphabetized the commandset listing, removed redundantly spelled commands.
208 - reworked Makefile and added an "upgrade" option so new files ONLY are
209 deployed after make. Execute using: "make upgrade"
210 - updated this file.
211
212 axmail v2.3.1
213 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
214 Changes:
215 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
216 message, a bell and a warning sign is generated after the message has been
217 read by the user with instructions to use SR to generate a receipt. This
218 was a difficult routine for me to think of considering the various race
219 conditions that can be expected and met.
220 - updated welcome.txt with version upgrade and new feature list.
221 - updated README.
222
223 axmail v2.3
224 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
225 Changes:
226 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
227 This defaults to NO but when flagged to YES, a request will be sent to the
228 remote client's agent. If the agent supports such, they will be prompted
229 whether or not to honor your receipt request. This is history as NO AGENT
230 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
231 receipt is similar to how HylaFax generates confirmation of transmission
232 receipt mails to your mailbox. Currently mail read in axMail will NOT
233 generate a receipt back. I may work on this later, but for now it doesn't
234 exist.
235 * My thoughts of the receipt function is negative. The fact that I may be
236 sending notification that I'm in my email client to a remote destination
237 IMHO is such that a webcam may as well be turned on and watch me do email,
238 and send the stream to "Big Brother" and I don't mean the television show.
239 </rant>
240 - Updated defines.h with the new version number.
241 - Updated welcome.txt so the new version number is displayed.
242
243 axmail v2.2
244 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
245 Changes:
246 - Made some maintenance changes, but forgot to log them in here.
247 axmail v2.1.1
248 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
249 Changes:
250 - Makefile
251 Code provided by Bob Tenty VE3TOK to make it more compatable
252 with newer GCC compiler requirements.
253 - utils.c
254 Code provided by Bob Tenty VE3TOK to fix a warning produced when
255 compiling.
256 - defines.h
257 Changed version number to reflect the changes incorporated by
258 Bob Tenty VE3TOK and committed to the subversion repository.
259
260 axmail v2.1
261 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
262 Changes:
263 - axmail.c
264 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
265 the system privilege matching.
266 - global
267 axMail is now under review for considerations as standard packaging in
268 RedHat's fedora project. It appears it's going to be added as a package.
269
270 axmail v2.0
271 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
272 Changes:
273 - defines.h
274 Updated version number to reflect version release 2.0. Version 1.0.5
275 was simply a maintenance test package to try and reincorporate what
276 I had done up to version 1.0.6 which I believe was one of my last
277 releases up to 2009. Since I've done all that I can recall at this
278 point and time, I decided to match URONode's release numerics with
279 a 2.0 release version.
280
281 axmail v1.0.5
282 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
283 Changes:
284 - defines.h
285 Updated email listings to reflect the most current ones I could find
286 including my own. Also added 2013 to the years worked on axMail by
287 me.
288 - quit.c
289 Forced ALL mail, read or otherwise when user quits to save to the
290 user's system mailbox. This is for reverse compatability with those
291 who may also run a web-based email service on the internet such as
292 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
293 any read mail (and all accompanying mail in that session) to the
294 axmail ~/mbox file. We don't want this for the specific reason of
295 "reverse email client" compatability.
296
297 axmail v1.0.4
298 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
299 Changes:
300 - setpwnam.c
301 Changed the way SIGPIPE was handled. Instead of being ignored, it will
302 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
303 a shell prompt, or a node frontend. I've been noticing especially on
304 some timeouts that temp files don't flush as they should and the
305 user's directory can start to fill up.
306
307 axMail v1.0.3
308 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
309 Changes:
310 - mailcmd.c
311 Reset the way I wanted to handle the user input routine for sending faxes.
312 Commented out some more unneeded/unused code in the do_fax routine... will
313 clean it up in next release or so.
314 - mailcmd.c
315 cleaned up a bug I introduced in the never released 1.0.2 where the
316 X-Mailer was duping itself after each line of the body of a message.
317 - sfax.hlp
318 Reworded the SFax help file to help show some examples of how to format
319 the header.
320
321 axMail v1.0.2
322 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
323 Changes:
324 - mailcmd.c
325 Cleaned up some of the code in SFax. Also made some cosmetic changes.
326
327 axMail v1.0.1
328 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
329 Changes:
330 - mailcmd.c
331 Added a new routine to allow users to send faxes. This is defined by the
332 command "SF" for Send Fax. The routine was taken from the "S"end function
333 however since it's a one-way transmission, there is no reply available
334 nor is there an option for users to fax to any fax service as some I know
335 are pay services.
336 - config.h
337 added definitions for faxgate in axmail.conf
338 - config.c
339 added routine to allow for faxgate as a variable and be called from
340 mailcmd.c
341 - defines.h
342 version upgraded from v1.0.0 (unreleased - test version) to
343 v1.0.1
344 - etc/axmail.conf
345 Added new line called "FaxGate" with an example of how to properly
346 configure this line.
347 - etc/help/sfax.hlp
348 Added new file "sfax.hlp" which is an online help file for the SFax
349 command.
350
351 axMail v0.0.9
352 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
353 Changes:
354 - mailcmd.c
355 Added a new routine that prompts the sender whether or not the message
356 is of an emergency/high priority mail message. If it's emergency message
357 then the headers are appended with an X-code flagged in such a manner
358 that Eudora and Outlook will display the received mail with a red flag
359 of sorts. The idea of such came to me in thinking of "what can I do
360 to help improve means of emergency communications using TCP/IP, Linux,
361 and packet radio?" Having the ability to "red flag" an SMTP message
362 I don't believe has yet to be available in any packet messaging
363 system... axMail I hope is the first.
364
365 If a user just hits enter, or selects "no" then the mail message
366 is sent under normal send routines.
367
368 found a minor bug in my routine where if an end user answered
369 "yes" in wanting to send an emergency/high priority message the system
370 ignored the request and sent it as 'normal' delivery. Made a minor
371 change to bullet-proof the responce.
372
373 Added online help text if user is unsure about sending a message
374 flagged urgent or normal. This text is available when the user is
375 prompted for priority selection by hitting "?" at the prompt.
376 - defines.h
377 Version updated from v0.0.8 to v0.0.9
378
379 axMail v0.0.8
380 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
381
382 Changes:
383 - mailcmd.c
384 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
385 it's version number in the X-Mailer: string.
386 - mailcmd.c
387 Added an X-Origin: string to show those peeking at mail headers
388 just how the message was possibly sent... by AMATEUR RADIO!
389 - axmail.conf
390 Added config option in "AllowMail" for axhome, a rewrite of code
391 submitted by Stefano IW3IJQ. While I stripped out home directory
392 structures similar to that of qmail or axspawn, Stefano convinced
393 me that it may be easier to manage home directories for axMail users
394 who don't have shell access to branch out within a preset directory.
395 - defines.h
396 Updated version number from 0.0.7 to 0.0.8
397 - axmail.c and config.c
398 Rewrote and incorporated code to allow for the routines to use
399 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
400 While I was at it, I rewrote and shortened the error text pushed
401 to a user who doesn't have permission to use such a directory.
402 * Note: When I write error texts and menus, I try to write them for
403 users on a multi-hop 1200 baud path thus the shorter the better as
404 long as context isn't lost and for long distance hops where full
405 paclen may cause retries (worse yet timeouts!)
406
407 axMail v0.0.7
408
409 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
410
411 Changes:
412 - cosmetics
413 My usual "I like seeing this this way" type cosmetics... too many
414 to mention!
415 - adduser.c
416 changed the hard coding of user 'home' directories so that instead
417 of them going into a period delimited sort, just dump em all into
418 /home/<user> which seems to be "the norm" on most systems I've had
419 to assist with.
420 - adduser.c
421 fixed a bug where creating a user was actually causing the program to
422 segfault upon exit the first time a user went into the mailbox! The
423 node frontends hid this segfault as the program still flushed itself
424 from ram but I spotted it when running it at a command prompt. The
425 segfault came when axMail attempted to write mail back to the user's
426 system mailbox and it didn't exist. How I fixed this is listed next.
427 This may just be a new bug that appeared with the upgrading of libs,
428 this I'm unsure of and since I have no desire to go backwards I have
429 decided to actually make a minor routine...
430 - welcome.txt
431 New users are now sent a "welcome" message that the sysop can easily
432 customize to their desires. It's located at /etc/ax25/welcome.txt.
433 I figured that since axMail was segfaulting because such a file did
434 not exist, I might as well make use of this need by having the program
435 send the user a greeting.
436 - defines.h
437 Changed paths to be more in line with the more modern type configs
438 as a default. Paths can still be defined by the sysop prior to
439 compiling axMail.
440 - Makefile
441 I changed the default of make install to include all of the subroutines
442 within the Makefile yet leaving such things as "make installbin"
443 available as runtime options if just a binary refresh creation is
444 desired.
445 - other
446 I'm sure I missed a note or two *shrug*
447
448 axMail v0.0.6
449
450 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
451 I at one time had but lost and can't seem to find it. My (n1uro)
452 changes may have alread been incorporated.
453
454 axMail v0.0.5
455
456 True mailbox functionalities created by Marius Petrescu.
457 Added Mailbox save routines (compatible with the command line
458 mail agent, including ~/mbox file)
459
460 axMail v0.0.4
461
462 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
463
464 This program is free software; you can redistribute it and/or modify
465 it under the terms of the GNU General Public License as published by
466 the Free Software Foundation; either version 2 of the License, or
467 (at your option) any later version.
468
469 This program is distributed in the hope that it will be useful,
470 but WITHOUT ANY WARRANTY; without even the implied warranty of
471 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
472 GNU General Public License for more details.
473
474 You should have received a copy of the GNU General Public License
475 along with this program; if not, write to the Free Software
476 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
477
478
479 Don't give this one to anyone yet... it is NOT ready for distribution!
480
481 This is a simple mail user agent intended to provide the
482 mail functions in xNOS in a Linux ax.25 environment. If required,
483 it creates a normal user account for each new user (code mostly taken
484 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
485 on the system. axMail uses sendmail (or similar) to deliver mail, and
486 reads mail from each user's system mailbox (/var/spool/mail/username).
487 It does not provide any means of transferring mail between hosts.
488
489 axMail provides a simple, low-overhead user interface, much similar
490 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
491 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
492
493 axMail is intended to be called from node. It takes one command
494 line argument of the user's callsign (with or without SSID). It must
495 be run as root, but it setuid()'s itself to the respective user's
496 privileges as soon as possible. It might run from ax25d as well.
497 It can also be executed from a shell with user privileges.
498
499 Some code (command parser, configuration file stuff) and the internal
500 architecture was taken from the LinuxNode frontend by Tomi Manninen
501 (OH2BNS). Thanks!
502
503 INSTALLATION:
504
505 See the file: INSTALL
506
507 TODO:
508 Suggestions?
509
510 --
511 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
512 ftp://ftp.n1uro.net/pub/hamradio/packet
0 /* command.c - Commands which have nothing to do with mail... */
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <unistd.h>
6 #include <time.h>
7
8 #include "defines.h"
9 #include "command.h"
10 #include "config.h"
11 #include "mailcmd.h"
12 #include "mbox.h"
13 #include "utils.h"
14 #include "quit.h"
15
16 void getsig(char *signature);
17 void getaddy(char *forward);
18
19 struct cmd Mailcmds[] = {
20 { "?", do_help },
21 { "Autofwd", do_forward },
22 { "Bye", do_exit },
23 { "Cancel", do_quit },
24 { "Delete", do_kill },
25 { "Exit", do_exit },
26 { "Help", do_help },
27 { "Info", do_help },
28 { "Kill", do_kill },
29 { "List", do_list },
30 { "Name", do_name },
31 { "Quit", do_exit },
32 { "Read", do_read },
33 { "Send", do_send },
34 { "SFax", do_fax },
35 { "SIg", do_signature },
36 { "SPers", do_psend },
37 { "SReply", do_send },
38 { "STatus", do_status },
39 { "Unkill", do_unkill },
40 { "Verbose", do_read },
41 { NULL, NULL }
42 };
43
44 int do_status(int argc, char **argv)
45 {
46 printf("Messages: %i\n", messages);
47 return 0;
48
49 }
50
51 int do_name(int argc, char **argv)
52 {
53 char name[32];
54
55 getname(name);
56
57 if (strlen(name) == 0)
58 printf("Name not changed. ");
59 else { /* Okay, save it */
60 strcpy(fullname, name);
61 }
62
63 printf("You're now known as %s.\n", fullname);
64
65 return 0;
66 }
67
68 /* int do_forward(int argc, char **argv) */
69 int do_forward(int argc, char **argv)
70 {
71 char *email;
72 char *fwdfile;
73 char fwd[79];
74 char forward[79];
75
76 getaddy(fwd);
77 FILE *fptr;
78
79 sprintf(forward, "%s/.forward", homedir);
80 fwdfile = strdup(forward);
81 fptr = fopen(fwdfile, "w+");
82 fprintf(fptr, "%s", fwd);
83 while (! *fwd) {
84 fclose(fptr);
85 remove(fwdfile);
86 printf("Forwarding halted, forward file removed.\n");
87 return 0;
88 }
89 printf("You're mail will be sent to:\n%s\nThank you.\n", fwd);
90 fclose(fptr);
91 return 0;
92 }
93
94 /* int do_signature(int argc, char **argv) */
95 int do_signature(int argc, char **argv)
96 {
97 char *sigfile;
98 char sig[79];
99 char signature[79];
100
101 getsig(sig);
102 FILE *fptr;
103
104 sprintf(signature, "%s/.signature", homedir);
105 sigfile = strdup(signature);
106 fptr = fopen(sigfile, "w+");
107 fprintf(fptr, "%s\n", sig);
108 while (! *sig) {
109 fclose(fptr);
110 remove(sigfile);
111 printf("Signature file deleted.\n");
112 return 0;
113 }
114 printf("You're signature is set to:\n%s\nThank you.\n", sig);
115 fclose(fptr);
116 return 0;
117 }
118
119 int do_help(int argc, char **argv)
120 {
121 FILE *fp;
122 char fname[80], line[256];
123 struct cmd *cmdp;
124 int i = 0;
125
126 if (*argv[0] == '?') { /* "?" */
127 printf("Commands:\n");
128 for (cmdp = Mailcmds; cmdp->name != NULL; cmdp++) {
129 printf("%s%s", i ? ", " : "", cmdp->name);
130 if (++i == 10) {
131 printf("\n");
132 i = 0;
133 }
134 }
135 if (i) printf("\n");
136 return 0;
137 }
138 strcpy(fname, DATA_AXMAIL_HELP_DIR);
139 if (*argv[0] == 'i') { /* "info" */
140 strcat(fname, "info.hlp");
141 printf("%s - %s\n", VERSION, COPYRIGHT);
142 printf("%s", LICENSE);
143 } else if (argc == 1) { /* "help" */
144 strcat(fname, "help.hlp");
145 } else { /* "help <cmd>" */
146 if (strchr(argv[1], '/') == NULL) {
147 strlwr(argv[1]);
148 strcat(fname, argv[1]);
149 strcat(fname, ".hlp");
150 }
151 }
152 if ((fp = fopen(fname, "r")) == NULL) {
153 if (*argv[0] != 'i')
154 printf("No help for command %s.\n", argv[1] ? argv[1] : "help");
155 return 0;
156 }
157 if (*argv[0] != 'i')
158 printf("Help for command %s:\n", argv[1] ? argv[1] : "help");
159 while (fgets(line, 256, fp) != NULL) {
160 printf("%s", line);
161 }
162 fclose(fp);
163 return 0;
164 }
165
166 int do_quit(int argc, char **argv)
167 {
168 quit(0, 0);
169 return 0;
170 }
171
172 int do_exit(int argc, char **argv)
173 {
174 quit(1, 0);
175 return 0;
176 }
177
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axMail 2.13
27 Updated June 24, 2021
28 - Went through the code and fixed multiple compile warnings. Warnings do not
29 affect the program/binary from compiling or funcitioning BUT rather gives
30 the author(s) a warning that possible compile instructions may have changed
31 or are changing.
32
33 axMail 2.12.2
34 Updated January 18, 2021
35 - Fixed bug in mailcmd.c where sending acted funky on 64 bit systems.
36 axMail would segfault out before properly returning the user back to
37 the mailbox prompt.
38 - While at it also fixed some compiler warnings in mailcmd.c
39 - edited defines.h to fix old path from /var/ax25 to /var/lib/ax25
40 - edited defines.h to reflect this version.
41
42 axMail 2.12.1
43 Updated January 17, 2021
44 - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail
45 to honor linux file system rules.
46 - Changed defines.h to reflect this version.
47 axMail 2.12
48 Updated August 17, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
49 - After fussing with an updated ClamSMTP system that appears to have some
50 issues at least in regards to the Debian repositories I have come to
51 learn that the MTA used (postfix) beginning with version 2.3 now may
52 use milter (mail filter) systems. Details on how to configure the newer
53 ClamAV-Milter system are at https://uronode.n1uro.com/linux/ under the
54 ClamSMTP link at the bottom of the page. This is quite a major enhancement
55 to axMail-Fax!
56
57 Since now it will scan for either clamsmtp OR clamav-milter the outputs
58 on mails show only that the mail has been scanned by ClamAV.
59 axMail 2.11.1
60 Updated February 21, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
61 - removed the #ifdef CLAMSMTP routine from config.h
62 - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer
63 needs to be previously defined in config.h and auto senses now in mailcmd.c.
64 It dawned on me that the reason it was segfaulting if there was no .conf
65 file that trying to fclose() a file that did not exist was the reason that
66 it was causing axmail to segfault.
67 - made this version 2.11.1 in defines.h.
68 - updated INSTALL and README to reflect history and instructions.
69 - updated Makefile so make upgrade does not replace config files since
70 it's not required if you're simply upgrading from axmail-2.9 or greater.
71 axmail 2.11
72 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
73 - Figured out how to add ClamSMTP to the mail system's MTA. Details
74 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
75 This will scan for viri both IN and OUT bound mails! Very handy!
76 - Added a define routine in config.h now. You must #define or #undef
77 CLAMSMTP based on whether or not you're running clamsmtp and have
78 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
79 create a symlink to it and you'll be fine.
80 - added the fact when #defined where mails are tagged with the fact that
81 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
82 - upped the version to 2.11 in defines.h
83 - added notes in INSTALL in regards to the new #define in config.h
84 axmail 2.10
85 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
86 - added online help for the "Delivery Receipt" command. This keeps
87 it in line with all the other online helps.
88 - modified defines.h with this version number and also increased the
89 year that I'm still working on modifications to the project.
90 axmail 2.9
91 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
92 - Removed asking for password upon new user login, instead added a new
93 field to axmail.conf for "SysopMail". Now the sysop has to put in their
94 email address as to inform the end user to request their desired password
95 into the system, especially if the sysop is running pop/imap features on
96 their system. This will prevent users from entering in plain text passwords
97 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
98 a major security fix for axMail-FAX.
99 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
100 another program changed the user's mail spool file the warning displays
101 clearer.
102 - changed version number to 2.9 in defines.h and changed the end year of
103 maintenance from 2017 to 2018.
104
105 axmail 2.8
106 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
107 Changes:
108 - added SPers as a command per the suggestion of VE1JOT. This was done in
109 command.c and was actually quite simple to impliment. The logic behind
110 it is to match the mail send command sets with those of standard PBBS
111 messaging commands.
112 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
113 urged that flags, cc, and bcc options be supressed to make it more user
114 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
115 do have compassion for those on HF. Steve gave me a different idea than
116 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
117 and command.c. If one needs a read receipt or to send cc/bcc copies of
118 their message then S still is an option.
119 - added a "spers" .hlp file to the archive.
120 - changed defines.h to reflect version 2.8.
121 - updated welcome.txt to be more generic rather than be version specific.
122 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
123 mail. This allows for a duplicate of the message to be sent to the second
124 person one wishes to copy on the mail.
125 - edited this file.
126 - while I was at it, I decided to add a "blind carbon copy" feature.
127 This will send a copy of a message to the user specified HOWEVER,
128 they will NOT be listed in the recipient listings. For those using
129 raw terminals, it's possible to NOT enter a 'cc' but still enter a
130 'bcc' address.
131 - edited help files: send.hlp and spersonal.hlp to help guide users
132 on how to best send mail.
133 - created a bypass method so that if users did not wish to use cc or bcc
134 mail, they can bypass them instead of being prompted for them - suggested
135 by VE1JOT.
136 - added online help for send/sp|cc|bcc mail.
137 - added a new signature file function to the system in both command.c and in
138 mailcmd.c. If no signature file exists, it will instruct the user on this
139 fact and also inform them how to make one using the new SIgnature command.
140 Note: If no ~/.signature file exists mail will still be sent, just without
141 a 1 line siguature (max: 79 characters).
142 - bullet proofed both the autoforward and signature file routines in command.c
143 by insuring that a null string not only halts execution of both but also
144 removes both ~/.forward and ~/.signature files respectively.
145 - cleaned up the send signature a bit and added my little spam ad even if
146 there is no signature file present. This was done in mailcmd.c.
147 - added a string in the signature prompt which informs users how to clear
148 their signature if they desire such. This was done in utils.c
149 - Added special critical instructions to INSTALL. I didn't know if I had
150 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
151 - Fixed a bug that when the mailbox file(s) weren't found for the system
152 MTA (aka: postfix) axMail would segfault. Now not only does it not
153 segfault but also instructs the user to inform the sysop of this error.
154 This bug existed since version 0.0.1. I've been wanting to do something
155 about this for IONs but didn't get to it until now. This was done in quit.c
156 - Fixed a couple of typos in README. I have a very difficult keyboard!
157 - Per the suggestion of G4APL (who gives us many great ideas - and why do
158 I refer to myself in plural? I need a DIET!) I did two things:
159 1 - when listing mail there's no message date stamp within the listing.
160 added in mailcmd.c
161 2 - reordered the mail listing fields where I felt they'd make the most
162 sense. Message subject, then message date, then message size are
163 the last 3 fields listed. They should also be kept in a column
164 justified manner of sorts.
165 3 - added a (St)atus header so the user has a better definition of
166 the status of a specific message.
167
168 axmail 2.7
169 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
170 Changes:
171 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
172 the user entered a parameter such as a message number for example,
173 it wouldn't properly function. This has been fixed. Thanks Van!
174 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
175 - I know in the past I had a 'cc' command for sending mail, and it's
176 been suck in my craw to readd it since.
177
178 axmail 2.6
179 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
180 Changes:
181 - changed version number in defines.h
182 - fixed error message when a pop client has deleted mail from the
183 main mail spool file.
184 - removed excessive receipt warning spotted by a gent who identifies
185 himself as rigor. This was in mailcmd.c in do_readmsg()
186 - while looking at the end of that routine, it just gave me an itch that
187 said "if you can look for a warning about a requested receipt, then
188 numbnutz you can offer the reader a chance to just generate a receipt
189 without having to do "SR" as previously stated at the end of the mail.
190 So, with that said and to get feeling back in my genitals, I wrote a
191 routine that asks the reader if they wish to send a receipt, and it
192 also echos where it's destined and confirmation it was sent.
193 - added an "--- end of message #* ---" tag at the end of mail when it
194 as finished displaying. This was done in mailcmd.c
195 - fixed an existing bug in the message routines where for each message
196 it wasn't resetting the receipt pointer! This bug existed since I
197 introduced the receipt "finder" in the messages. I'm shocked that
198 it wasn't reported to me by someone earlier. Now *only* if a message
199 has requested a receipt will it show that a receipt has been asked
200 for... whew!
201 - So many missing online help files! Again I'm surprised no one brought
202 this to my attention. How did we get along with them? "Oh my!" - Sulu
203 - Updated this README file.
204
205 axmail v2.5.1
206 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
207 Changes:
208 - added axmail.8 man page as per spec of Debian downstream.
209 - modified Makefile to include axmail.8 manpage installation for both
210 new and upgrade options.
211 - modified defines.h and this document to reflect maintenance release.
212
213 axmail v2.5
214 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
215 Changes:
216 - added new delivery receipt function to the send routine. This
217 compliments the read receipt function in the event of high
218 priority mail. Typically the read receipt is an option generated
219 by the recipient who may not decide to generate one. At least this
220 modification ensures with an ESMTP delivery that the sender using
221 axMail will get a reciept from "MAILER-DAEMON" which will verify
222 the status of delivered mail. This change was done in mailcmd.c
223 and is designed with the sendmail binary included with postfix.
224 - updated this README file.
225 - updated version number in defines.h
226
227 axmail v2.4
228 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
229 Changes:
230 - cleaned up mbox.c where I had originally placed the receipt checker
231 routine in. This caused loops within the buffer that displayed the
232 message. The true routine lives in mailcmd.c
233 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
234 downstream compiles to make packages.
235 - changed version in defines.h
236 - major change in command.c, added a new Autofwd command to allow users to
237 auto-forward mail from a remote system to their "home" axMail-FAX base
238 system. Could also be used to forward mail to their internet accounts.
239 - added autofwd.hlp file.
240 - alphabetized the commandset listing, removed redundantly spelled commands.
241 - reworked Makefile and added an "upgrade" option so new files ONLY are
242 deployed after make. Execute using: "make upgrade"
243 - updated this file.
244
245 axmail v2.3.1
246 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
247 Changes:
248 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
249 message, a bell and a warning sign is generated after the message has been
250 read by the user with instructions to use SR to generate a receipt. This
251 was a difficult routine for me to think of considering the various race
252 conditions that can be expected and met.
253 - updated welcome.txt with version upgrade and new feature list.
254 - updated README.
255
256 axmail v2.3
257 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
258 Changes:
259 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
260 This defaults to NO but when flagged to YES, a request will be sent to the
261 remote client's agent. If the agent supports such, they will be prompted
262 whether or not to honor your receipt request. This is history as NO AGENT
263 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
264 receipt is similar to how HylaFax generates confirmation of transmission
265 receipt mails to your mailbox. Currently mail read in axMail will NOT
266 generate a receipt back. I may work on this later, but for now it doesn't
267 exist.
268 * My thoughts of the receipt function is negative. The fact that I may be
269 sending notification that I'm in my email client to a remote destination
270 IMHO is such that a webcam may as well be turned on and watch me do email,
271 and send the stream to "Big Brother" and I don't mean the television show.
272 </rant>
273 - Updated defines.h with the new version number.
274 - Updated welcome.txt so the new version number is displayed.
275
276 axmail v2.2
277 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
278 Changes:
279 - Made some maintenance changes, but forgot to log them in here.
280 axmail v2.1.1
281 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
282 Changes:
283 - Makefile
284 Code provided by Bob Tenty VE3TOK to make it more compatable
285 with newer GCC compiler requirements.
286 - utils.c
287 Code provided by Bob Tenty VE3TOK to fix a warning produced when
288 compiling.
289 - defines.h
290 Changed version number to reflect the changes incorporated by
291 Bob Tenty VE3TOK and committed to the subversion repository.
292
293 axmail v2.1
294 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
295 Changes:
296 - axmail.c
297 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
298 the system privilege matching.
299 - global
300 axMail is now under review for considerations as standard packaging in
301 RedHat's fedora project. It appears it's going to be added as a package.
302
303 axmail v2.0
304 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
305 Changes:
306 - defines.h
307 Updated version number to reflect version release 2.0. Version 1.0.5
308 was simply a maintenance test package to try and reincorporate what
309 I had done up to version 1.0.6 which I believe was one of my last
310 releases up to 2009. Since I've done all that I can recall at this
311 point and time, I decided to match URONode's release numerics with
312 a 2.0 release version.
313
314 axmail v1.0.5
315 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
316 Changes:
317 - defines.h
318 Updated email listings to reflect the most current ones I could find
319 including my own. Also added 2013 to the years worked on axMail by
320 me.
321 - quit.c
322 Forced ALL mail, read or otherwise when user quits to save to the
323 user's system mailbox. This is for reverse compatability with those
324 who may also run a web-based email service on the internet such as
325 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
326 any read mail (and all accompanying mail in that session) to the
327 axmail ~/mbox file. We don't want this for the specific reason of
328 "reverse email client" compatability.
329
330 axmail v1.0.4
331 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
332 Changes:
333 - setpwnam.c
334 Changed the way SIGPIPE was handled. Instead of being ignored, it will
335 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
336 a shell prompt, or a node frontend. I've been noticing especially on
337 some timeouts that temp files don't flush as they should and the
338 user's directory can start to fill up.
339
340 axMail v1.0.3
341 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
342 Changes:
343 - mailcmd.c
344 Reset the way I wanted to handle the user input routine for sending faxes.
345 Commented out some more unneeded/unused code in the do_fax routine... will
346 clean it up in next release or so.
347 - mailcmd.c
348 cleaned up a bug I introduced in the never released 1.0.2 where the
349 X-Mailer was duping itself after each line of the body of a message.
350 - sfax.hlp
351 Reworded the SFax help file to help show some examples of how to format
352 the header.
353
354 axMail v1.0.2
355 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
356 Changes:
357 - mailcmd.c
358 Cleaned up some of the code in SFax. Also made some cosmetic changes.
359
360 axMail v1.0.1
361 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
362 Changes:
363 - mailcmd.c
364 Added a new routine to allow users to send faxes. This is defined by the
365 command "SF" for Send Fax. The routine was taken from the "S"end function
366 however since it's a one-way transmission, there is no reply available
367 nor is there an option for users to fax to any fax service as some I know
368 are pay services.
369 - config.h
370 added definitions for faxgate in axmail.conf
371 - config.c
372 added routine to allow for faxgate as a variable and be called from
373 mailcmd.c
374 - defines.h
375 version upgraded from v1.0.0 (unreleased - test version) to
376 v1.0.1
377 - etc/axmail.conf
378 Added new line called "FaxGate" with an example of how to properly
379 configure this line.
380 - etc/help/sfax.hlp
381 Added new file "sfax.hlp" which is an online help file for the SFax
382 command.
383
384 axMail v0.0.9
385 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
386 Changes:
387 - mailcmd.c
388 Added a new routine that prompts the sender whether or not the message
389 is of an emergency/high priority mail message. If it's emergency message
390 then the headers are appended with an X-code flagged in such a manner
391 that Eudora and Outlook will display the received mail with a red flag
392 of sorts. The idea of such came to me in thinking of "what can I do
393 to help improve means of emergency communications using TCP/IP, Linux,
394 and packet radio?" Having the ability to "red flag" an SMTP message
395 I don't believe has yet to be available in any packet messaging
396 system... axMail I hope is the first.
397
398 If a user just hits enter, or selects "no" then the mail message
399 is sent under normal send routines.
400
401 found a minor bug in my routine where if an end user answered
402 "yes" in wanting to send an emergency/high priority message the system
403 ignored the request and sent it as 'normal' delivery. Made a minor
404 change to bullet-proof the responce.
405
406 Added online help text if user is unsure about sending a message
407 flagged urgent or normal. This text is available when the user is
408 prompted for priority selection by hitting "?" at the prompt.
409 - defines.h
410 Version updated from v0.0.8 to v0.0.9
411
412 axMail v0.0.8
413 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
414
415 Changes:
416 - mailcmd.c
417 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
418 it's version number in the X-Mailer: string.
419 - mailcmd.c
420 Added an X-Origin: string to show those peeking at mail headers
421 just how the message was possibly sent... by AMATEUR RADIO!
422 - axmail.conf
423 Added config option in "AllowMail" for axhome, a rewrite of code
424 submitted by Stefano IW3IJQ. While I stripped out home directory
425 structures similar to that of qmail or axspawn, Stefano convinced
426 me that it may be easier to manage home directories for axMail users
427 who don't have shell access to branch out within a preset directory.
428 - defines.h
429 Updated version number from 0.0.7 to 0.0.8
430 - axmail.c and config.c
431 Rewrote and incorporated code to allow for the routines to use
432 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
433 While I was at it, I rewrote and shortened the error text pushed
434 to a user who doesn't have permission to use such a directory.
435 * Note: When I write error texts and menus, I try to write them for
436 users on a multi-hop 1200 baud path thus the shorter the better as
437 long as context isn't lost and for long distance hops where full
438 paclen may cause retries (worse yet timeouts!)
439
440 axMail v0.0.7
441
442 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
443
444 Changes:
445 - cosmetics
446 My usual "I like seeing this this way" type cosmetics... too many
447 to mention!
448 - adduser.c
449 changed the hard coding of user 'home' directories so that instead
450 of them going into a period delimited sort, just dump em all into
451 /home/<user> which seems to be "the norm" on most systems I've had
452 to assist with.
453 - adduser.c
454 fixed a bug where creating a user was actually causing the program to
455 segfault upon exit the first time a user went into the mailbox! The
456 node frontends hid this segfault as the program still flushed itself
457 from ram but I spotted it when running it at a command prompt. The
458 segfault came when axMail attempted to write mail back to the user's
459 system mailbox and it didn't exist. How I fixed this is listed next.
460 This may just be a new bug that appeared with the upgrading of libs,
461 this I'm unsure of and since I have no desire to go backwards I have
462 decided to actually make a minor routine...
463 - welcome.txt
464 New users are now sent a "welcome" message that the sysop can easily
465 customize to their desires. It's located at /etc/ax25/welcome.txt.
466 I figured that since axMail was segfaulting because such a file did
467 not exist, I might as well make use of this need by having the program
468 send the user a greeting.
469 - defines.h
470 Changed paths to be more in line with the more modern type configs
471 as a default. Paths can still be defined by the sysop prior to
472 compiling axMail.
473 - Makefile
474 I changed the default of make install to include all of the subroutines
475 within the Makefile yet leaving such things as "make installbin"
476 available as runtime options if just a binary refresh creation is
477 desired.
478 - other
479 I'm sure I missed a note or two *shrug*
480
481 axMail v0.0.6
482
483 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
484 I at one time had but lost and can't seem to find it. My (n1uro)
485 changes may have alread been incorporated.
486
487 axMail v0.0.5
488
489 True mailbox functionalities created by Marius Petrescu.
490 Added Mailbox save routines (compatible with the command line
491 mail agent, including ~/mbox file)
492
493 axMail v0.0.4
494
495 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
496
497 This program is free software; you can redistribute it and/or modify
498 it under the terms of the GNU General Public License as published by
499 the Free Software Foundation; either version 2 of the License, or
500 (at your option) any later version.
501
502 This program is distributed in the hope that it will be useful,
503 but WITHOUT ANY WARRANTY; without even the implied warranty of
504 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
505 GNU General Public License for more details.
506
507 You should have received a copy of the GNU General Public License
508 along with this program; if not, write to the Free Software
509 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
510
511
512 Don't give this one to anyone yet... it is NOT ready for distribution!
513
514 This is a simple mail user agent intended to provide the
515 mail functions in xNOS in a Linux ax.25 environment. If required,
516 it creates a normal user account for each new user (code mostly taken
517 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
518 on the system. axMail uses sendmail (or similar) to deliver mail, and
519 reads mail from each user's system mailbox (/var/spool/mail/username).
520 It does not provide any means of transferring mail between hosts.
521
522 axMail provides a simple, low-overhead user interface, much similar
523 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
524 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
525
526 axMail is intended to be called from node. It takes one command
527 line argument of the user's callsign (with or without SSID). It must
528 be run as root, but it setuid()'s itself to the respective user's
529 privileges as soon as possible. It might run from ax25d as well.
530 It can also be executed from a shell with user privileges.
531
532 Some code (command parser, configuration file stuff) and the internal
533 architecture was taken from the LinuxNode frontend by Tomi Manninen
534 (OH2BNS). Thanks!
535
536 INSTALLATION:
537
538 See the file: INSTALL
539
540 TODO:
541 Suggestions?
542
543 --
544 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
545 ftp://ftp.n1uro.net/pub/hamradio/packet
0 all: axmail
1
2 MAN_DIR = /usr/local/share/man
3 CC = gcc
4 LD = gcc
5 CFLAGS = -O2 -Wstrict-prototypes -g -I../lib
6 LIBS = -lcrypt
7 MODULES = utils.o config.o adduser.o command.o mailcmd.o mbox.o head.o lock.o axmail.o quit.o
8
9 .c.o:
10 $(CC) $(CFLAGS) -c $<
11
12 upgrade: installbin installhelp installman
13
14 install: installbin installconf installhelp installman
15
16 installbin: all
17 install -m 0755 -s -o root -g root axmail /usr/local/sbin
18
19 installconf:
20 install -m 755 -o root -g root -d /usr/local/etc/ax25
21 install -b -m 644 -o root -g root etc/axmail.conf /usr/local/etc/ax25
22 install -m 644 -o root -g root etc/welcome.txt /usr/local/etc/ax25
23
24 installhelp:
25 install -m 755 -o root -g root -d /usr/local/var/lib/ax25/axmail/help
26 install -m 644 -o root -g root etc/help/*.hlp /usr/local/var/lib/ax25/axmail/help
27
28 installman:
29 install -m 644 -p man/axmail.8 $(MAN_DIR)/man8
30 install -m 644 -p man/axmail.conf.5 $(MAN_DIR)/man5
31 back:
32 rm -f ../mail.tar.gz
33 tar cvf ../mail.tar *
34 gzip ../mail.tar
35
36 clean:
37 rm -f axmail *.o *~ *.bak core etc/*~ etc/help/*~
38
39 distclean: clean
40 rm -f axmail
41
42 axmail: $(MODULES)
43 $(LD) -o axmail $(MODULES) $(LIBS) $(LDFLAGS)
44
45 utils.o: utils.h utils.c mbox.h
46 config.o: config.h config.c defines.h axmail.h utils.h
47 adduser.o: adduser.h adduser.c utils.h config.h defines.h
48 command.o: command.h command.c config.h mailcmd.h mbox.h utils.h quit.h
49 mailcmd.o: mailcmd.h mailcmd.c defines.h utils.h mbox.h config.h
50 mbox.o: mbox.h mbox.c utils.h defines.h config.h head.h
51 head.o: head.h head.c defines.h
52 utils.o: utils.h utils.c
53 lock.o: lock.h lock.c utils.h
54 quit.o: quit.h quit.c config.h lock.h
55 axmail.o: axmail.h axmail.c config.h adduser.h utils.h quit.h mbox.h
0
1 /* in mailcmd.c */
2 extern int do_list(int argc, char **argv);
3 extern int do_read(int argc, char **argv);
4 extern int do_send(int argc, char **argv);
5 extern int do_psend(int argc, char **argv);
6 extern int do_fax(int argc, char **argv);
7 extern int do_kill(int argc, char **argv);
8 extern int do_unkill(int argc, char **argv);
9
0
1 /* in mailcmd.c */
2 extern int do_list(int argc, char **argv);
3 extern int do_read(int argc, char **argv);
4 extern int do_send(int argc, char **argv);
5 extern int do_psend(int argc, char **argv);
6 extern int do_fax(int argc, char **argv);
7 extern int do_kill(int argc, char **argv);
8 extern int do_unkill(int argc, char **argv);
0 .TH AXMAIL.CONF5 "28 September 2015" Linux "Linux System Managers Manual"
1 .SH NAME
2 axMail \- A powerful but simple SMTP plugin for URONode.
3 .SH SYNOPSIS
4 .B axmail.conf
5 .SH DESCRIPTION
6 .LP
7 .B axmail.conf
8 This file configures the operations of axMail\-FAX. You have to insure that
9 you add the proper group using addgroup. The common one to use is "ax25".
10 .SH COMMANDS
11 The following opions are supported for
12 .B axmail.conf:
13 .TP 14
14 .BI "IdleTimeout"
15 This should not be longer than the same command in uronode.conf.
16 .TP 14
17 .BI "HostName"
18 This is the fully qualified hostname of your mail system. Typically this
19 would be an amprnet domnain such as n1uro.ampr.org.
20 .TP 14
21 .BI "AllowMail"
22 This command controls who has access to use mail on your system. The
23 default is all.
24 .TP 14
25 .BI "Identification"
26 This shows how users can authenticate into the application. The default is
27 none as the password used over RF may also be used for popping/imap if
28 the local sysop chooses to do this.
29 Disconnect user from their mailbox."
30 .TP 14
31 .BI "AutoCreate"
32 This allows creation of the user accounts. Since you can also configure
33 dovecot or a pop3 daemon and pop-before-smtp to allow mail on smartphones
34 as well, this should be set to yes which is default.
35 .TP 14
36 .BI "LoginAllowed"
37 This grants or denies permissions for other functions such as ssh on the
38 box. This also controls access to imap/pop. Default is yes.
39 .TP 14
40 .BI "AutoGroup"
41 I suggest using ax25. You'll have to set this using addgroup ax25.
42 .TP 14
43 .BI "First_uid"
44 This is the first user id numeric to be used when axmail creates accounts.
45 I suggest 2000 as this keeps mail clients 1000 UID away from actual local
46 clients so it'll somewhat separate them this way.
47 .TP 14
48 .BI "Last_uid"
49 This sets just how many users may create and use mailboxes using axmail.
50 .TP 14
51 .BI "HomeDir"
52 This sets the base of the users home directory. I suggest using the
53 standard home directory for all users.
54 .TP 14
55 .BI "Shell"
56 This is the shell the users are granted. I suggest if you wish not to allow
57 ssh or telnet access into your server to use /bin/false.
58 .TP 14
59 .BI "FaxGate"
60 This is the efax gateway to send your faxes through to. The SFax command
61 will preformat your mail to use this gateway. Remove the quotes.
62 .SH FILES
63 .LP
64 .TP 5
65 .B /usr/local/etc/ax25/welcome.txt
66 Greeting file for new users to welcome them to the mail system.
67 .br
68 .TP 5
69 .B /etc/postfix/main.cf
70 postfix configuration file.
71 .br
72 .SH AUTHORS
73 Brian Rogers (N1URO) <n1uro@n1uro.com>
74 .br
75 .SH OTHERS
76 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>
77 .br
78 Bob Tenty (VE3TOK) <ve3tok@gmail.com>
79 .br
80 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.11"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2020 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 /* mailcmd.c - Mail commands */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <syslog.h>
7
8 #include "mailcmd.h"
9 #include "defines.h"
10 #include "config.h"
11 #include "mbox.h"
12 #include "utils.h"
13
14 /* List messages */
15
16 void printhead(int i, struct message *m) {
17 char ch = ' ';
18
19 if ((m->m_flag & (MREAD|MNEW)) == MNEW)
20 ch = 'N';
21 if ((m->m_flag & (MREAD|MNEW)) == 0)
22 ch = 'U';
23 if ((m->m_flag & (MDELETED)) == MDELETED)
24 ch = 'K';
25
26 printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n",
27 (current == i+1) ? '>' : ' ',
28 ch, i+1, m->from, m->subj, m->date ,m->m_size);
29 }
30
31 int do_list(int argc, char **argv)
32 {
33 int i;
34
35 if (!(messages)) {
36 printf("No messages.\n");
37 return 0;
38 }
39
40 printf("St Num From Subject Date Size\n");
41
42 for (i = 0; i < messages; i++) {
43 printhead(i, &message[i]);
44 }
45
46 return 0;
47 }
48
49 /* Read a message (xNOS-stylish parameters) */
50
51 int do_read(int argc, char **argv)
52 {
53 char *myargv[64];
54 int myargc, argsmine;
55 char *tmpbuf;
56 int i, j, k;
57 struct message *m;
58 int msg, maxmsg;
59 char line[2000];
60
61 // Automatic Receipt generator
62 FILE *f;
63 char str [LINESIZE + 1];
64
65 if (!(messages)) {
66 printf("You have no messages.\n");
67 return 0;
68 }
69
70 if (argc > 1) {
71 argsmine = 0;
72 for (i = 1; i < argc; i++)
73 myargv[i] = argv[i];
74 myargc = argc;
75 } else {
76 argsmine = 1;
77 if (current >= messages) {
78 printf("No more messages.\n");
79 return 0;
80 }
81 current++;
82 myargc = 2;
83 myargv[1] = malloc(17);
84 sprintf(myargv[1], "echo");
85 sprintf(myargv[1], "%i", current);
86 }
87
88 for (i = 1; i < myargc; i++) {
89 tmpbuf = strchr(myargv[i], '-');
90 msg = atoi(myargv[i]);
91 if (tmpbuf == NULL)
92 maxmsg = msg;
93 else
94 maxmsg = atoi(++tmpbuf);
95 if (maxmsg < msg) {
96 printf("Bad message number %i.\n", maxmsg);
97 continue;
98 }
99 for (; msg <= maxmsg; msg++) {
100 if (msg < 1 || msg > messages) {
101 printf("There's no message number %i.\n", msg);
102 continue;
103 }
104 readmesg(msg, (!strncmp(argv[0], "v", 1)));
105 printf("--- end of message #%i --- \n", msg);
106 if (dot->receipt != NULL) {
107 getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): ");
108 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
109 /* Let's try to automate the receipt generator more */
110 f = fopen(tempMesg, "w");
111 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
112 strncpy (str, dot->from, LINESIZE);
113 printf("Receipt going to: %s\n", str);
114 fprintf(f,"To: %s\n", str);
115 fprintf(f,"X-Mailer: %s\n",VERSION);
116 fprintf(f,"X-Origin: Amateur Radio Services\n");
117 fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj);
118 strncpy (str, dot->subj, LINESIZE);
119 fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj);
120 fprintf(f,"written on %s has been read.\n\n", dot->date);
121 fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n");
122 fclose(f);
123 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
124 system(str);
125 printf("Read receipt sent.\n");
126 }
127 }
128 }
129
130 }
131 if (argsmine)
132 for (i = 1; i < myargc; i++)
133 free(myargv[i]);
134 return 0;
135 }
136
137 /* Send a message (perhaps a reply) */
138
139 int do_send(int argc, char **argv)
140 {
141 FILE *f;
142 FILE *g;
143
144 char str[LINESIZE + 1];
145 char cc[LINESIZE + 1];
146 char bcc[LINESIZE + 1];
147 int i;
148
149 int reply = 0;
150
151 if (!strncmp(argv[0], "sr", 2)) {
152 reply = 1;
153 if (argc == 1) {
154 if (current == 0) {
155 printf("No current message to reply to.\n");
156 return 0;
157 }
158 i = current;
159 } else
160 i = atoi(argv[0]);
161
162 i--;
163 if ((i < 0) || (i >= messages)) {
164 printf("Just enter SR without a parameter or number.\n");
165 return 0;
166 }
167
168 dot = &message[i];
169 }
170
171 if ((f = fopen(tempMesg, "w")) == NULL) {
172 printf("Could not create temporary file.\n");
173 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
174 return 0;
175 }
176
177 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
178
179 str[0] = '\0';
180 if (argc != 1) /* Recipient on command line */
181 for (i = 1; i < argc; i++) {
182 if (i > 1)
183 strcat(str, " ");
184 strncat(str, argv[i], LINESIZE - strlen(str));
185 }
186 else {
187 if (reply) {
188 strncpy(str, dot->from, LINESIZE);
189 printf("To: %s\n", str);
190 } else {
191 mymain:
192 getstr(str, LINESIZE, "(? = help)\nTo: ");
193 if (!strcmp(str, "?")) {
194 printf("Enter the email address or addresses separated by commas on this line\n");
195 printf("You'll be asked if you want copies to others.\n");
196 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
197 goto mymain;
198 }
199
200 if (str[0] == '\0') {
201 printf("No recipients, message cancelled.\n");
202 fclose(f);
203 remove(tempMesg);
204 return 0;
205 }
206
207 }
208 }
209
210 fprintf( f, "To: %s\n", str);
211 /* adding a carbon copy feature */
212
213 copies:
214 getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): ");
215 if (!strcmp(str, "?")) {
216 printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n");
217 printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n");
218 goto copies;
219 } else {
220
221 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
222 goto carbon;
223 } else {
224 goto prio;
225 }
226 }
227 carbon:
228 getstr(cc, LINESIZE, "(? = help)\ncc: ");
229
230 if (!strcmp(cc, "?")) {
231 printf("Enter your carbon copied address(es) below. You will be prompted for\n");
232 printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n");
233 printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n");
234 goto carbon;
235 }
236 if (cc[0] == '\0') {
237 goto goblind;
238 }
239 fprintf( f, "cc: %s\n", cc);
240
241 goblind:
242 /* adding a blind carbon copy feature */
243 getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: ");
244
245 if (!strcmp(bcc, "?")) {
246 printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n");
247 printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n");
248 goto goblind;
249 }
250 if (bcc[0] == '\0') {
251 goto header;
252 }
253 fprintf( f, "bcc: %s\n", bcc);
254
255
256 header:
257 fprintf( f, "X-Mailer: %s\n", VERSION );
258 fprintf( f, "X-Origin: Amateur Radio Services\n" );
259 goto prio;;
260
261 /* adding priority receive rule */
262
263 prio:
264 getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): ");
265
266 /* try to bullet-proof end-user responces a bit... */
267
268 if (!strcmp(str, "?")) {
269 printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n");
270 printf("priority in nature and with most mail client software will present\n");
271 printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n");
272 printf("by hitting the enter key will send your mail message via normal delivery.\n\n");
273 goto prio;
274 }
275
276 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
277 fprintf( f, "X-Priority: 1 (Highest)\n" );
278 }
279 else
280 { fprintf( f,"X-Priority: 3 (Normal)\n" );
281 }
282
283 receipt:
284 getstr(str, LINESIZE, "Read receipt requested? (y/N/?): ");
285
286 if (!strcmp(str, "?")) {
287 printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n");
288 printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n");
289 printf("by hitting the enter key will not request a confirmation receipt.\n\n");
290 goto receipt;
291 }
292
293 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
294 fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname);
295 }
296 else
297 { fprintf( f,"" );
298 }
299
300 if (reply) {
301 if (strncasecmp(dot->subj, "Re: ", 3))
302 snprintf(str, LINESIZE, "Re: %s", dot->subj);
303 else
304 snprintf(str, LINESIZE, "%s", dot->subj);
305 printf("Subject: %s\n", str);
306 } else
307 getstr(str, LINESIZE, "Subject: ");
308
309 fprintf(f, "Subject: %s\n", str);
310
311 if (reply)
312 fprintf(f, "In-Reply-To: %s\n", dot->id);
313
314 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
315 fflush(stdout);
316
317 cont:
318 do {
319 fgets(str, LINESIZE, stdin);
320 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
321 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
322
323 retry:
324 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
325 if (!strcmp(str, "?")) {
326 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
327 printf("let you continue writing the message. Answering anything else will\n");
328 printf("proceed with delivering the message to the recipient.\n");
329 goto retry;
330 }
331 if (!strcasecmp(str, "c")) {
332 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
333 fflush(stdout);
334 goto cont;
335 }
336 /* append a signature file signature to the mail message */
337 FILE *stream;
338 char *line = NULL;
339 char *sig = NULL;
340 char buffer[79 + 1];
341 size_t len = 0;
342 ssize_t read;
343
344 sprintf(buffer,"%s/.signature", homedir);
345 stream = fopen(buffer, "r");
346 if (stream == NULL) {
347 printf("No signature file found, use the SIG command to make one.\n");
348 printf("Mail send.\n");
349 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
350 goto mailmsg;
351 } else {
352 while ((read = getline(&line, &len, stream)) != -1) {
353 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
354 }
355
356 free(line);
357 fclose(stream);
358 }
359 mailmsg:
360
361
362 if (fclose(f)) {
363 printf("Ouch, could not close temporary file.\n");
364 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
365 return 0;
366 }
367
368 delrcpt:
369 if (strcasecmp(str, "n")) {
370 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
371 if (!strcasecmp(str, "?")) {
372 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
373 printf("it that you desire notification that your mail message not only was received but\n");
374 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
375 printf("if you need to log the fact that you sent a communication to a specific person\n");
376 printf("especially for emergency communication purposes and they do NOT send you a read\n");
377 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
378 printf("you infact did send a communication and the remote person did in fact received it.\n");
379 printf("This feature can ONLY be found in axMail-FAX.\n");
380 goto delrcpt;
381 }
382 if (!strcasecmp(str, "y")) {
383 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
384 system(str);
385 printf("Message sent, delivery notification activated.\n");
386 } else {
387 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
388 system(str);
389 printf("Message sent.\n");
390 }
391 } else
392 printf("Message canceled.\n");
393
394 if (remove(tempMesg)) {
395 printf("Ouch, could not remove temporary file.\n");
396 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
397 return 0;
398 }
399
400 return 0;
401 }
402
403 /* Send a personal message with no flags or copy prompts */
404
405 int do_psend(int argc, char **argv)
406 {
407 FILE *f;
408 FILE *g;
409
410 char str[LINESIZE + 1];
411 int i;
412
413 int reply = 0;
414
415 if (!strncmp(argv[0], "sr", 2)) {
416 reply = 1;
417 if (argc == 1) {
418 if (current == 0) {
419 printf("No current message to reply to.\n");
420 return 0;
421 }
422 i = current;
423 } else
424 i = atoi(argv[0]);
425
426 i--;
427 if ((i < 0) || (i >= messages)) {
428 printf("Just enter SR without a parameter or number.\n");
429 return 0;
430 }
431
432 dot = &message[i];
433 }
434
435 if ((f = fopen(tempMesg, "w")) == NULL) {
436 printf("Could not create temporary file.\n");
437 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
438 return 0;
439 }
440
441 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
442
443 str[0] = '\0';
444 if (argc != 1) /* Recipient on command line */
445 for (i = 1; i < argc; i++) {
446 if (i > 1)
447 strcat(str, " ");
448 strncat(str, argv[i], LINESIZE - strlen(str));
449 }
450 else {
451 if (reply) {
452 strncpy(str, dot->from, LINESIZE);
453 printf("To: %s\n", str);
454 } else {
455 mypmain:
456 getstr(str, LINESIZE, "(? = help)\nTo: ");
457 if (!strcmp(str, "?")) {
458 printf("Enter the email address or addresses separated by commas on this line\n");
459 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
460 goto mypmain;
461 }
462
463 if (str[0] == '\0') {
464 printf("No recipients, message cancelled.\n");
465 fclose(f);
466 remove(tempMesg);
467 return 0;
468 }
469
470 }
471 }
472
473 fprintf( f, "To: %s\n", str);
474 fprintf( f, "X-Mailer: %s\n", VERSION );
475 fprintf( f, "X-Origin: Amateur Radio Services\n" );
476 fprintf( f, "X-Priority: 1 (Highest)\n" );
477
478 if (reply) {
479 if (strncasecmp(dot->subj, "Re: ", 3))
480 snprintf(str, LINESIZE, "Re: %s", dot->subj);
481 else
482 snprintf(str, LINESIZE, "%s", dot->subj);
483 printf("Subject: %s\n", str);
484 } else
485 getstr(str, LINESIZE, "Subject: ");
486
487 fprintf(f, "Subject: %s\n", str);
488
489 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
490 fflush(stdout);
491
492 pcont:
493 do {
494 fgets(str, LINESIZE, stdin);
495 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
496 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
497
498 pretry:
499 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
500 if (!strcmp(str, "?")) {
501 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
502 printf("let you continue writing the message. Answering anything else will\n");
503 printf("proceed with delivering the message to the recipient.\n");
504 goto pretry;
505 }
506 if (!strcasecmp(str, "c")) {
507 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
508 fflush(stdout);
509 goto pcont;
510 }
511
512 /* append a signature file signature to the mail message */
513 FILE *stream;
514 char *line = NULL;
515 char *sig = NULL;
516 char buffer[79 + 1];
517 size_t len = 0;
518 ssize_t read;
519
520 sprintf(buffer,"%s/.signature", homedir);
521 stream = fopen(buffer, "r");
522 if (stream == NULL) {
523 printf("No signature file found, use the SIG command to make one.\n");
524 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
525 goto pmailmsg;
526 } else {
527 while ((read = getline(&line, &len, stream)) != -1) {
528 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
529 }
530
531 free(line);
532 fclose(stream);
533 }
534
535 pmailmsg:
536
537 if (fclose(f)) {
538 printf("Ouch, could not close temporary file.\n");
539 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
540 return 0;
541 }
542 if (strcasecmp(str, "n")) {
543 pdelrcpt:
544 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
545 if (!strcasecmp(str, "?")) {
546 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
547 printf("it that you desire notification that your mail message not only was received but\n");
548 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
549 printf("if you need to log the fact that you sent a communication to a specific person\n");
550 printf("especially for emergency communication purposes and they do NOT send you a read\n");
551 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
552 printf("you infact did send a communication and the remote person did in fact received it.\n");
553 printf("This feature can ONLY be found in axMail-FAX.\n");
554 goto pdelrcpt;
555 }
556 if (!strcasecmp(str, "y")) {
557 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
558 system(str);
559 printf("Message sent, delivery notification activated.\n");
560 } else {
561 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
562 system(str);
563 printf("Message sent.\n");
564 }
565 } else
566 printf("Message canceled.\n");
567
568 if (remove(tempMesg)) {
569 printf("Ouch, could not remove temporary file.\n");
570 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
571 return 0;
572 }
573
574 return 0;
575 }
576
577 /* Kill a message */
578
579 int do_kill(int argc, char **argv)
580 {
581 int i, msg = 0, cnt = 0;
582 char *myargv[64];
583 int myargc, argsmine;
584
585 if (!(messages)) {
586 printf("You have no messages.\n");
587 return 0;
588 }
589
590 if (argc > 1) {
591 argsmine = 0;
592 for (i = 1; i < argc; i++)
593 myargv[i] = argv[i];
594 myargc = argc;
595 } else {
596 if (current == 0) {
597 printf("No current message to kill.\n");
598 return 0;
599 }
600 argsmine = 1;
601 myargc = 2;
602 myargv[1] = malloc(17);
603 sprintf(myargv[1], "%i", current);
604 }
605
606 for (i = 1; i < myargc; i++) {
607 msg = atoi(myargv[i]) - 1;
608
609 if ((msg < 0) || (msg >= messages)) {
610 printf("There's no message %s.\n", myargv[i]);
611 continue;
612 }
613
614 dot = &message[msg];
615
616 if ((dot->m_flag & MDELETED) == MDELETED) {
617 printf("Message %i is already dead.\n", msg + 1);
618 continue;
619 }
620
621 dot->m_flag |= MDELETED;
622 cnt++;
623 }
624
625 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
626 printf("Message %i killed.\n", msg + 1);
627 else if (cnt > 1)
628 printf("%i messages killed.\n", cnt);
629
630 if (argsmine)
631 for (i = 1; i < myargc; i++)
632 free(myargv[i]);
633
634 return 0;
635 }
636
637 /* Unkill a message */
638
639 int do_unkill(int argc, char **argv)
640 {
641 int i, msg = 0, cnt = 0;
642 char *myargv[64];
643 int myargc, argsmine;
644
645 if (!(messages)) {
646 printf("You have no messages.\n");
647 return 0;
648 }
649
650 if (argc > 1) {
651 argsmine = 0;
652 for (i = 1; i < argc; i++)
653 myargv[i] = argv[i];
654 myargc = argc;
655 } else {
656 if (current == 0) {
657 printf("No current message to unkill.\n");
658 return 0;
659 }
660 argsmine = 1;
661 myargc = 2;
662 myargv[1] = malloc(17);
663 sprintf(myargv[1], "%i", current);
664 }
665
666 for (i = 1; i < myargc; i++) {
667 msg = atoi(myargv[i]) - 1;
668
669 if ((msg < 0) || (msg >= messages)) {
670 printf("There's no message %s.\n", myargv[i]);
671 continue;
672 }
673
674 dot = &message[msg];
675
676 if ((dot->m_flag & MDELETED) != MDELETED) {
677 printf("Message %i is not dead.\n", msg + 1);
678 continue;
679 }
680
681 dot->m_flag ^= (dot->m_flag & MDELETED);
682 cnt++;
683 }
684
685 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
686 printf("Message %i unkilled.\n", msg + 1);
687 else if (cnt > 1)
688 printf("%i messages unkilled.\n", cnt);
689
690 if (argsmine)
691 for (i = 1; i < myargc; i++)
692 free(myargv[i]);
693
694 return 0;
695 }
696
697 /* Send a Fax */
698 int do_fax(int argc, char **argv)
699 {
700 FILE *f;
701 char str[LINESIZE + 1];
702 int i;
703
704 int reply = 0;
705
706 if (!strncmp(argv[0], "sr", 2)) {
707 reply = 1;
708 if (argc == 1) {
709 if (current == 0) {
710 printf("No current message to reply to.\n");
711 return 0;
712 }
713 i = current;
714 } else
715 i = atoi(argv[1]);
716
717 i--;
718 if ((i < 0) || (i >= messages)) {
719 printf("There's no message %s.\n", argv[1]);
720 return 0;
721 }
722
723 dot = &message[i];
724 }
725
726 if ((f = fopen(tempMesg, "w")) == NULL) {
727 printf("Could not create temporary file.\n");
728 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
729 return 0;
730 }
731
732 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
733
734 str[0] = '\0';
735 if (argc != 1) /* Recipient on command line */
736 for (i = 1; i < argc; i++) {
737 if (i > 1)
738 strcat(str, " ");
739 strncat(str, argv[i], LINESIZE - strlen(str));
740 }
741 else {
742 }
743
744 printf("To: Fax Gateway\n");
745 fprintf( f, "To: %s\n", faxgate );
746 fprintf( f, "X-Mailer: %s\n", VERSION );
747 fprintf( f, "X-Origin: Amateur Radio Services\n" );
748 goto prio;;
749
750 /* adding priority receive rule */
751
752 prio:
753 /* if (reply) {
754 if (strncasecmp(dot->subj, "Re: ", 3))
755 snprintf(str, LINESIZE, "Re: %s", dot->subj);
756 else
757 snprintf(str, LINESIZE, "%s", dot->subj);
758 printf("Subject: %s\n", str);
759 } else */
760 getstr(str, LINESIZE, "Enter a header <firstname@fullphone Brief note here>\nEx: john@16195551212 Hi From Packet\nHeader: ");
761
762 fprintf(f, "Subject: %s\n", str);
763
764 if (reply)
765 fprintf(f, "In-Reply-To: %s\n", dot->id);
766
767 printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n");
768 fflush(stdout);
769
770 cont:
771 do {
772 /* fprintf( f, "X-Mailer: %s\n", VERSION );
773 fprintf( f, "X-Origin: Amateur Radio Services\n" ); */
774 fgets(str, LINESIZE, stdin);
775 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
776 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
777
778 retry:
779 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
780 if (!strcmp(str, "?")) {
781 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
782 printf("let you continue writing the facsimile. Answering anything else will\n");
783 printf("proceed with delivering the facsimile to the recipient.\n");
784 goto retry;
785 }
786 if (!strcasecmp(str, "c")) {
787 printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n");
788 fflush(stdout);
789 goto cont;
790 }
791
792 if (fclose(f)) {
793 printf("Ouch, could not close temporary file.\n");
794 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
795 return 0;
796 }
797
798 if (strcasecmp(str, "n")) {
799 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
800 system(str);
801 printf("Facsimile sent.\n");
802 } else
803 printf("Facsimile canceled.\n");
804
805 if (remove(tempMesg)) {
806 printf("Ouch, could not remove temporary file.\n");
807 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
808 return 0;
809 }
810
811 return 0;
812 }
0 USAGE
1 send [<mail recipient>]
2
3 DESCRIPTION
4 This command sends message. If no mail recipient is specified,
5 then you will be asked. You will also be prompted for a cc: and
6 also for a bcc: entry if desired. Hitting enter disables these
7 features. You may enter multiple addresses on each line if you
8 desire too. Separate them with a comma (,). Ex:
9
10 s n1uro@email.com, user@foo.net, noone@bar.org
11 cc: ripoff@arrl.org, commish@fcc.gov
12 bcc: ghost@noth.ing, not@listed.info
0 USAGE
1 help [<command>]
2
3 DESCRIPTION
4 Gives help for the specified command or this text if no
5 command is specified. Commands can not be abbreviated.
6 Use the "?" command to retrieve a list of available commands.
0 axMail - an SMTP mailbox for the various linux node frontends
1 and outbound FAX engine.
2
3 Current author: Brian Rogers (N1URO) <n1uro@n1uro.com>
4 Past author: Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>
5 Creator: Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
6
7 Additional Submissions: Stefano (IW3IJQ) <ziotibia1@libero.it>
8
9 As with any of the softwares I tweek n geek, *use at your own risk*!
10 With that said, and the fact that this is GPL software if you find
11 something that's borked... don't just submit a bug report. Fix it if
12 you can. Rerelease it under your own callsign if you wish, or feel free
13 to send me your code and I'll import it in.
14
15 This is probably one of the simplest packages to install and configure!
16 After you run tar zxvf axmail-0.0.8.tgz cd axmail-0.0.8 (which is where
17 you should be now if you're reading this :) ) and run:
18
19 make; make install
20
21 (on newer gcc/libs I do know that there's a warning after it makes but
22 it doesn't prevent the binary from compiling and so far it seems to test
23 ok. I'll fix that if and when I get the chance but don't hold your breath
24 on it hi!)
25
26 cd /usr/local/etc/ax25 and using your favorite editor (vi, joe, pico, etc) and
27 edit axmail.conf. In here you can specify how you wish the mailbox
28 to handle accounting for end users. On *most* linux systems, the default
29 should be "ok" but if you wish to have users contact you first, or if
30 you wish to have the system auto-create a standard shell login, or popmail
31 account for the users, etc... you may do so in the file. Double check your
32 settings (it *is* possible you can configure axmail.conf so that everyone
33 has root-group access... but why would you wish to do that? You've been
34 *warned* so double check your config settings for auto-creation of
35 accounts before saving!) The file is well commented to assist you. When
36 you're finished and have become an expert, if you wish to you can delete
37 the comment lines.
38
39 You may also customize the file "welcome.txt" in /usr/local/etc/ax25/ if you
40 wish to also. I suggest leaving the first line as-is as this is the so called
41 "new user" welcome greeting email. I've supplied a basic and short
42 greeting email message that users will get once they've created their
43 mailbox. If you would rather new users email your mail account directly
44 instead of root, you may wish to change that line.
45
46 For the software itself... believe it or not, you're *DONE*! That's all!
47 However... now we need to get it hooked into which ever node frontend you
48 run so that users have a way of accessing it. axMail runs as an external
49 process (ExtCmd) to the node. I've tested it with URONode (obviously) and
50 with LinuxNode by Tomi. To do this cd /usr/local/etc/ax25 and using your
51 favorite editor open node.conf and add the following line to your ExtCmds:
52
53 ExtCmd MAil 1 root /usr/local/sbin/axmail axmail %u
54 (note: MA in the word MAil is in CAPS)
55
56 Save uronode.conf and telnet in to test! It should work just fine. Since you
57 would have an existing account on your server, it's unlikely that you'll
58 get the welcome message, but since you can edit it, you'll know what it
59 says :)
60
61 **ERROR 1**
62 *** Note:
63 If you're installing axMail-FAX via source, but your MTA (aka: postfix)
64 was installed from repository packaging, you may need to create a symlink
65 to your users mail file directory... typically:
66 /var/spool/mail/ -> /usr/local/var/spool/mail/
67 If you don't do this, users will NOT see their incoming mail.
68 ***
69
70 Happy mailing!
71
0 Subject: Welcome to axMail-FAX
1
2 Welcome to axmail! Your email address is listed above the prompt.
3 For further assistance, try "?" or email root.
4
5 axMail is the first mail client for packet that allows it's users the ability
6 to:
7 send/receive emails, send outbound faxing with confirmations and receipts
8 read receipts for their mail , server to server confirmation of delivery of mail
9 cc and bcc fields for multiple copies of mail, priority flagging for emergency
10 communications, and an SP shortcut for those using HF to bypass many prompting
11 ...all by using just a dumb terminal.
12
13 Some sites may offer pop3/IMAP/webmail as well. Contact your sysop to see if
14 this is possible.
15
16 73!
0 USAGE
1 sfax
2
3 DESCRIPTION
4 This command sends a facsimile. The To: field will be preset for
5 you. You can specify a user but you *must* specify a full phone
6 number to fax to. Ex: n1uro@14132416644
7
8 Notes: Faxes will send only! You will get a confirmation that your
9 fax was received into the system and another message after the
10 fax was either sent successfully or had issues sending. Faxes
11 will only work within the United States. Sending of faxes
12 elsewhere is a violation of this program.
13
14 IMPORTANT: you *must* include the beginning country code. For
15 the U.S it's 1, for the U.K. it's 011. An example of a properly
16 entered number would be: 12125551212
17
18
19
0 #!/bin/bash -x
1
2 # email2fax-axmail 1.0beta
3 # This script allows you to send faxes through your Hylafax server.
4 # It extracts PDF,TIFF or PS attachments from an email and then passes
5 # it to Hylafax thru "sendfax" command.
6
7 # Hylafax adaptation by:
8 # (c) Brian Rogers - NCC 2007
9 # (c) Raffaello Cassetta 2006
10 # Original work by:
11 # (c) Tomasz Chmielewski < tch @ wpkg . org > 2005-2006
12 # License: GPLv2
13
14 # Variables you might want to change
15
16 FAXMAIL="NCC FAX <fax@asterisk.n1uro.ampr.org>" # email from which confirmations are sent
17
18 DEFSENDER="fax@n1uro.ampr.org" # If email doesn't have "From:" field, default to this for Hylafax error mails
19
20 LOGFILE=/var/log/fax.log # where to log
21
22 TMPDIR=/var/email2fax # dir for temp files; must be writable by the launching user
23
24 MAXAGE=30 # how long to keep temp files, in minutes.
25 # There should be no reason for keeping these files so long because
26 # once sendfax has enqueued the document, this is stored in Hylafax
27 # spool directory and there resides until fax transmission's completion
28 # In a production environment, with tens or hundreds of fax submitted every
29 # minute, you should reduce this to a value as low as possible. Anyway, leave
30 # some grace time to tolerate delays in bash script executions (due to high
31 # CPU load or whatelse)
32
33 WHOAMI=`whoami` # User that launches script - useful for testing/debugging when invoked
34 # by MDAs or other daemons
35
36 SENDFAXOPTS=" " # Default sendfax options
37
38
39 # You probably don't have to change anything below...
40
41 DATADIR=$TMPDIR/`date +%s-%N`
42 EMAILFILE=$DATADIR/emailfile.eml
43 COVERFILE=$DATADIR/coverpage.txt
44 MESSAGEFILE=$DATADIR/message.txt
45
46 DATETIME=`date +"%A, %B %d %Y, at %R:%S"` # date put in email confirmations
47 #DATETIME=`date +"%A, %B %d %Y, at %r"` # date put in email confirmations, different format
48
49 VERSION="email2fax-axmail v1.0" # version
50
51 PATH="/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:"$PATH
52
53 ############################################################
54 # check how we are started, print help if pipe wasn't used #
55 ############################################################
56
57 [ -p /dev/stdin ]
58 [ $? -eq 1 ] && EMPTY=1 && cat <<EOF
59 $VERSION, email to fax gateway for Hylafax
60
61 Usage:
62
63 "piped message" | email2fax-axmail [OPTIONS]
64
65 Options:
66 --nomail don't send any error or confirmation email when a message has been submitted (default: send error or confirmation email)
67 --noconfirm don't send any confirmation email when a message has been submitted, send email only for errors (default: send confirmation or error email)
68 --nodelete don't delete temporary files (default: delete temporary files)
69 --nofax don't send the fax (default: send fax)
70 --debug enable debug logging
71 --notify enable notification by electronic mail when the facsimile has been delivered.
72 by default HylaFAX will notify the submitter only if there is a problem with a job.
73 --notify-all enable notification by electronic mail when the facsimile has been delivered and when it is
74 requeued for retransmission. by default HylaFAX will notify the submitter only if there is a
75 problem with a job.
76 --usebody uses message body as faxcover
77
78 Email can contain either PDF,PS,TIFF attachments or text body, and must have at least one destination fax number as a subject.
79 Multiple destination numbers should be separated by spaces.
80 If no attachment is supplied, message body is sent as fax.
81
82 Examples:
83
84 This one sends a fax from the command line, and enables debug logging:
85
86 cat message.eml | email2fax-axmail --debug
87
88
89 This one enables debug logging, doesn't send a confirmation email,
90 doesn't delete temporary files, and doesn't send a fax (useful for testing etc.):
91
92 cat message.eml | email2fax-axmail --debug --nomail --nodelete --nofax
93
94
95 This entry in .procmailrc located in fax recipient home directory intercepts all emails
96 to fax recipient, and passes them to email2fax-axmail:
97
98 :0fw
99 | /usr/local/bin/email2fax-axmail
100
101
102 The same can be done in .forward file located in the same directory with this semantic:
103
104 "| /usr/local/bin/email2fax-axmail"
105
106 quotes included
107
108
109 By default, email2fax-axmail logs ALL messages to $LOGFILE, and saves temporary files in $TMPDIR.
110 These paths, along with several different variables, can be changed
111 at the beginning of this script ($0).
112
113 See http://wpkg.org/email2fax for updates, bug reports, and answers.
114
115 EOF
116
117 [ "$EMPTY" == "1" ] && exit 0
118
119 cat <<EOF >> $LOGFILE
120 --------------------------------------------------------------
121 $VERSION started on $DATETIME with options:
122
123 $0 $@
124
125 by user: $WHOAMI
126
127 EOF
128
129
130 #################################################
131 # Check the error code and make a proper action #
132 #################################################
133
134 send_msg()
135 {
136
137 [ $1 -eq 1 -o $1 -eq 2 ] && NEWSUBJECT="Fax problem"
138 [ $1 -eq 0 -a $NOFAX -eq 1 ] && NEWSUBJECT="Fax not sent"
139 [ $1 -eq 0 -a $NOFAX -eq 0 ] && NEWSUBJECT="Fax confirmation"
140
141 #FAXNUMBERS=`echo $NEWNUM | sed -e "s/ /, /g" -e "s/@/ /" | awk '{print $2}'`
142 FAXNUMBERS=`cat $COVERFILE |grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' `
143 cat <<EOF >$MESSAGEFILE
144 From: $FAXMAIL
145 To: $SENDER
146 Subject: $NEWSUBJECT
147
148 Dear sender,
149
150 EOF
151
152 case "$1" in
153
154 0)
155 if [ $NOFAX -eq 0 ] ; then
156
157 if [ $NOCONFIRM -eq 0 ] ; then
158 cat <<EOF >>$MESSAGEFILE
159 The message was accepted for fax delivery.
160
161 Fax number(s): $FAXNUMBERS
162 Date: $DATETIME
163
164 EOF
165 [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t
166
167 fi
168 else
169
170 cat <<EOF >>$MESSAGEFILE
171 Fax sending is currently disabled, please contact your administrator.
172
173 Fax number(s): $FAXNUMBERS
174 Date: $DATETIME
175
176 EOF
177 [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t
178
179 fi
180
181 del_temp
182
183 ;;
184
185 1)
186 echo "No e-mail message passed to email2fax-axmail, or message broken." >>$LOGFILE
187 cat <<EOF >>$MESSAGEFILE
188 The message you sent was broken or invalid.
189 Check if it had a proper attachment (must be one PDF or one TIFF attachment
190 or plain text body),
191 and if the fax number was correct, and try again.
192 If the problem persists, contact your administrator.
193
194 Fax number(s): $FAXNUMBERS
195 Date: $DATETIME
196
197 EOF
198
199 [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t
200 del_temp
201 ;;
202
203 2)
204 cat <<EOF >>$MESSAGEFILE
205 System not configured properly for sending faxes, contact your administrator.
206
207 Date: $DATETIME
208
209 EOF
210
211
212 [ $NOMAIL -ne 1 ] && echo $NOMAIL && cat $MESSAGEFILE | sendmail -t
213 del_temp
214
215 esac
216 }
217
218
219 #######################################
220 # Delete temporary files if requested #
221 #######################################
222
223 del_temp()
224 {
225 if [ $NODELETE -eq 0 ] ; then
226 [ $DEBUG -eq 1 ] && echo "Removing old temporary files" >>$LOGFILE
227 [ $DEBUG -eq 0 ] && find $TMPDIR/* -type d -mmin +$MAXAGE -exec rm -fvr {} \; &>/dev/null
228 [ $DEBUG -eq 1 ] && find $TMPDIR/* -type d -mmin +$MAXAGE -exec rm -fvr {} \; >>$LOGFILE
229 echo >>$LOGFILE
230 else
231 echo "Not removing old temporary files" >>$LOGFILE
232 echo >>$LOGFILE
233 fi
234 }
235
236
237 #####################################################
238 # By default, our internal "error code" should be 0 #
239 #####################################################
240 ERRORCODE=0
241
242
243 #############################################
244 # Make sure temp dir exists and is writable #
245 #############################################
246
247 mkdir -p $DATADIR
248 if [ $? -ne 0 ] ; then
249 echo "$DATADIR not writable, can't continue!" >>$LOGFILE
250 ERRORCODE=2
251 fi
252
253 ###########################################
254 # Check if "munpack" program is installed #
255 ###########################################
256
257 if [ `which munpack &>/dev/null ; echo $?` -ne 0 ] ; then
258 echo "munpack is not installed: can't extract attachments, can't continue!" >>$LOGFILE
259 ERRORCODE=2
260 fi
261
262 ############################################
263 # Read flags and set appropriate behaviour #
264 ############################################
265
266 # --nomail takes precedence over --noconfirm. If --nomail is present then --noconfirm is ignored
267 [ `echo $@ | grep -i -q '\-\-nomail' ; echo $?` -eq 0 ] && NOMAIL=1 || NOMAIL=0
268 if test $NOMAIL = 0; then
269 [ `echo $@ | grep -i -q '\-\-noconfirm' ; echo $?` -eq 0 ] && NOCONFIRM=1 || NOCONFIRM=0
270 else
271 NOCONFIRM=0
272 fi
273
274 [ `echo $@ | grep -i -q '\-\-usebody' ; echo $?` -eq 0 ] && USEBODY=1 || USEBODY=0
275 [ `echo $@ | grep -i -q '\-\-nodelete' ; echo $?` -eq 0 ] && NODELETE=1 || NODELETE=0
276 [ `echo $@ | grep -i -q '\-\-nofax' ; echo $?` -eq 0 ] && NOFAX=1 || NOFAX=0
277 [ `echo $@ | grep -i -q '\-\-debug' ; echo $?` -eq 0 ] && DEBUG=1 || DEBUG=0
278
279 # --notify-all takes precedence over --notify. If --notify-all is present then --notify is ignored
280 [ `echo $@ | grep -i -q '\-\-notify\-all' ; echo $?` -eq 0 ] && NOTIFYALL=1 || NOTIFYALL=0
281 if test $NOTIFYALL = 1; then
282 NOTIFY="-R"
283 else
284 [ `echo $@ | grep -i -q '\-\-notify' ; echo $?` -eq 0 ] && NOTIFY="-D" || NOTIFY=""
285 fi
286
287 UNKNOWN_FLAGS=`echo $@ | sed -e "s/--nomail//gI" -e "s/--nodelete//gI" -e "s/--nofax//gI" -e "s/--debug//gI" -e "s/--usebody//gI" -e "s/--notify-all//gI" -e "s/--notify//gI" -e "s/--noconfirm//gI"`
288 [ -z $UNKNOWN_FLAGS ]
289 [ $? -ne 0 ] && echo "WARNING: unknown flags: $UNKNOWN_FLAGS" >>$LOGFILE
290
291 if [ $DEBUG -eq 1 ] ; then
292 cat <<EOF >>$LOGFILE
293 Variables used:
294
295 FAXMAIL: $FAXMAIL
296 LOGFILE: $LOGFILE
297 VERSION: $VERSION
298 TMPDIR: $TMPDIR
299 DATADIR: $DATADIR
300 EMAILFILE: $EMAILFILE
301 MESSAGEFILE: $MESSAGEFILE
302 DATETIME: $DATETIME
303
304 EOF
305
306 fi
307
308
309 ############################################################
310 # If we can't continue, send a message with an explanation #
311 ############################################################
312
313 [ $ERRORCODE -eq 2 ] && send_msg 2 && exit 2
314
315
316 #########################################
317 # Make a temporary file out of an email #
318 #########################################
319
320 cat | sed 's/$//' > $EMAILFILE
321 cp $EMAILFILE $COVERFILE
322
323 ##############################
324 # COVERPAGE VARIABLES ADDED: #
325 ##############################
326 COVERTO=`cat $COVERFILE |grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $1}' `
327 COVERCOM=`cat $COVERFILE | grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{$1=""; $2=""; sub(" ", " "); print}' `
328
329 ######################################################################
330 # If input file is too short (broken email etc.) send error and quit #
331 ######################################################################
332
333 if [ `du -b $EMAILFILE | awk '{print $1}'` -lt 15 ] ; then
334 echo "No e-mail message passed to email2fax-axmail, or message broken." >>$LOGFILE
335 # send_msg 1
336 # exit 1
337 fi
338
339
340 #############################################################################################
341 # Get the email address to send a confirmation to, and telephone number(s) to send faxes to #
342 # Verify suitable data and take appropriate action #
343 #############################################################################################
344
345 SUBJLINE=`grep -m 1 "Subject:" $EMAILFILE`
346 # TOLINE=`grep -m 1 "To:" $EMAILFILE.1`
347 SENDER=`grep -m 1 "From:" $EMAILFILE | sed -e "s/From://"`
348 NUMBERS=`echo $SUBJLINE | awk '{print NF}'`
349 SUBJECT=`echo $SUBJLINE | sed -e "s/Subject://" `
350
351 # If no fax numbers in the subject, send an explanation and quit
352 [ $NUMBERS -lt 2 ] && send_msg 1 && exit 1
353
354 # If no sender in file, don't send a confirmation email
355 if [ -z "$SENDER" ] ; then
356 NOMAIL=1
357 SENDER=$DEFSENDER
358 fi
359
360 #########################################################################
361 # Extract everything from mail, check files and take appropriate action #
362 #########################################################################
363
364 # extract everything from mail
365 MOUT=`munpack -t -C "$DATADIR" "$EMAILFILE"`
366
367 # I AGREE: the following "for" cycle is terrible, please make it better
368 # ^^^^^^^^
369 SEQ="ODD"
370 for P in $MOUT
371 do
372 if [ "$SEQ" = "ODD" ] ; then
373 SEQ="EVEN"
374 FORVAR=$P
375 else
376 FORVAR=$FORVAR" "$P
377 if [ `echo "$FORVAR"|grep -c "text/plain"` -ne 0 ] ; then
378 TXT=`echo $FORVAR | cut -f1 -d " "`" "$TXT
379 # TXT=`cat $DATADIR/$EMAILFILE|formail -k -X X-Origin: -X X-Mailer >$DATADIR/part1`
380 $FORVAR=$P
381 elif [ `echo "$FORVAR"|grep -c -e "pdf" -e "tif" -e "postscript"` -ne 0 ] ; then
382 ATTACH=`echo $FORVAR | cut -f1 -d " "`" "$ATTACH
383 else
384 mkdir $DATADIR/convdir
385 cat $DATADIR/emailfile.eml|formail -k -X X-Origin: -X X-Mailer >$DATADIR/part1
386 touch $DATADIR/convdir/foo
387 /usr/bin/text2ps -B $DATADIR/part1 > $DATADIR/convdir/part1.ps
388 # fi
389 fi
390 SEQ="ODD"
391 fi
392 done
393
394 # If no txt nor pdf nor tif nor ps parts are present, send error and exit
395 # If only text is present, then it's only a mail
396 if [ -z "$ATTACH" -a -z "$TXT" || -f "$CONVDIR/part1.ps" ] ; then
397 echo "No pdf nor tif nor ps nor text body present." >>$LOGFILE
398 send_msg 1
399 exit 1
400 elif [ -z "$ATTACH" ] ; then
401 ISMAIL=1
402 else
403 ISMAIL=0
404 fi
405
406
407 #############################################################################
408 # Read destination numbers from subject, verify and take appropriate action #
409 #############################################################################
410
411 # Convert fax numbers from the subject field to separate numbers
412 SUBJLINE=`grep -m 1 "Subject:" $EMAILFILE | sed -e "s/Subject://" -e "s/[-() ]/ /g" -e "s/,/ /g"`
413
414 NEWNUM=""
415
416 for FAXNUM in $SUBJLINE
417
418 do
419 FAXNUM=`cat $COVERFILE | grep -m 1 "Subject:" | sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' `
420 [ ! -z `echo "$FAXNUM" | sed -e "s/[0-9]//g"` ] && echo "Wrong fax number: $FAXNUM" >>$LOGFILE && FAXNUM=
421
422 [ -n "$FAXNUM" ] && NEWNUM="$NEWNUM $FAXNUM"
423
424 done
425
426 # If no numbers have been munged, send an error message and exit
427 if test "$NEWNUM" = "" ; then
428
429 echo "No destination numbers present in Subject field." >>$LOGFILE
430 # send_msg 1
431 # exit 1
432
433 fi
434
435 # Log who sends fax where
436 cat <<EOF >>$LOGFILE
437 Fax from$SENDER to fax number(s): $FAXNUM
438 Attachments: $ATTACH
439 EOF
440
441
442 ############################
443 # Send document to sendfax #
444 ############################
445
446 if [ $NOFAX -eq 0 ] ; then
447
448 # If the user wants to send the body or it's only a text message, then create text parts list.
449 # We use faxmail to convert plain text to ps format - just to avoid strange characters that could confuse sendfax.
450 # There should be a dedicated app for doing this, but faxmail is available here and now (default with Hylafax)- nonetheless, it works :P
451 if [ $USEBODY -eq 1 -o $ISMAIL -eq 1 ] ; then
452 CONVDIR="$DATADIR/convdir" # to avoid name collisions we create a dir for converted text
453 mkdir $CONVDIR
454 for ITEM in $TXT
455 do
456 cat $DATADIR/emailfile.eml | formail -k -X X-Origin: -X X-mailer: > part1
457 TXT2PS="$CONVDIR/$ITEM.ps"
458 /usr/bin/text2ps -B $DATADIR/part1 > $CONVDIR/part1.ps
459 TEXTPART=""$TXT2PS" "$TEXTPART""
460 done
461 else
462 TEXTPART=""
463 fi
464
465 # If we have to send PDF or TIF attachments then create list
466 if [ $ISMAIL -eq 0 ] ; then
467 for ITEM in $ATTACH
468 do
469 ATTACHMENT=""$DATADIR/$ITEM" "$ATTACHMENT""
470 done
471 else
472 ATTACHMENT=""
473 fi
474
475 # create destination array for "sendfax"
476 NUM=`cat $COVERFILE | grep -m 1 "Subject:" | sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' `
477 # DEST=""
478 # for NUM in $NEWNUM
479 # do
480 # DEST="-d $COVERTO@$NUM "$DEST
481 DEST="-d $COVERTO@$NUM"
482 # done
483 # TEXTPART="$CONVDIR/part1.ps"
484
485 ## if [ -z "$TEXTPART" ]
486 sendfax -r "Amateur Communication" -x "axMail-Fax" -c "$COVERCOM" -f "$SENDER" $DEST $CONVDIR/part1.ps $TEXTPART $ATTACHMENT >> $LOGFILE 2>&1 &
487 ## else
488 ## sendfax -r "Email2Fax" -x "E-Fax at NCC" -c "$COVERCOM" -f "$SENDER" $DEST $TEXTPART $ATTACHMENT >> $LOGFILE 2>&1 &
489 ## fi
490 else
491
492 echo "Not sending fax because --nofax was used" >>$LOGFILE
493
494 fi
495
496 echo >>$LOGFILE
497
498 send_msg 0
0 .TH AXMAIL8 "28 September 2015" Linux "Linux System Managers Manual"
1 .SH NAME
2 axMail \- A powerful but simple SMTP plugin for URONode.
3 .SH SYNOPSIS
4 .B axmail %u
5 .SH DESCRIPTION
6 .LP
7 .B axMail\-FAX
8 is a simple but powerful SMTP mail plugin for URONode. This package allows
9 an end user to read and send SMTP based mail via RF, with many options
10 available.
11 .SH COMMANDS
12 The following commands are supported for users of
13 .B axMail\-FAX:
14 .TP 14
15 .BI ?
16 Give short list of available commands.
17 .TP 14
18 .BI "Autofwd \-
19 allows the end user for forward their mail to this location to any valid SMTP mailbox."
20 .TP 14
21 .BI "Bye \-
22 Disconnect user from their mailbox."
23 .TP 14
24 .BI "Cancel \-
25 Exit mailbox, discard any kills."
26 .TP 14
27 .BI "Delete (number) -\
28 Delete message number #. Multiple numbers can be space delimited."
29 .TP 14
30 .BI "Exit \-
31 Quit the mailbox, save changes."
32 .TP 14
33 .BI "Help (command) -\
34 Display help for specific command."
35 .TP 14
36 .BI "Info \-
37 Online information about this application."
38 .TP 14
39 .BI "Kill \-
40 see Delete. Msg numbers can be space delimited for multi kills."
41 .TP 14
42 .BI "List \-
43 List your mailbox messages for reading."
44 .TP 14
45 .BI "Name \-
46 Enter or change your name in your outgoing mail. This does not change your email address."
47 .TP 14
48 .BI "Quit \-
49 Quit the application, kill messages flagged for deletion."
50 .TP 14
51 .BI "Read (number) \-
52 Read message number #. You may reply to it after reading it by using the Send Reply (SReply) command."
53 .TP 14
54 .BI "Send \-
55 Send a message. axMail will prompt you through everything step by step and also will ask you for two layers of receipt generations.
56 .TP 14
57 .BI "STatus \-
58 Quick listing of your mailbox status."
59 .TP 14
60 .BI "Unkill \-
61 Undelete or unkill a message flagged for deletion."
62 .TP 14
63 .BI "Verbose \-
64 Read your mail with full message headers for debugging."
65 .SH FILES
66 .LP
67 .TP 5
68 .B /usr/local/etc/ax25/axmail.conf
69 axMail configuration file.
70 .br
71 .TP 5
72 .B /etc/postfix/main.cf
73 postfix configuration file.
74 .br
75 .SH AUTHORS
76 Brian Rogers (N1URO) <n1uro@n1uro.com>
77 .br
78 .SH OTHERS
79 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>
80 .br
81 Bob Tenty (VE3TOK) <ve3tok@gmail.com>
82 .br
83 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>
0 If you are upgrading axmail from ver 1.0.1, all you really need to do
1 is copy the binary over the existing one.
2
3 ** version 2.9 requires a new field to be added to axmail.conf!
4 make upgrade will back up your old file. You can copy it back over and
5 add "SysopMail <sysop@email.address> if you wish.
6
7 If you are upgrading axMail from any version equal to or earlier than 1.0.0
8 back up your /etc/ax25/axmail.conf file and do a full install.
9
0
1 /* head.c - parse mail headers.
2 Grabbed from mailx 5.3b, reformatted, hacked and cleaned
3 to compile without warnings by Heikki Hannikainen <hessu@pspt.fi> */
4
5 /*
6 * Copyright (c) 1980 Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms are permitted
10 * provided that this notice is preserved and that due credit is given
11 * to the University of California at Berkeley. The name of the University
12 * may not be used to endorse or promote products derived from this
13 * software without specific prior written permission. This software
14 * is provided ``as is'' without express or implied warranty.
15 */
16
17 /*
18 * Mail -- a mail program
19 *
20 * Routines for processing and detecting headlines.
21 */
22
23 #include <stdio.h>
24 #include <ctype.h>
25
26 #include "head.h"
27 #include "defines.h"
28
29 /*
30 * See if the passed line buffer is a mail header.
31 * Return true if yes. Note the extreme pains to
32 * accomodate all funny formats.
33 */
34
35 int ishead(char linebuf[])
36 {
37 char *cp;
38 struct headline hl;
39 char parbuf[LINESIZE];
40
41 cp = linebuf;
42 if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
43 *cp++ != ' ')
44 return 0;
45 parse(linebuf, &hl, parbuf);
46 if (hl.l_from == NULL || hl.l_date == NULL) {
47 /* No from or date field */
48 return 0;
49 }
50 if (!isdate(hl.l_date)) {
51 /* Date field not legal date */
52 return 0;
53 }
54 /*
55 * I guess we got it!
56 */
57 return 1;
58 }
59
60 /*
61 * Split a headline into its useful components.
62 * Copy the line into dynamic string space, then set
63 * pointers into the copied line in the passed headline
64 * structure. Actually, it scans.
65 */
66
67 void parse(char line[], struct headline *hl, char pbuf[])
68 {
69 char *cp, *sp;
70 char word[LINESIZE];
71
72 hl->l_from = NULL;
73 hl->l_tty = NULL;
74 hl->l_date = NULL;
75 cp = line;
76 sp = pbuf;
77 /*
78 * Skip over "From" first.
79 */
80 cp = nextword(cp, word);
81 cp = nextword(cp, word);
82 if (*word)
83 hl->l_from = copyin(word, &sp);
84 if (cp != NULL && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
85 cp = nextword(cp, word);
86 hl->l_tty = copyin(word, &sp);
87 }
88 if (cp != NULL)
89 hl->l_date = copyin(cp, &sp);
90 }
91
92 /*
93 * Copy the string on the left into the string on the right
94 * and bump the right (reference) string pointer by the length.
95 * Thus, dynamically allocate space in the right string, copying
96 * the left string into it.
97 */
98
99 char *copyin(char *src, char **space)
100 {
101 char *cp, *top;
102
103 top = cp = *space;
104 while ((*cp++ = *src++))
105 ;
106 *space = cp;
107 return top;
108 }
109
110 #define L 1 /* A lower case char */
111 #define S 2 /* A space */
112 #define D 3 /* A digit */
113 #define O 4 /* An optional digit or space */
114 #define C 5 /* A colon */
115 #define N 6 /* A new line */
116 #define U 7 /* An upper case char */
117
118 char ctypes[] = { U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0 };
119 char tmztypes[] = { U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,U,U,U,S,D,D,D,D,0 };
120
121 /*
122 * Match the given string (cp) against the given template (tp).
123 * Return 1 if they match, 0 if they don't
124 */
125
126 int cmatch(char *cp, char *tp)
127 {
128
129 while (*cp && *tp)
130 switch (*tp++) {
131 case L:
132 if (!islower(*cp++))
133 return 0;
134 break;
135 case U:
136 if (!isupper(*cp++))
137 return 0;
138 break;
139 case S:
140 if (*cp++ != ' ')
141 return 0;
142 break;
143 case D:
144 if (!isdigit(*cp++))
145 return 0;
146 break;
147 case O:
148 if (*cp != ' ' && !isdigit(*cp))
149 return 0;
150 cp++;
151 break;
152 case C:
153 if (*cp++ != ':')
154 return 0;
155 break;
156 case N:
157 if (*cp++ != '\n')
158 return 0;
159 break;
160 }
161 if (*cp || *tp)
162 return 0;
163 return 1;
164 }
165
166 /*
167 * Test to see if the passed string is a ctime(3) generated
168 * date string as documented in the manual. The template
169 * below is used as the criterion of correctness.
170 * Also, we check for a possible trailing time zone using
171 * the auxtype template.
172 */
173
174 int isdate(char date[])
175 {
176
177 if (cmatch(date, ctypes))
178 return 1;
179 return cmatch(date, tmztypes);
180 }
181
182 /*
183 * Collect a liberal (space, tab delimited) word into the word buffer
184 * passed. Also, return a pointer to the next word following that,
185 * or NULL if none follow.
186 */
187
188 char *nextword(char *wp, char *wbuf)
189 {
190 char c;
191
192 if (wp == NULL) {
193 *wbuf = 0;
194 return NULL;
195 }
196 while ((c = *wp++) && c != ' ' && c != '\t') {
197 *wbuf++ = c;
198 if (c == '"') {
199 while ((c = *wp++) && c != '"')
200 *wbuf++ = c;
201 if (c == '"')
202 *wbuf++ = c;
203 else
204 wp--;
205 }
206 }
207 *wbuf = '\0';
208 for (; c == ' ' || c == '\t'; c = *wp++)
209 ;
210 if (c == 0)
211 return NULL;
212 return (wp - 1);
213 }
0 /* mailcmd.c - Mail commands */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <syslog.h>
7
8 #include "mailcmd.h"
9 #include "defines.h"
10 #include "config.h"
11 #include "mbox.h"
12 #include "utils.h"
13
14 /* List messages */
15
16 void printhead(int i, struct message *m) {
17 char ch = ' ';
18
19 if ((m->m_flag & (MREAD|MNEW)) == MNEW)
20 ch = 'N';
21 if ((m->m_flag & (MREAD|MNEW)) == 0)
22 ch = 'U';
23 if ((m->m_flag & (MDELETED)) == MDELETED)
24 ch = 'K';
25
26 printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n",
27 (current == i+1) ? '>' : ' ',
28 ch, i+1, m->from, m->subj, m->date ,m->m_size);
29 }
30
31 int do_list(int argc, char **argv)
32 {
33 int i;
34
35 if (!(messages)) {
36 printf("No messages.\n");
37 return 0;
38 }
39
40 printf("St Num From Subject Date Size\n");
41
42 for (i = 0; i < messages; i++) {
43 printhead(i, &message[i]);
44 }
45
46 return 0;
47 }
48
49 /* Read a message (xNOS-stylish parameters) */
50
51 int do_read(int argc, char **argv)
52 {
53 char *myargv[64];
54 int myargc, argsmine;
55 char *tmpbuf;
56 int i, j, k;
57 struct message *m;
58 int msg, maxmsg;
59 char line[2000];
60
61 // Automatic Receipt generator
62 FILE *f;
63 char str [LINESIZE + 1];
64
65 if (!(messages)) {
66 printf("You have no messages.\n");
67 return 0;
68 }
69
70 if (argc > 1) {
71 argsmine = 0;
72 for (i = 1; i < argc; i++)
73 myargv[i] = argv[i];
74 myargc = argc;
75 } else {
76 argsmine = 1;
77 if (current >= messages) {
78 printf("No more messages.\n");
79 return 0;
80 }
81 current++;
82 myargc = 2;
83 myargv[1] = malloc(17);
84 sprintf(myargv[1], "echo");
85 sprintf(myargv[1], "%i", current);
86 }
87
88 for (i = 1; i < myargc; i++) {
89 tmpbuf = strchr(myargv[i], '-');
90 msg = atoi(myargv[i]);
91 if (tmpbuf == NULL)
92 maxmsg = msg;
93 else
94 maxmsg = atoi(++tmpbuf);
95 if (maxmsg < msg) {
96 printf("Bad message number %i.\n", maxmsg);
97 continue;
98 }
99 for (; msg <= maxmsg; msg++) {
100 if (msg < 1 || msg > messages) {
101 printf("There's no message number %i.\n", msg);
102 continue;
103 }
104 readmesg(msg, (!strncmp(argv[0], "v", 1)));
105 printf("--- end of message #%i --- \n", msg);
106 if (dot->receipt != NULL) {
107 getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): ");
108 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
109 /* Let's try to automate the receipt generator more */
110 f = fopen(tempMesg, "w");
111 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
112 strncpy (str, dot->from, LINESIZE);
113 printf("Receipt going to: %s\n", str);
114 fprintf(f,"To: %s\n", str);
115 fprintf(f,"X-Mailer: %s\n",VERSION);
116 fprintf(f,"X-Origin: Amateur Radio Services\n");
117 fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj);
118 strncpy (str, dot->subj, LINESIZE);
119 fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj);
120 fprintf(f,"written on %s has been read.\n\n", dot->date);
121 fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n");
122 fclose(f);
123 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
124 system(str);
125 printf("Read receipt sent.\n");
126 }
127 }
128 }
129
130 }
131 if (argsmine)
132 for (i = 1; i < myargc; i++)
133 free(myargv[i]);
134 return 0;
135 }
136
137 /* Send a message (perhaps a reply) */
138
139 int do_send(int argc, char **argv)
140 {
141 FILE *f;
142 FILE *g;
143
144 char str[LINESIZE + 1];
145 char cc[LINESIZE + 1];
146 char bcc[LINESIZE + 1];
147 int i;
148
149 int reply = 0;
150
151 if (!strncmp(argv[0], "sr", 2)) {
152 reply = 1;
153 if (argc == 1) {
154 if (current == 0) {
155 printf("No current message to reply to.\n");
156 return 0;
157 }
158 i = current;
159 } else
160 i = atoi(argv[0]);
161
162 i--;
163 if ((i < 0) || (i >= messages)) {
164 printf("Just enter SR without a parameter or number.\n");
165 return 0;
166 }
167
168 dot = &message[i];
169 }
170
171 if ((f = fopen(tempMesg, "w")) == NULL) {
172 printf("Could not create temporary file.\n");
173 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
174 return 0;
175 }
176
177 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
178
179 str[0] = '\0';
180 if (argc != 1) /* Recipient on command line */
181 for (i = 1; i < argc; i++) {
182 if (i > 1)
183 strcat(str, " ");
184 strncat(str, argv[i], LINESIZE - strlen(str));
185 }
186 else {
187 if (reply) {
188 strncpy(str, dot->from, LINESIZE);
189 printf("To: %s\n", str);
190 } else {
191 mymain:
192 getstr(str, LINESIZE, "(? = help)\nTo: ");
193 if (!strcmp(str, "?")) {
194 printf("Enter the email address or addresses separated by commas on this line\n");
195 printf("You'll be asked if you want copies to others.\n");
196 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
197 goto mymain;
198 }
199
200 if (str[0] == '\0') {
201 printf("No recipients, message cancelled.\n");
202 fclose(f);
203 remove(tempMesg);
204 return 0;
205 }
206
207 }
208 }
209
210 fprintf( f, "To: %s\n", str);
211 /* adding a carbon copy feature */
212
213 copies:
214 getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): ");
215 if (!strcmp(str, "?")) {
216 printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n");
217 printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n");
218 goto copies;
219 } else {
220
221 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
222 goto carbon;
223 } else {
224 goto prio;
225 }
226 }
227 carbon:
228 getstr(cc, LINESIZE, "(? = help)\ncc: ");
229
230 if (!strcmp(cc, "?")) {
231 printf("Enter your carbon copied address(es) below. You will be prompted for\n");
232 printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n");
233 printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n");
234 goto carbon;
235 }
236 if (cc[0] == '\0') {
237 goto goblind;
238 }
239 fprintf( f, "cc: %s\n", cc);
240
241 goblind:
242 /* adding a blind carbon copy feature */
243 getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: ");
244
245 if (!strcmp(bcc, "?")) {
246 printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n");
247 printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n");
248 goto goblind;
249 }
250 if (bcc[0] == '\0') {
251 goto header;
252 }
253 fprintf( f, "bcc: %s\n", bcc);
254
255
256 header:
257 fprintf( f, "X-Mailer: %s\n", VERSION );
258 fprintf( f, "X-Origin: Amateur Radio Services\n" );
259 goto prio;;
260
261 /* adding priority receive rule */
262
263 prio:
264 getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): ");
265
266 /* try to bullet-proof end-user responces a bit... */
267
268 if (!strcmp(str, "?")) {
269 printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n");
270 printf("priority in nature and with most mail client software will present\n");
271 printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n");
272 printf("by hitting the enter key will send your mail message via normal delivery.\n\n");
273 goto prio;
274 }
275
276 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
277 fprintf( f, "X-Priority: 1 (Highest)\n" );
278 }
279 else
280 { fprintf( f,"X-Priority: 3 (Normal)\n" );
281 }
282
283 receipt:
284 getstr(str, LINESIZE, "Read receipt requested? (y/N/?): ");
285
286 if (!strcmp(str, "?")) {
287 printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n");
288 printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n");
289 printf("by hitting the enter key will not request a confirmation receipt.\n\n");
290 goto receipt;
291 }
292
293 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
294 fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname);
295 }
296 else
297 { fprintf( f,"" );
298 }
299
300 if (reply) {
301 if (strncasecmp(dot->subj, "Re: ", 3))
302 snprintf(str, LINESIZE, "Re: %s", dot->subj);
303 else
304 snprintf(str, LINESIZE, "%s", dot->subj);
305 printf("Subject: %s\n", str);
306 } else
307 getstr(str, LINESIZE, "Subject: ");
308
309 fprintf(f, "Subject: %s\n", str);
310
311 if (reply)
312 fprintf(f, "In-Reply-To: %s\n", dot->id);
313
314 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
315 fflush(stdout);
316
317 cont:
318 do {
319 fgets(str, LINESIZE, stdin);
320 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
321 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
322
323 retry:
324 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
325 if (!strcmp(str, "?")) {
326 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
327 printf("let you continue writing the message. Answering anything else will\n");
328 printf("proceed with delivering the message to the recipient.\n");
329 goto retry;
330 }
331 if (!strcasecmp(str, "c")) {
332 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
333 fflush(stdout);
334 goto cont;
335 }
336 /* append a signature file signature to the mail message */
337 FILE *stream;
338 #ifdef CLAMSMTP
339 FILE *streamm;
340 #endif
341 char *line = NULL;
342 char *sig = NULL;
343 char buffer[79 + 1];
344 #ifdef CLAMSMTP
345 char bufferr[50 + 1];
346 #endif
347 size_t len = 0;
348 ssize_t read;
349
350 sprintf(buffer,"%s/.signature", homedir);
351 #ifdef CLAMSMTP
352 sprintf(bufferr,"/etc/clamsmtpd.conf");
353 #endif
354 stream = fopen(buffer, "r");
355 #ifdef CLAMSMTP
356 streamm = fopen(bufferr, "r");
357 #endif
358 if (stream == NULL) {
359 printf("No signature file found, use the SIG command to make one.\n");
360 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
361 #ifdef CLAMSMTP
362 if (streamm != NULL) {
363 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
364 }
365 #endif
366 goto mailmsg;
367 } else {
368 while ((read = getline(&line, &len, stream)) != -1) {
369 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
370 #ifdef CLAMSMTP
371 if (streamm != NULL) {
372 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
373 }
374 #endif
375 }
376
377 free(line);
378 fclose(stream);
379 #ifdef CLAMSMTP
380 fclose(streamm);
381 #endif
382 }
383 mailmsg:
384
385
386 if (fclose(f)) {
387 printf("Ouch, could not close temporary file.\n");
388 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
389 return 0;
390 }
391
392 delrcpt:
393 if (strcasecmp(str, "n")) {
394 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
395 if (!strcasecmp(str, "?")) {
396 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
397 printf("it that you desire notification that your mail message not only was received but\n");
398 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
399 printf("if you need to log the fact that you sent a communication to a specific person\n");
400 printf("especially for emergency communication purposes and they do NOT send you a read\n");
401 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
402 printf("you infact did send a communication and the remote person did in fact received it.\n");
403 printf("This feature can ONLY be found in axMail-FAX.\n");
404 goto delrcpt;
405 }
406 if (!strcasecmp(str, "y")) {
407 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
408 system(str);
409 printf("Message sent, delivery notification activated.\n");
410 } else {
411 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
412 system(str);
413 printf("Message sent.\n");
414 }
415 } else
416 printf("Message canceled.\n");
417
418 if (remove(tempMesg)) {
419 printf("Ouch, could not remove temporary file.\n");
420 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
421 return 0;
422 }
423
424 return 0;
425 }
426
427 /* Send a personal message with no flags or copy prompts */
428
429 int do_psend(int argc, char **argv)
430 {
431 FILE *f;
432 FILE *g;
433
434 char str[LINESIZE + 1];
435 int i;
436
437 int reply = 0;
438
439 if (!strncmp(argv[0], "sr", 2)) {
440 reply = 1;
441 if (argc == 1) {
442 if (current == 0) {
443 printf("No current message to reply to.\n");
444 return 0;
445 }
446 i = current;
447 } else
448 i = atoi(argv[0]);
449
450 i--;
451 if ((i < 0) || (i >= messages)) {
452 printf("Just enter SR without a parameter or number.\n");
453 return 0;
454 }
455
456 dot = &message[i];
457 }
458
459 if ((f = fopen(tempMesg, "w")) == NULL) {
460 printf("Could not create temporary file.\n");
461 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
462 return 0;
463 }
464
465 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
466
467 str[0] = '\0';
468 if (argc != 1) /* Recipient on command line */
469 for (i = 1; i < argc; i++) {
470 if (i > 1)
471 strcat(str, " ");
472 strncat(str, argv[i], LINESIZE - strlen(str));
473 }
474 else {
475 if (reply) {
476 strncpy(str, dot->from, LINESIZE);
477 printf("To: %s\n", str);
478 } else {
479 mypmain:
480 getstr(str, LINESIZE, "(? = help)\nTo: ");
481 if (!strcmp(str, "?")) {
482 printf("Enter the email address or addresses separated by commas on this line\n");
483 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
484 goto mypmain;
485 }
486
487 if (str[0] == '\0') {
488 printf("No recipients, message cancelled.\n");
489 fclose(f);
490 remove(tempMesg);
491 return 0;
492 }
493
494 }
495 }
496
497 fprintf( f, "To: %s\n", str);
498 fprintf( f, "X-Mailer: %s\n", VERSION );
499 fprintf( f, "X-Origin: Amateur Radio Services\n" );
500 fprintf( f, "X-Priority: 1 (Highest)\n" );
501
502 if (reply) {
503 if (strncasecmp(dot->subj, "Re: ", 3))
504 snprintf(str, LINESIZE, "Re: %s", dot->subj);
505 else
506 snprintf(str, LINESIZE, "%s", dot->subj);
507 printf("Subject: %s\n", str);
508 } else
509 getstr(str, LINESIZE, "Subject: ");
510
511 fprintf(f, "Subject: %s\n", str);
512
513 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
514 fflush(stdout);
515
516 pcont:
517 do {
518 fgets(str, LINESIZE, stdin);
519 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
520 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
521
522 pretry:
523 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
524 if (!strcmp(str, "?")) {
525 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
526 printf("let you continue writing the message. Answering anything else will\n");
527 printf("proceed with delivering the message to the recipient.\n");
528 goto pretry;
529 }
530 if (!strcasecmp(str, "c")) {
531 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
532 fflush(stdout);
533 goto pcont;
534 }
535
536 /* append a signature file signature to the mail message */
537 FILE *stream;
538 #ifdef CLAMSMTP
539 FILE *streamm;
540 #endif
541 char *line = NULL;
542 char *sig = NULL;
543 char buffer[79 + 1];
544 #ifdef CLAMSMTP
545 char bufferr[50 + 1];
546 #endif
547 size_t len = 0;
548 ssize_t read;
549
550 sprintf(buffer,"%s/.signature", homedir);
551 #ifdef CLAMSMTP
552 sprintf(bufferr,"/etc/clamsmtpd.conf");
553 #endif
554 stream = fopen(buffer, "r");
555 #ifdef CLAMSMTP
556 streamm = fopen(bufferr, "r");
557 #endif
558 if (stream == NULL) {
559 printf("No signature file found, use the SIG command to make one.\n");
560 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
561 #ifdef CLAMSMTP
562 if (streamm != NULL) {
563 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
564 }
565 #endif
566 goto pmailmsg;
567 } else {
568 while ((read = getline(&line, &len, stream)) != -1) {
569 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
570 #ifdef CLAMSMTP
571 if (streamm != NULL) {
572 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
573 }
574 #endif
575 }
576
577 free(line);
578 fclose(stream);
579 #ifdef CLAMSMTP
580 fclose(streamm);
581 #endif
582 }
583
584 pmailmsg:
585
586 if (fclose(f)) {
587 printf("Ouch, could not close temporary file.\n");
588 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
589 return 0;
590 }
591 if (strcasecmp(str, "n")) {
592 pdelrcpt:
593 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
594 if (!strcasecmp(str, "?")) {
595 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
596 printf("it that you desire notification that your mail message not only was received but\n");
597 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
598 printf("if you need to log the fact that you sent a communication to a specific person\n");
599 printf("especially for emergency communication purposes and they do NOT send you a read\n");
600 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
601 printf("you infact did send a communication and the remote person did in fact received it.\n");
602 printf("This feature can ONLY be found in axMail-FAX.\n");
603 goto pdelrcpt;
604 }
605 if (!strcasecmp(str, "y")) {
606 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
607 system(str);
608 printf("Message sent, delivery notification activated.\n");
609 } else {
610 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
611 system(str);
612 printf("Message sent.\n");
613 }
614 } else
615 printf("Message canceled.\n");
616
617 if (remove(tempMesg)) {
618 printf("Ouch, could not remove temporary file.\n");
619 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
620 return 0;
621 }
622
623 return 0;
624 }
625
626 /* Kill a message */
627
628 int do_kill(int argc, char **argv)
629 {
630 int i, msg = 0, cnt = 0;
631 char *myargv[64];
632 int myargc, argsmine;
633
634 if (!(messages)) {
635 printf("You have no messages.\n");
636 return 0;
637 }
638
639 if (argc > 1) {
640 argsmine = 0;
641 for (i = 1; i < argc; i++)
642 myargv[i] = argv[i];
643 myargc = argc;
644 } else {
645 if (current == 0) {
646 printf("No current message to kill.\n");
647 return 0;
648 }
649 argsmine = 1;
650 myargc = 2;
651 myargv[1] = malloc(17);
652 sprintf(myargv[1], "%i", current);
653 }
654
655 for (i = 1; i < myargc; i++) {
656 msg = atoi(myargv[i]) - 1;
657
658 if ((msg < 0) || (msg >= messages)) {
659 printf("There's no message %s.\n", myargv[i]);
660 continue;
661 }
662
663 dot = &message[msg];
664
665 if ((dot->m_flag & MDELETED) == MDELETED) {
666 printf("Message %i is already dead.\n", msg + 1);
667 continue;
668 }
669
670 dot->m_flag |= MDELETED;
671 cnt++;
672 }
673
674 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
675 printf("Message %i killed.\n", msg + 1);
676 else if (cnt > 1)
677 printf("%i messages killed.\n", cnt);
678
679 if (argsmine)
680 for (i = 1; i < myargc; i++)
681 free(myargv[i]);
682
683 return 0;
684 }
685
686 /* Unkill a message */
687
688 int do_unkill(int argc, char **argv)
689 {
690 int i, msg = 0, cnt = 0;
691 char *myargv[64];
692 int myargc, argsmine;
693
694 if (!(messages)) {
695 printf("You have no messages.\n");
696 return 0;
697 }
698
699 if (argc > 1) {
700 argsmine = 0;
701 for (i = 1; i < argc; i++)
702 myargv[i] = argv[i];
703 myargc = argc;
704 } else {
705 if (current == 0) {
706 printf("No current message to unkill.\n");
707 return 0;
708 }
709 argsmine = 1;
710 myargc = 2;
711 myargv[1] = malloc(17);
712 sprintf(myargv[1], "%i", current);
713 }
714
715 for (i = 1; i < myargc; i++) {
716 msg = atoi(myargv[i]) - 1;
717
718 if ((msg < 0) || (msg >= messages)) {
719 printf("There's no message %s.\n", myargv[i]);
720 continue;
721 }
722
723 dot = &message[msg];
724
725 if ((dot->m_flag & MDELETED) != MDELETED) {
726 printf("Message %i is not dead.\n", msg + 1);
727 continue;
728 }
729
730 dot->m_flag ^= (dot->m_flag & MDELETED);
731 cnt++;
732 }
733
734 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
735 printf("Message %i unkilled.\n", msg + 1);
736 else if (cnt > 1)
737 printf("%i messages unkilled.\n", cnt);
738
739 if (argsmine)
740 for (i = 1; i < myargc; i++)
741 free(myargv[i]);
742
743 return 0;
744 }
745
746 /* Send a Fax */
747 int do_fax(int argc, char **argv)
748 {
749 FILE *f;
750 char str[LINESIZE + 1];
751 int i;
752
753 int reply = 0;
754
755 if (!strncmp(argv[0], "sr", 2)) {
756 reply = 1;
757 if (argc == 1) {
758 if (current == 0) {
759 printf("No current message to reply to.\n");
760 return 0;
761 }
762 i = current;
763 } else
764 i = atoi(argv[1]);
765
766 i--;
767 if ((i < 0) || (i >= messages)) {
768 printf("There's no message %s.\n", argv[1]);
769 return 0;
770 }
771
772 dot = &message[i];
773 }
774
775 if ((f = fopen(tempMesg, "w")) == NULL) {
776 printf("Could not create temporary file.\n");
777 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
778 return 0;
779 }
780
781 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
782
783 str[0] = '\0';
784 if (argc != 1) /* Recipient on command line */
785 for (i = 1; i < argc; i++) {
786 if (i > 1)
787 strcat(str, " ");
788 strncat(str, argv[i], LINESIZE - strlen(str));
789 }
790 else {
791 }
792
793 printf("To: Fax Gateway\n");
794 fprintf( f, "To: %s\n", faxgate );
795 fprintf( f, "X-Mailer: %s\n", VERSION );
796 fprintf( f, "X-Origin: Amateur Radio Services\n" );
797 goto prio;;
798
799 /* adding priority receive rule */
800
801 prio:
802 /* if (reply) {
803 if (strncasecmp(dot->subj, "Re: ", 3))
804 snprintf(str, LINESIZE, "Re: %s", dot->subj);
805 else
806 snprintf(str, LINESIZE, "%s", dot->subj);
807 printf("Subject: %s\n", str);
808 } else */
809 getstr(str, LINESIZE, "Enter a header <firstname@fullphone Brief note here>\nEx: john@16195551212 Hi From Packet\nHeader: ");
810
811 fprintf(f, "Subject: %s\n", str);
812
813 if (reply)
814 fprintf(f, "In-Reply-To: %s\n", dot->id);
815
816 printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n");
817 fflush(stdout);
818
819 cont:
820 do {
821 /* fprintf( f, "X-Mailer: %s\n", VERSION );
822 fprintf( f, "X-Origin: Amateur Radio Services\n" ); */
823 fgets(str, LINESIZE, stdin);
824 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
825 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
826
827 retry:
828 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
829 if (!strcmp(str, "?")) {
830 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
831 printf("let you continue writing the facsimile. Answering anything else will\n");
832 printf("proceed with delivering the facsimile to the recipient.\n");
833 goto retry;
834 }
835 if (!strcasecmp(str, "c")) {
836 printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n");
837 fflush(stdout);
838 goto cont;
839 }
840
841 if (fclose(f)) {
842 printf("Ouch, could not close temporary file.\n");
843 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
844 return 0;
845 }
846
847 if (strcasecmp(str, "n")) {
848 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
849 system(str);
850 printf("Facsimile sent.\n");
851 } else
852 printf("Facsimile canceled.\n");
853
854 if (remove(tempMesg)) {
855 printf("Ouch, could not remove temporary file.\n");
856 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
857 return 0;
858 }
859
860 return 0;
861 }
0 USAGE
1 Cancel
2
3 DESCRIPTION
4 When you choose to Cancel out of the mailbox, any changes you
5 have done to your axMail-FAX mail file will NOT be saved and
6 you will be logged out of the axMail-FAX system.
0 /* mailcmd.c - Mail commands */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <syslog.h>
7
8 #include "mailcmd.h"
9 #include "defines.h"
10 #include "config.h"
11 #include "mbox.h"
12 #include "utils.h"
13
14 /* List messages */
15
16 void printhead(int i, struct message *m) {
17 char ch = ' ';
18
19 if ((m->m_flag & (MREAD|MNEW)) == MNEW)
20 ch = 'N';
21 if ((m->m_flag & (MREAD|MNEW)) == 0)
22 ch = 'U';
23 if ((m->m_flag & (MDELETED)) == MDELETED)
24 ch = 'K';
25
26 printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n",
27 (current == i+1) ? '>' : ' ',
28 ch, i+1, m->from, m->subj, m->date ,m->m_size);
29 }
30
31 int do_list(int argc, char **argv)
32 {
33 int i;
34
35 if (!(messages)) {
36 printf("No messages.\n");
37 return 0;
38 }
39
40 printf("St Num From Subject Date Size\n");
41
42 for (i = 0; i < messages; i++) {
43 printhead(i, &message[i]);
44 }
45
46 return 0;
47 }
48
49 /* Read a message (xNOS-stylish parameters) */
50
51 int do_read(int argc, char **argv)
52 {
53 char *myargv[64];
54 int myargc, argsmine;
55 char *tmpbuf;
56 int i, j, k;
57 struct message *m;
58 int msg, maxmsg;
59 char line[2000];
60
61 // Automatic Receipt generator
62 FILE *f;
63 char str [LINESIZE + 1];
64
65 if (!(messages)) {
66 printf("You have no messages.\n");
67 return 0;
68 }
69
70 if (argc > 1) {
71 argsmine = 0;
72 for (i = 1; i < argc; i++)
73 myargv[i] = argv[i];
74 myargc = argc;
75 } else {
76 argsmine = 1;
77 if (current >= messages) {
78 printf("No more messages.\n");
79 return 0;
80 }
81 current++;
82 myargc = 2;
83 myargv[1] = malloc(17);
84 sprintf(myargv[1], "echo");
85 sprintf(myargv[1], "%i", current);
86 }
87
88 for (i = 1; i < myargc; i++) {
89 tmpbuf = strchr(myargv[i], '-');
90 msg = atoi(myargv[i]);
91 if (tmpbuf == NULL)
92 maxmsg = msg;
93 else
94 maxmsg = atoi(++tmpbuf);
95 if (maxmsg < msg) {
96 printf("Bad message number %i.\n", maxmsg);
97 continue;
98 }
99 for (; msg <= maxmsg; msg++) {
100 if (msg < 1 || msg > messages) {
101 printf("There's no message number %i.\n", msg);
102 continue;
103 }
104 readmesg(msg, (!strncmp(argv[0], "v", 1)));
105 printf("--- end of message #%i --- \n", msg);
106 if (dot->receipt != NULL) {
107 getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): ");
108 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
109 /* Let's try to automate the receipt generator more */
110 f = fopen(tempMesg, "w");
111 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
112 strncpy (str, dot->from, LINESIZE);
113 printf("Receipt going to: %s\n", str);
114 fprintf(f,"To: %s\n", str);
115 fprintf(f,"X-Mailer: %s\n",VERSION);
116 fprintf(f,"X-Origin: Amateur Radio Services\n");
117 fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj);
118 strncpy (str, dot->subj, LINESIZE);
119 fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj);
120 fprintf(f,"written on %s has been read.\n\n", dot->date);
121 fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n");
122 fclose(f);
123 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
124 system(str);
125 printf("Read receipt sent.\n");
126 }
127 }
128 }
129
130 }
131 if (argsmine)
132 for (i = 1; i < myargc; i++)
133 free(myargv[i]);
134 return 0;
135 }
136
137 /* Send a message (perhaps a reply) */
138
139 int do_send(int argc, char **argv)
140 {
141 FILE *f;
142 FILE *g;
143
144 char str[LINESIZE + 1];
145 char cc[LINESIZE + 1];
146 char bcc[LINESIZE + 1];
147 int i;
148
149 int reply = 0;
150
151 if (!strncmp(argv[0], "sr", 2)) {
152 reply = 1;
153 if (argc == 1) {
154 if (current == 0) {
155 printf("No current message to reply to.\n");
156 return 0;
157 }
158 i = current;
159 } else
160 i = atoi(argv[0]);
161
162 i--;
163 if ((i < 0) || (i >= messages)) {
164 printf("Just enter SR without a parameter or number.\n");
165 return 0;
166 }
167
168 dot = &message[i];
169 }
170
171 if ((f = fopen(tempMesg, "w")) == NULL) {
172 printf("Could not create temporary file.\n");
173 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
174 return 0;
175 }
176
177 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
178
179 str[0] = '\0';
180 if (argc != 1) /* Recipient on command line */
181 for (i = 1; i < argc; i++) {
182 if (i > 1)
183 strcat(str, " ");
184 strncat(str, argv[i], LINESIZE - strlen(str));
185 }
186 else {
187 if (reply) {
188 strncpy(str, dot->from, LINESIZE);
189 printf("To: %s\n", str);
190 } else {
191 mymain:
192 getstr(str, LINESIZE, "(? = help)\nTo: ");
193 if (!strcmp(str, "?")) {
194 printf("Enter the email address or addresses separated by commas on this line\n");
195 printf("You'll be asked if you want copies to others.\n");
196 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
197 goto mymain;
198 }
199
200 if (str[0] == '\0') {
201 printf("No recipients, message cancelled.\n");
202 fclose(f);
203 remove(tempMesg);
204 return 0;
205 }
206
207 }
208 }
209
210 fprintf( f, "To: %s\n", str);
211 /* adding a carbon copy feature */
212
213 copies:
214 getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): ");
215 if (!strcmp(str, "?")) {
216 printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n");
217 printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n");
218 goto copies;
219 } else {
220
221 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
222 goto carbon;
223 } else {
224 goto prio;
225 }
226 }
227 carbon:
228 getstr(cc, LINESIZE, "(? = help)\ncc: ");
229
230 if (!strcmp(cc, "?")) {
231 printf("Enter your carbon copied address(es) below. You will be prompted for\n");
232 printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n");
233 printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n");
234 goto carbon;
235 }
236 if (cc[0] == '\0') {
237 goto goblind;
238 }
239 fprintf( f, "cc: %s\n", cc);
240
241 goblind:
242 /* adding a blind carbon copy feature */
243 getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: ");
244
245 if (!strcmp(bcc, "?")) {
246 printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n");
247 printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n");
248 goto goblind;
249 }
250 if (bcc[0] == '\0') {
251 goto header;
252 }
253 fprintf( f, "bcc: %s\n", bcc);
254
255
256 header:
257 fprintf( f, "X-Mailer: %s\n", VERSION );
258 fprintf( f, "X-Origin: Amateur Radio Services\n" );
259 goto prio;;
260
261 /* adding priority receive rule */
262
263 prio:
264 getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): ");
265
266 /* try to bullet-proof end-user responces a bit... */
267
268 if (!strcmp(str, "?")) {
269 printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n");
270 printf("priority in nature and with most mail client software will present\n");
271 printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n");
272 printf("by hitting the enter key will send your mail message via normal delivery.\n\n");
273 goto prio;
274 }
275
276 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
277 fprintf( f, "X-Priority: 1 (Highest)\n" );
278 }
279 else
280 { fprintf( f,"X-Priority: 3 (Normal)\n" );
281 }
282
283 receipt:
284 getstr(str, LINESIZE, "Read receipt requested? (y/N/?): ");
285
286 if (!strcmp(str, "?")) {
287 printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n");
288 printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n");
289 printf("by hitting the enter key will not request a confirmation receipt.\n\n");
290 goto receipt;
291 }
292
293 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
294 fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname);
295 }
296 else
297 { fprintf( f,"" );
298 }
299
300 if (reply) {
301 if (strncasecmp(dot->subj, "Re: ", 3))
302 snprintf(str, LINESIZE, "Re: %s", dot->subj);
303 else
304 snprintf(str, LINESIZE, "%s", dot->subj);
305 printf("Subject: %s\n", str);
306 } else
307 getstr(str, LINESIZE, "Subject: ");
308
309 fprintf(f, "Subject: %s\n", str);
310
311 if (reply)
312 fprintf(f, "In-Reply-To: %s\n", dot->id);
313
314 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
315 fflush(stdout);
316
317 cont:
318 do {
319 fgets(str, LINESIZE, stdin);
320 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
321 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
322
323 retry:
324 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
325 if (!strcmp(str, "?")) {
326 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
327 printf("let you continue writing the message. Answering anything else will\n");
328 printf("proceed with delivering the message to the recipient.\n");
329 goto retry;
330 }
331 if (!strcasecmp(str, "c")) {
332 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
333 fflush(stdout);
334 goto cont;
335 }
336 /* append a signature file signature to the mail message */
337 FILE *stream;
338 FILE *streamm;
339 FILE *streammm;
340 char *line = NULL;
341 char *sig = NULL;
342 char buffer[79 + 1];
343 char bufferr[50 + 1];
344 char bufferrr[50 + 1];
345 size_t len = 0;
346 ssize_t read;
347
348 sprintf(buffer,"%s/.signature", homedir);
349 sprintf(bufferr,"/etc/clamsmtpd.conf");
350 sprintf(bufferrr,"/etc/clamav/clamav-milter.conf");
351 stream = fopen(buffer, "r");
352 streamm = fopen(bufferr, "r");
353 streammm = fopen(bufferrr, "r");
354 if (stream == NULL) {
355 printf("No signature file found, use the SIG command to make one.\n");
356 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
357 if (streamm == NULL) {
358 }
359 else if (streammm == NULL) {
360 } else {
361 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
362 fclose(streamm);
363 fclose(streammm);
364 }
365
366 goto mailmsg;
367 } else {
368 while ((read = getline(&line, &len, stream)) != -1) {
369 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
370 if (streamm == NULL) {
371 } else if (streammm == NULL) {
372 } else {
373 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
374 fclose(streamm);
375 }
376 }
377
378 free(line);
379 fclose(stream);
380 }
381 mailmsg:
382
383
384 if (fclose(f)) {
385 printf("Ouch, could not close temporary file.\n");
386 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
387 return 0;
388 }
389
390 delrcpt:
391 if (strcasecmp(str, "n")) {
392 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
393 if (!strcasecmp(str, "?")) {
394 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
395 printf("it that you desire notification that your mail message not only was received but\n");
396 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
397 printf("if you need to log the fact that you sent a communication to a specific person\n");
398 printf("especially for emergency communication purposes and they do NOT send you a read\n");
399 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
400 printf("you infact did send a communication and the remote person did in fact received it.\n");
401 printf("This feature can ONLY be found in axMail-FAX.\n");
402 goto delrcpt;
403 }
404 if (!strcasecmp(str, "y")) {
405 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
406 system(str);
407 printf("Message sent, delivery notification activated.\n");
408 } else {
409 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
410 system(str);
411 printf("Message sent.\n");
412 }
413 } else
414 printf("Message canceled.\n");
415
416 if (remove(tempMesg)) {
417 printf("Ouch, could not remove temporary file.\n");
418 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
419 return 0;
420 }
421
422 return 0;
423 }
424
425 /* Send a personal message with no flags or copy prompts */
426
427 int do_psend(int argc, char **argv)
428 {
429 FILE *f;
430 FILE *g;
431
432 char str[LINESIZE + 1];
433 int i;
434
435 int reply = 0;
436
437 if (!strncmp(argv[0], "sr", 2)) {
438 reply = 1;
439 if (argc == 1) {
440 if (current == 0) {
441 printf("No current message to reply to.\n");
442 return 0;
443 }
444 i = current;
445 } else
446 i = atoi(argv[0]);
447
448 i--;
449 if ((i < 0) || (i >= messages)) {
450 printf("Just enter SR without a parameter or number.\n");
451 return 0;
452 }
453
454 dot = &message[i];
455 }
456
457 if ((f = fopen(tempMesg, "w")) == NULL) {
458 printf("Could not create temporary file.\n");
459 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
460 return 0;
461 }
462
463 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
464
465 str[0] = '\0';
466 if (argc != 1) /* Recipient on command line */
467 for (i = 1; i < argc; i++) {
468 if (i > 1)
469 strcat(str, " ");
470 strncat(str, argv[i], LINESIZE - strlen(str));
471 }
472 else {
473 if (reply) {
474 strncpy(str, dot->from, LINESIZE);
475 printf("To: %s\n", str);
476 } else {
477 mypmain:
478 getstr(str, LINESIZE, "(? = help)\nTo: ");
479 if (!strcmp(str, "?")) {
480 printf("Enter the email address or addresses separated by commas on this line\n");
481 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
482 goto mypmain;
483 }
484
485 if (str[0] == '\0') {
486 printf("No recipients, message cancelled.\n");
487 fclose(f);
488 remove(tempMesg);
489 return 0;
490 }
491
492 }
493 }
494
495 fprintf( f, "To: %s\n", str);
496 fprintf( f, "X-Mailer: %s\n", VERSION );
497 fprintf( f, "X-Origin: Amateur Radio Services\n" );
498 fprintf( f, "X-Priority: 1 (Highest)\n" );
499
500 if (reply) {
501 if (strncasecmp(dot->subj, "Re: ", 3))
502 snprintf(str, LINESIZE, "Re: %s", dot->subj);
503 else
504 snprintf(str, LINESIZE, "%s", dot->subj);
505 printf("Subject: %s\n", str);
506 } else
507 getstr(str, LINESIZE, "Subject: ");
508
509 fprintf(f, "Subject: %s\n", str);
510
511 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
512 fflush(stdout);
513
514 pcont:
515 do {
516 fgets(str, LINESIZE, stdin);
517 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
518 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
519
520 pretry:
521 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
522 if (!strcmp(str, "?")) {
523 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
524 printf("let you continue writing the message. Answering anything else will\n");
525 printf("proceed with delivering the message to the recipient.\n");
526 goto pretry;
527 }
528 if (!strcasecmp(str, "c")) {
529 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
530 fflush(stdout);
531 goto pcont;
532 }
533
534 /* append a signature file signature to the mail message */
535 FILE *stream;
536 FILE *streamm;
537 FILE *streammm;
538 char *line = NULL;
539 char *sig = NULL;
540 char buffer[79 + 1];
541 char bufferr[50 + 1];
542 char bufferrr[50 + 1];
543 size_t len = 0;
544 ssize_t read;
545
546 sprintf(buffer,"%s/.signature", homedir);
547 sprintf(bufferr,"/etc/clamsmtpd.conf");
548 sprintf(bufferrr,"/etc/clamav/clamav-milter.conf");
549 stream = fopen(buffer, "r");
550 streamm = fopen(bufferr, "r");
551 streammm= fopen(bufferrr, "r");
552 if (stream == NULL) {
553 printf("No signature file found, use the SIG command to make one.\n");
554 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
555 } else if (streamm == NULL) {
556 }
557 else if (streammm == NULL) {
558 } else {
559 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
560 fclose(streamm);
561 }
562 goto pmailmsg;
563 if (stream) {
564 while ((read = getline(&line, &len, stream)) != -1) {
565 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
566 if (streamm == NULL) {
567 }
568 if (streammm == NULL) {
569 } else {
570 fprintf(f, "\n---\nMail scanned for viri by ClamAV.");
571 fclose(streamm);
572 fclose(streammm);
573 }
574 }
575
576 free(line);
577 fclose(stream);
578 }
579
580 pmailmsg:
581
582 if (fclose(f)) {
583 printf("Ouch, could not close temporary file.\n");
584 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
585 return 0;
586 }
587 if (strcasecmp(str, "n")) {
588 pdelrcpt:
589 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
590 if (!strcasecmp(str, "?")) {
591 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
592 printf("it that you desire notification that your mail message not only was received but\n");
593 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
594 printf("if you need to log the fact that you sent a communication to a specific person\n");
595 printf("especially for emergency communication purposes and they do NOT send you a read\n");
596 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
597 printf("you infact did send a communication and the remote person did in fact received it.\n");
598 printf("This feature can ONLY be found in axMail-FAX.\n");
599 goto pdelrcpt;
600 }
601 if (!strcasecmp(str, "y")) {
602 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
603 system(str);
604 printf("Message sent, delivery notification activated.\n");
605 } else {
606 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
607 system(str);
608 printf("Message sent.\n");
609 }
610 } else
611 printf("Message canceled.\n");
612
613 if (remove(tempMesg)) {
614 printf("Ouch, could not remove temporary file.\n");
615 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
616 return 0;
617 }
618
619 return 0;
620 }
621
622 /* Kill a message */
623
624 int do_kill(int argc, char **argv)
625 {
626 int i, msg = 0, cnt = 0;
627 char *myargv[64];
628 int myargc, argsmine;
629
630 if (!(messages)) {
631 printf("You have no messages.\n");
632 return 0;
633 }
634
635 if (argc > 1) {
636 argsmine = 0;
637 for (i = 1; i < argc; i++)
638 myargv[i] = argv[i];
639 myargc = argc;
640 } else {
641 if (current == 0) {
642 printf("No current message to kill.\n");
643 return 0;
644 }
645 argsmine = 1;
646 myargc = 2;
647 myargv[1] = malloc(17);
648 sprintf(myargv[1], "%i", current);
649 }
650
651 for (i = 1; i < myargc; i++) {
652 msg = atoi(myargv[i]) - 1;
653
654 if ((msg < 0) || (msg >= messages)) {
655 printf("There's no message %s.\n", myargv[i]);
656 continue;
657 }
658
659 dot = &message[msg];
660
661 if ((dot->m_flag & MDELETED) == MDELETED) {
662 printf("Message %i is already dead.\n", msg + 1);
663 continue;
664 }
665
666 dot->m_flag |= MDELETED;
667 cnt++;
668 }
669
670 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
671 printf("Message %i killed.\n", msg + 1);
672 else if (cnt > 1)
673 printf("%i messages killed.\n", cnt);
674
675 if (argsmine)
676 for (i = 1; i < myargc; i++)
677 free(myargv[i]);
678
679 return 0;
680 }
681
682 /* Unkill a message */
683
684 int do_unkill(int argc, char **argv)
685 {
686 int i, msg = 0, cnt = 0;
687 char *myargv[64];
688 int myargc, argsmine;
689
690 if (!(messages)) {
691 printf("You have no messages.\n");
692 return 0;
693 }
694
695 if (argc > 1) {
696 argsmine = 0;
697 for (i = 1; i < argc; i++)
698 myargv[i] = argv[i];
699 myargc = argc;
700 } else {
701 if (current == 0) {
702 printf("No current message to unkill.\n");
703 return 0;
704 }
705 argsmine = 1;
706 myargc = 2;
707 myargv[1] = malloc(17);
708 sprintf(myargv[1], "%i", current);
709 }
710
711 for (i = 1; i < myargc; i++) {
712 msg = atoi(myargv[i]) - 1;
713
714 if ((msg < 0) || (msg >= messages)) {
715 printf("There's no message %s.\n", myargv[i]);
716 continue;
717 }
718
719 dot = &message[msg];
720
721 if ((dot->m_flag & MDELETED) != MDELETED) {
722 printf("Message %i is not dead.\n", msg + 1);
723 continue;
724 }
725
726 dot->m_flag ^= (dot->m_flag & MDELETED);
727 cnt++;
728 }
729
730 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
731 printf("Message %i unkilled.\n", msg + 1);
732 else if (cnt > 1)
733 printf("%i messages unkilled.\n", cnt);
734
735 if (argsmine)
736 for (i = 1; i < myargc; i++)
737 free(myargv[i]);
738
739 return 0;
740 }
741
742 /* Send a Fax */
743 int do_fax(int argc, char **argv)
744 {
745 FILE *f;
746 char str[LINESIZE + 1];
747 int i;
748
749 int reply = 0;
750
751 if (!strncmp(argv[0], "sr", 2)) {
752 reply = 1;
753 if (argc == 1) {
754 if (current == 0) {
755 printf("No current message to reply to.\n");
756 return 0;
757 }
758 i = current;
759 } else
760 i = atoi(argv[1]);
761
762 i--;
763 if ((i < 0) || (i >= messages)) {
764 printf("There's no message %s.\n", argv[1]);
765 return 0;
766 }
767
768 dot = &message[i];
769 }
770
771 if ((f = fopen(tempMesg, "w")) == NULL) {
772 printf("Could not create temporary file.\n");
773 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
774 return 0;
775 }
776
777 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
778
779 str[0] = '\0';
780 if (argc != 1) /* Recipient on command line */
781 for (i = 1; i < argc; i++) {
782 if (i > 1)
783 strcat(str, " ");
784 strncat(str, argv[i], LINESIZE - strlen(str));
785 }
786 else {
787 }
788
789 printf("To: Fax Gateway\n");
790 fprintf( f, "To: %s\n", faxgate );
791 fprintf( f, "X-Mailer: %s\n", VERSION );
792 fprintf( f, "X-Origin: Amateur Radio Services\n" );
793 goto prio;;
794
795 /* adding priority receive rule */
796
797 prio:
798 /* if (reply) {
799 if (strncasecmp(dot->subj, "Re: ", 3))
800 snprintf(str, LINESIZE, "Re: %s", dot->subj);
801 else
802 snprintf(str, LINESIZE, "%s", dot->subj);
803 printf("Subject: %s\n", str);
804 } else */
805 getstr(str, LINESIZE, "Enter a header <firstname@fullphone Brief note here>\nEx: john@16195551212 Hi From Packet\nHeader: ");
806
807 fprintf(f, "Subject: %s\n", str);
808
809 if (reply)
810 fprintf(f, "In-Reply-To: %s\n", dot->id);
811
812 printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n");
813 fflush(stdout);
814
815 cont:
816 do {
817 /* fprintf( f, "X-Mailer: %s\n", VERSION );
818 fprintf( f, "X-Origin: Amateur Radio Services\n" ); */
819 fgets(str, LINESIZE, stdin);
820 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
821 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
822
823 retry:
824 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
825 if (!strcmp(str, "?")) {
826 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
827 printf("let you continue writing the facsimile. Answering anything else will\n");
828 printf("proceed with delivering the facsimile to the recipient.\n");
829 goto retry;
830 }
831 if (!strcasecmp(str, "c")) {
832 printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n");
833 fflush(stdout);
834 goto cont;
835 }
836
837 if (fclose(f)) {
838 printf("Ouch, could not close temporary file.\n");
839 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
840 return 0;
841 }
842
843 if (strcasecmp(str, "n")) {
844 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
845 system(str);
846 printf("Facsimile sent.\n");
847 } else
848 printf("Facsimile canceled.\n");
849
850 if (remove(tempMesg)) {
851 printf("Ouch, could not remove temporary file.\n");
852 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
853 return 0;
854 }
855
856 return 0;
857 }
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.13"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2021 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/lib/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 Subject: Welcome to axMail-FAX
1
2 Welcome to axmail! Your email address is listed above the prompt.
3 For further assistance, try "?" or email root.
4
5 axMail is the first mail client for packet that allows it's users the ability
6 to:
7 send/receive emails, send outbound faxing with confirmations and receipts
8 read receipts for their mail , server to server confirmation of delivery of mail
9 cc and bcc fields for multiple copies of mail, priority flagging for emergency
10 communications, and an SP shortcut for those using HF to bypass many prompting
11 ...all by using just a dumb terminal.
12
13 Some sites may offer pop3/IMAP/webmail as well. Contact your sysop to see if
14 this is possible.
15
16 73!
0
1 #include <utmp.h>
2 #include "defines.h"
3
4 #undef CLAMSMTP
5
6 extern char callsign[20];
7 extern char username[20];
8 extern char fullname[31];
9 extern char forward[79];
10
11 extern char *homedir; /* User's home directory */
12 extern char *fwdfile; /* User's .forward file (~/.forward) */
13 extern char *sigfile; /* User's .signature file (~/.signature) */
14 extern char *maildir; /* User's mail directory (~/mail) */
15 extern char *mailbox; /* System mailbox (/var/spool/mail/user) */
16 extern char *userbox; /* User's mailbox (~/mbox) */
17 extern char *mailconf; /* User's own axmail configuration */
18
19 extern int local; /* Running with user privileges? */
20
21 extern char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */
22 extern char *tempRcpt; /* Temporary files: return receipt */
23 extern char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */
24 extern char *tempEdit;
25 extern char *tempMesg;
26
27 extern char *faxgate; /* Email of your E-Fax Gateway */
28 extern char *hostname;
29 extern char *sysopmail;
30 extern char *def_shell; /* Default settings for autoaccounts */
31 extern char *def_homedir;
32
33 extern int mail_allowed, identification, autocreate, login_allowed;
34 extern int first_uid, last_uid;
35 extern gid_t user_gid;
36 extern char mboxname[PATHSIZE];
37 extern long IdleTimeout;
38
39 struct cmd {
40 char *name;
41 int (*function) (int argc, char **argv);
42 };
43
44 extern struct cmd Mailcmds[];
45
46 extern void tinit(void);
47 extern int read_config(void);
0
1 #include <utmp.h>
2 #include "defines.h"
3
4 //#define CLAMSMTP
5
6 extern char callsign[20];
7 extern char username[20];
8 extern char fullname[31];
9 extern char forward[79];
10
11 extern char *homedir; /* User's home directory */
12 extern char *fwdfile; /* User's .forward file (~/.forward) */
13 extern char *sigfile; /* User's .signature file (~/.signature) */
14 extern char *maildir; /* User's mail directory (~/mail) */
15 extern char *mailbox; /* System mailbox (/var/spool/mail/user) */
16 extern char *userbox; /* User's mailbox (~/mbox) */
17 extern char *mailconf; /* User's own axmail configuration */
18
19 extern int local; /* Running with user privileges? */
20
21 extern char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */
22 extern char *tempRcpt; /* Temporary files: return receipt */
23 extern char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */
24 extern char *tempEdit;
25 extern char *tempMesg;
26
27 extern char *faxgate; /* Email of your E-Fax Gateway */
28 extern char *hostname;
29 extern char *sysopmail;
30 extern char *def_shell; /* Default settings for autoaccounts */
31 extern char *def_homedir;
32
33 extern int mail_allowed, identification, autocreate, login_allowed;
34 extern int first_uid, last_uid;
35 extern gid_t user_gid;
36 extern char mboxname[PATHSIZE];
37 extern long IdleTimeout;
38
39 struct cmd {
40 char *name;
41 int (*function) (int argc, char **argv);
42 };
43
44 extern struct cmd Mailcmds[];
45
46 extern void tinit(void);
47 extern int read_config(void);
0 USAGE
1 Verbose <msg #>
2
3 DESCRIPTION
4 Like with the Read command, verbose will print out the full mail
5 headers along with the body of the message. This command requires
6 a parameter consisting of the message number you wish to read.
7 Ex: V 3 will verbosely print message #3 including all mail
8 headers. This can be quite lengthy but also can be quite
9 handy if you're trying to find out if someone else's mail
10 account may have been compromised or spoofed.
0 # /etc/ax25/axmail.conf - axMail configuration file
1 #
2
3 # Idle timeout (seconds).
4 IdleTimeout 900
5
6 # Local hostname.
7 HostName <your>.ampr.org
8
9 # Sysop's email address
10 SysopMail <your@email.address>
11
12 # Who (of those who are listed in /etc/passwd) are allowed to use axmail
13 # all : All users who have an account (or have just created one)
14 # nologin : Those who have "+" as password (the axmail-only accounts)
15 # passwd : Those who have a password set (NOT those with "+" as password)
16 # axhome : Those who put all ham home dirs within one branch
17 AllowMail all
18
19 # Do we ask for a password or rely on the callsign
20 # none : Trust the callsign given on command line
21 # passwd : Ask for a plaintext password (brrrr...)
22 # TODO: MDn authenthication !
23 Identification none
24
25 #
26 # ------ Parameters for automatically created user accounts
27 #
28
29 # Allow automatic creation of user accounts
30 AutoCreate yes
31
32 # Automatically created login accounts can login (through telnet, etc)
33 # yes : User is prompted for password, when the account is created
34 # no : Password is set to "+" (cannot login) (preferred, axmail-only
35 # account)
36 # crazy : Password is left empty (can login without password)
37 LoginAllowed no
38
39 # Group name or id for autoaccount
40 AutoGroup ax25
41
42 # First user id to use for automatically created accounts
43 First_uid 2000
44
45 # Maximum user id
46 Last_uid 2999
47
48 # Where to add the home directories for the new users
49 HomeDir /home
50
51 # User shell
52 Shell /bin/false
53
54 # Fax Gateway - must be defined without quotes
55 FaxGate "your@faxgate.com"
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.12.1"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2021 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 /* mailcmd.c - Mail commands */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <syslog.h>
7
8 #include "mailcmd.h"
9 #include "defines.h"
10 #include "config.h"
11 #include "mbox.h"
12 #include "utils.h"
13
14 /* List messages */
15
16 void printhead(int i, struct message *m) {
17 char ch = ' ';
18
19 if ((m->m_flag & (MREAD|MNEW)) == MNEW)
20 ch = 'N';
21 if ((m->m_flag & (MREAD|MNEW)) == 0)
22 ch = 'U';
23 if ((m->m_flag & (MDELETED)) == MDELETED)
24 ch = 'K';
25
26 printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n",
27 (current == i+1) ? '>' : ' ',
28 ch, i+1, m->from, m->subj, m->date ,m->m_size);
29 }
30
31 int do_list(int argc, char **argv)
32 {
33 int i;
34
35 if (!(messages)) {
36 printf("No messages.\n");
37 return 0;
38 }
39
40 printf("St Num From Subject Date Size\n");
41
42 for (i = 0; i < messages; i++) {
43 printhead(i, &message[i]);
44 }
45
46 return 0;
47 }
48
49 /* Read a message (xNOS-stylish parameters) */
50
51 int do_read(int argc, char **argv)
52 {
53 char *myargv[64];
54 int myargc, argsmine;
55 char *tmpbuf;
56 int i, j, k;
57 struct message *m;
58 int msg, maxmsg;
59 char line[2000];
60
61 // Automatic Receipt generator
62 FILE *f;
63 char str [LINESIZE + 1];
64
65 if (!(messages)) {
66 printf("You have no messages.\n");
67 return 0;
68 }
69
70 if (argc > 1) {
71 argsmine = 0;
72 for (i = 1; i < argc; i++)
73 myargv[i] = argv[i];
74 myargc = argc;
75 } else {
76 argsmine = 1;
77 if (current >= messages) {
78 printf("No more messages.\n");
79 return 0;
80 }
81 current++;
82 myargc = 2;
83 myargv[1] = malloc(17);
84 sprintf(myargv[1], "echo");
85 sprintf(myargv[1], "%i", current);
86 }
87
88 for (i = 1; i < myargc; i++) {
89 tmpbuf = strchr(myargv[i], '-');
90 msg = atoi(myargv[i]);
91 if (tmpbuf == NULL)
92 maxmsg = msg;
93 else
94 maxmsg = atoi(++tmpbuf);
95 if (maxmsg < msg) {
96 printf("Bad message number %i.\n", maxmsg);
97 continue;
98 }
99 for (; msg <= maxmsg; msg++) {
100 if (msg < 1 || msg > messages) {
101 printf("There's no message number %i.\n", msg);
102 continue;
103 }
104 readmesg(msg, (!strncmp(argv[0], "v", 1)));
105 printf("--- end of message #%i --- \n", msg);
106 if (dot->receipt != NULL) {
107 getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): ");
108 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
109 /* Let's try to automate the receipt generator more */
110 f = fopen(tempMesg, "w");
111 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
112 strncpy (str, dot->from, LINESIZE);
113 printf("Receipt going to: %s\n", str);
114 fprintf(f,"To: %s\n", str);
115 fprintf(f,"X-Mailer: %s\n",VERSION);
116 fprintf(f,"X-Origin: Amateur Radio Services\n");
117 fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj);
118 strncpy (str, dot->subj, LINESIZE);
119 fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj);
120 fprintf(f,"written on %s has been read.\n\n", dot->date);
121 fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n");
122 fclose(f);
123 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
124 system(str);
125 printf("Read receipt sent.\n");
126 }
127 }
128 }
129
130 }
131 if (argsmine)
132 for (i = 1; i < myargc; i++)
133 free(myargv[i]);
134 return 0;
135 }
136
137 /* Send a message (perhaps a reply) */
138
139 int do_send(int argc, char **argv)
140 {
141 FILE *f;
142 FILE *g;
143
144 char str[LINESIZE + 1];
145 char cc[LINESIZE + 1];
146 char bcc[LINESIZE + 1];
147 int i;
148
149 int reply = 0;
150
151 if (!strncmp(argv[0], "sr", 2)) {
152 reply = 1;
153 if (argc == 1) {
154 if (current == 0) {
155 printf("No current message to reply to.\n");
156 return 0;
157 }
158 i = current;
159 } else
160 i = atoi(argv[0]);
161
162 i--;
163 if ((i < 0) || (i >= messages)) {
164 printf("Just enter SR without a parameter or number.\n");
165 return 0;
166 }
167
168 dot = &message[i];
169 }
170
171 if ((f = fopen(tempMesg, "w")) == NULL) {
172 printf("Could not create temporary file.\n");
173 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
174 return 0;
175 }
176
177 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
178
179 str[0] = '\0';
180 if (argc != 1) /* Recipient on command line */
181 for (i = 1; i < argc; i++) {
182 if (i > 1)
183 strcat(str, " ");
184 strncat(str, argv[i], LINESIZE - strlen(str));
185 }
186 else {
187 if (reply) {
188 strncpy(str, dot->from, LINESIZE);
189 printf("To: %s\n", str);
190 } else {
191 mymain:
192 getstr(str, LINESIZE, "(? = help)\nTo: ");
193 if (!strcmp(str, "?")) {
194 printf("Enter the email address or addresses separated by commas on this line\n");
195 printf("You'll be asked if you want copies to others.\n");
196 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
197 goto mymain;
198 }
199
200 if (str[0] == '\0') {
201 printf("No recipients, message cancelled.\n");
202 fclose(f);
203 remove(tempMesg);
204 return 0;
205 }
206
207 }
208 }
209
210 fprintf( f, "To: %s\n", str);
211 /* adding a carbon copy feature */
212
213 copies:
214 getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): ");
215 if (!strcmp(str, "?")) {
216 printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n");
217 printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n");
218 goto copies;
219 } else {
220
221 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
222 goto carbon;
223 } else {
224 goto prio;
225 }
226 }
227 carbon:
228 getstr(cc, LINESIZE, "(? = help)\ncc: ");
229
230 if (!strcmp(cc, "?")) {
231 printf("Enter your carbon copied address(es) below. You will be prompted for\n");
232 printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n");
233 printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n");
234 goto carbon;
235 }
236 if (cc[0] == '\0') {
237 goto goblind;
238 }
239 fprintf( f, "cc: %s\n", cc);
240
241 goblind:
242 /* adding a blind carbon copy feature */
243 getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: ");
244
245 if (!strcmp(bcc, "?")) {
246 printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n");
247 printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n");
248 goto goblind;
249 }
250 if (bcc[0] == '\0') {
251 goto header;
252 }
253 fprintf( f, "bcc: %s\n", bcc);
254
255
256 header:
257 fprintf( f, "X-Mailer: %s\n", VERSION );
258 fprintf( f, "X-Origin: Amateur Radio Services\n" );
259 goto prio;;
260
261 /* adding priority receive rule */
262
263 prio:
264 getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): ");
265
266 /* try to bullet-proof end-user responces a bit... */
267
268 if (!strcmp(str, "?")) {
269 printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n");
270 printf("priority in nature and with most mail client software will present\n");
271 printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n");
272 printf("by hitting the enter key will send your mail message via normal delivery.\n\n");
273 goto prio;
274 }
275
276 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
277 fprintf( f, "X-Priority: 1 (Highest)\n" );
278 }
279 else
280 { fprintf( f,"X-Priority: 3 (Normal)\n" );
281 }
282
283 receipt:
284 getstr(str, LINESIZE, "Read receipt requested? (y/N/?): ");
285
286 if (!strcmp(str, "?")) {
287 printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n");
288 printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n");
289 printf("by hitting the enter key will not request a confirmation receipt.\n\n");
290 goto receipt;
291 }
292
293 if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) {
294 fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname);
295 }
296 else
297 { fprintf( f,"" );
298 }
299
300 if (reply) {
301 if (strncasecmp(dot->subj, "Re: ", 3))
302 snprintf(str, LINESIZE, "Re: %s", dot->subj);
303 else
304 snprintf(str, LINESIZE, "%s", dot->subj);
305 printf("Subject: %s\n", str);
306 } else
307 getstr(str, LINESIZE, "Subject: ");
308
309 fprintf(f, "Subject: %s\n", str);
310
311 if (reply)
312 fprintf(f, "In-Reply-To: %s\n", dot->id);
313
314 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
315 fflush(stdout);
316
317 cont:
318 do {
319 fgets(str, LINESIZE, stdin);
320 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
321 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
322
323 retry:
324 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
325 if (!strcmp(str, "?")) {
326 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
327 printf("let you continue writing the message. Answering anything else will\n");
328 printf("proceed with delivering the message to the recipient.\n");
329 goto retry;
330 }
331 if (!strcasecmp(str, "c")) {
332 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
333 fflush(stdout);
334 goto cont;
335 }
336 /* append a signature file signature to the mail message */
337 FILE *stream;
338 FILE *streamm;
339 char *line = NULL;
340 char *sig = NULL;
341 char buffer[79 + 1];
342 char bufferr[50 + 1];
343 size_t len = 0;
344 ssize_t read;
345
346 sprintf(buffer,"%s/.signature", homedir);
347 sprintf(bufferr,"/etc/clamsmtpd.conf");
348 stream = fopen(buffer, "r");
349 streamm = fopen(bufferr, "r");
350 if (stream == NULL) {
351 printf("No signature file found, use the SIG command to make one.\n");
352 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
353 if (streamm == NULL) {
354 } else {
355 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
356 fclose(streamm);
357 }
358 goto mailmsg;
359 } else {
360 while ((read = getline(&line, &len, stream)) != -1) {
361 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
362 if (streamm == NULL) {
363 } else {
364 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
365 fclose(streamm);
366 }
367 }
368
369 free(line);
370 fclose(stream);
371 }
372 mailmsg:
373
374
375 if (fclose(f)) {
376 printf("Ouch, could not close temporary file.\n");
377 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
378 return 0;
379 }
380
381 delrcpt:
382 if (strcasecmp(str, "n")) {
383 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
384 if (!strcasecmp(str, "?")) {
385 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
386 printf("it that you desire notification that your mail message not only was received but\n");
387 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
388 printf("if you need to log the fact that you sent a communication to a specific person\n");
389 printf("especially for emergency communication purposes and they do NOT send you a read\n");
390 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
391 printf("you infact did send a communication and the remote person did in fact received it.\n");
392 printf("This feature can ONLY be found in axMail-FAX.\n");
393 goto delrcpt;
394 }
395 if (!strcasecmp(str, "y")) {
396 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
397 system(str);
398 printf("Message sent, delivery notification activated.\n");
399 } else {
400 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
401 system(str);
402 printf("Message sent.\n");
403 }
404 } else
405 printf("Message canceled.\n");
406
407 if (remove(tempMesg)) {
408 printf("Ouch, could not remove temporary file.\n");
409 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
410 return 0;
411 }
412
413 return 0;
414 }
415
416 /* Send a personal message with no flags or copy prompts */
417
418 int do_psend(int argc, char **argv)
419 {
420 FILE *f;
421 FILE *g;
422
423 char str[LINESIZE + 1];
424 int i;
425
426 int reply = 0;
427
428 if (!strncmp(argv[0], "sr", 2)) {
429 reply = 1;
430 if (argc == 1) {
431 if (current == 0) {
432 printf("No current message to reply to.\n");
433 return 0;
434 }
435 i = current;
436 } else
437 i = atoi(argv[0]);
438
439 i--;
440 if ((i < 0) || (i >= messages)) {
441 printf("Just enter SR without a parameter or number.\n");
442 return 0;
443 }
444
445 dot = &message[i];
446 }
447
448 if ((f = fopen(tempMesg, "w")) == NULL) {
449 printf("Could not create temporary file.\n");
450 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
451 return 0;
452 }
453
454 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
455
456 str[0] = '\0';
457 if (argc != 1) /* Recipient on command line */
458 for (i = 1; i < argc; i++) {
459 if (i > 1)
460 strcat(str, " ");
461 strncat(str, argv[i], LINESIZE - strlen(str));
462 }
463 else {
464 if (reply) {
465 strncpy(str, dot->from, LINESIZE);
466 printf("To: %s\n", str);
467 } else {
468 mypmain:
469 getstr(str, LINESIZE, "(? = help)\nTo: ");
470 if (!strcmp(str, "?")) {
471 printf("Enter the email address or addresses separated by commas on this line\n");
472 printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n");
473 goto mypmain;
474 }
475
476 if (str[0] == '\0') {
477 printf("No recipients, message cancelled.\n");
478 fclose(f);
479 remove(tempMesg);
480 return 0;
481 }
482
483 }
484 }
485
486 fprintf( f, "To: %s\n", str);
487 fprintf( f, "X-Mailer: %s\n", VERSION );
488 fprintf( f, "X-Origin: Amateur Radio Services\n" );
489 fprintf( f, "X-Priority: 1 (Highest)\n" );
490
491 if (reply) {
492 if (strncasecmp(dot->subj, "Re: ", 3))
493 snprintf(str, LINESIZE, "Re: %s", dot->subj);
494 else
495 snprintf(str, LINESIZE, "%s", dot->subj);
496 printf("Subject: %s\n", str);
497 } else
498 getstr(str, LINESIZE, "Subject: ");
499
500 fprintf(f, "Subject: %s\n", str);
501
502 printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n");
503 fflush(stdout);
504
505 pcont:
506 do {
507 fgets(str, LINESIZE, stdin);
508 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
509 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
510
511 pretry:
512 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
513 if (!strcmp(str, "?")) {
514 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
515 printf("let you continue writing the message. Answering anything else will\n");
516 printf("proceed with delivering the message to the recipient.\n");
517 goto pretry;
518 }
519 if (!strcasecmp(str, "c")) {
520 printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n");
521 fflush(stdout);
522 goto pcont;
523 }
524
525 /* append a signature file signature to the mail message */
526 FILE *stream;
527 FILE *streamm;
528 char *line = NULL;
529 char *sig = NULL;
530 char buffer[79 + 1];
531 char bufferr[50 + 1];
532 size_t len = 0;
533 ssize_t read;
534
535 sprintf(buffer,"%s/.signature", homedir);
536 sprintf(bufferr,"/etc/clamsmtpd.conf");
537 stream = fopen(buffer, "r");
538 streamm = fopen(bufferr, "r");
539 if (stream == NULL) {
540 printf("No signature file found, use the SIG command to make one.\n");
541 fprintf(f, "\n---\nsent via axMail-FAX by N1URO.");
542 if (streamm == NULL) {
543 } else {
544 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
545 fclose(streamm);
546 }
547 goto pmailmsg;
548 } else {
549 while ((read = getline(&line, &len, stream)) != -1) {
550 fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line);
551 if (streamm == NULL) {
552 } else {
553 fprintf(f, "\n---\nMail scanned for viri by ClamSMTP.");
554 fclose(streamm);
555 }
556 }
557
558 free(line);
559 fclose(stream);
560 }
561
562 pmailmsg:
563
564 if (fclose(f)) {
565 printf("Ouch, could not close temporary file.\n");
566 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
567 return 0;
568 }
569 if (strcasecmp(str, "n")) {
570 pdelrcpt:
571 getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): ");
572 if (!strcasecmp(str, "?")) {
573 printf("Requesting a delivery receipt sends the remote mail server a command that tells\n");
574 printf("it that you desire notification that your mail message not only was received but\n");
575 printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n");
576 printf("if you need to log the fact that you sent a communication to a specific person\n");
577 printf("especially for emergency communication purposes and they do NOT send you a read\n");
578 printf("receipt even though you asked for one, this covers you and is your log of proof that\n");
579 printf("you infact did send a communication and the remote person did in fact received it.\n");
580 printf("This feature can ONLY be found in axMail-FAX.\n");
581 goto pdelrcpt;
582 }
583 if (!strcasecmp(str, "y")) {
584 sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
585 system(str);
586 printf("Message sent, delivery notification activated.\n");
587 } else {
588 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
589 system(str);
590 printf("Message sent.\n");
591 }
592 } else
593 printf("Message canceled.\n");
594
595 if (remove(tempMesg)) {
596 printf("Ouch, could not remove temporary file.\n");
597 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
598 return 0;
599 }
600
601 return 0;
602 }
603
604 /* Kill a message */
605
606 int do_kill(int argc, char **argv)
607 {
608 int i, msg = 0, cnt = 0;
609 char *myargv[64];
610 int myargc, argsmine;
611
612 if (!(messages)) {
613 printf("You have no messages.\n");
614 return 0;
615 }
616
617 if (argc > 1) {
618 argsmine = 0;
619 for (i = 1; i < argc; i++)
620 myargv[i] = argv[i];
621 myargc = argc;
622 } else {
623 if (current == 0) {
624 printf("No current message to kill.\n");
625 return 0;
626 }
627 argsmine = 1;
628 myargc = 2;
629 myargv[1] = malloc(17);
630 sprintf(myargv[1], "%i", current);
631 }
632
633 for (i = 1; i < myargc; i++) {
634 msg = atoi(myargv[i]) - 1;
635
636 if ((msg < 0) || (msg >= messages)) {
637 printf("There's no message %s.\n", myargv[i]);
638 continue;
639 }
640
641 dot = &message[msg];
642
643 if ((dot->m_flag & MDELETED) == MDELETED) {
644 printf("Message %i is already dead.\n", msg + 1);
645 continue;
646 }
647
648 dot->m_flag |= MDELETED;
649 cnt++;
650 }
651
652 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
653 printf("Message %i killed.\n", msg + 1);
654 else if (cnt > 1)
655 printf("%i messages killed.\n", cnt);
656
657 if (argsmine)
658 for (i = 1; i < myargc; i++)
659 free(myargv[i]);
660
661 return 0;
662 }
663
664 /* Unkill a message */
665
666 int do_unkill(int argc, char **argv)
667 {
668 int i, msg = 0, cnt = 0;
669 char *myargv[64];
670 int myargc, argsmine;
671
672 if (!(messages)) {
673 printf("You have no messages.\n");
674 return 0;
675 }
676
677 if (argc > 1) {
678 argsmine = 0;
679 for (i = 1; i < argc; i++)
680 myargv[i] = argv[i];
681 myargc = argc;
682 } else {
683 if (current == 0) {
684 printf("No current message to unkill.\n");
685 return 0;
686 }
687 argsmine = 1;
688 myargc = 2;
689 myargv[1] = malloc(17);
690 sprintf(myargv[1], "%i", current);
691 }
692
693 for (i = 1; i < myargc; i++) {
694 msg = atoi(myargv[i]) - 1;
695
696 if ((msg < 0) || (msg >= messages)) {
697 printf("There's no message %s.\n", myargv[i]);
698 continue;
699 }
700
701 dot = &message[msg];
702
703 if ((dot->m_flag & MDELETED) != MDELETED) {
704 printf("Message %i is not dead.\n", msg + 1);
705 continue;
706 }
707
708 dot->m_flag ^= (dot->m_flag & MDELETED);
709 cnt++;
710 }
711
712 if (cnt == 1) /* GCC warns here, but what the heck! 8-) */
713 printf("Message %i unkilled.\n", msg + 1);
714 else if (cnt > 1)
715 printf("%i messages unkilled.\n", cnt);
716
717 if (argsmine)
718 for (i = 1; i < myargc; i++)
719 free(myargv[i]);
720
721 return 0;
722 }
723
724 /* Send a Fax */
725 int do_fax(int argc, char **argv)
726 {
727 FILE *f;
728 char str[LINESIZE + 1];
729 int i;
730
731 int reply = 0;
732
733 if (!strncmp(argv[0], "sr", 2)) {
734 reply = 1;
735 if (argc == 1) {
736 if (current == 0) {
737 printf("No current message to reply to.\n");
738 return 0;
739 }
740 i = current;
741 } else
742 i = atoi(argv[1]);
743
744 i--;
745 if ((i < 0) || (i >= messages)) {
746 printf("There's no message %s.\n", argv[1]);
747 return 0;
748 }
749
750 dot = &message[i];
751 }
752
753 if ((f = fopen(tempMesg, "w")) == NULL) {
754 printf("Could not create temporary file.\n");
755 syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n");
756 return 0;
757 }
758
759 fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname);
760
761 str[0] = '\0';
762 if (argc != 1) /* Recipient on command line */
763 for (i = 1; i < argc; i++) {
764 if (i > 1)
765 strcat(str, " ");
766 strncat(str, argv[i], LINESIZE - strlen(str));
767 }
768 else {
769 }
770
771 printf("To: Fax Gateway\n");
772 fprintf( f, "To: %s\n", faxgate );
773 fprintf( f, "X-Mailer: %s\n", VERSION );
774 fprintf( f, "X-Origin: Amateur Radio Services\n" );
775 goto prio;;
776
777 /* adding priority receive rule */
778
779 prio:
780 /* if (reply) {
781 if (strncasecmp(dot->subj, "Re: ", 3))
782 snprintf(str, LINESIZE, "Re: %s", dot->subj);
783 else
784 snprintf(str, LINESIZE, "%s", dot->subj);
785 printf("Subject: %s\n", str);
786 } else */
787 getstr(str, LINESIZE, "Enter a header <firstname@fullphone Brief note here>\nEx: john@16195551212 Hi From Packet\nHeader: ");
788
789 fprintf(f, "Subject: %s\n", str);
790
791 if (reply)
792 fprintf(f, "In-Reply-To: %s\n", dot->id);
793
794 printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n");
795 fflush(stdout);
796
797 cont:
798 do {
799 /* fprintf( f, "X-Mailer: %s\n", VERSION );
800 fprintf( f, "X-Origin: Amateur Radio Services\n" ); */
801 fgets(str, LINESIZE, stdin);
802 if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f);
803 } while (strcmp(str, ".\n") && strcmp(str, "/ex\n"));
804
805 retry:
806 getstr(str, LINESIZE, "Deliver (Y/n/c/?): ");
807 if (!strcmp(str, "?")) {
808 printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n");
809 printf("let you continue writing the facsimile. Answering anything else will\n");
810 printf("proceed with delivering the facsimile to the recipient.\n");
811 goto retry;
812 }
813 if (!strcasecmp(str, "c")) {
814 printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n");
815 fflush(stdout);
816 goto cont;
817 }
818
819 if (fclose(f)) {
820 printf("Ouch, could not close temporary file.\n");
821 syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n");
822 return 0;
823 }
824
825 if (strcasecmp(str, "n")) {
826 sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg);
827 system(str);
828 printf("Facsimile sent.\n");
829 } else
830 printf("Facsimile canceled.\n");
831
832 if (remove(tempMesg)) {
833 printf("Ouch, could not remove temporary file.\n");
834 syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n");
835 return 0;
836 }
837
838 return 0;
839 }
0 #include <utmp.h>
1 #include "defines.h"
2
3 extern char callsign[20];
4 extern char username[20];
5 extern char fullname[31];
6 extern char forward[79];
7
8 extern char *homedir; /* User's home directory */
9 extern char *fwdfile; /* User's .forward file (~/.forward) */
10 extern char *sigfile; /* User's .signature file (~/.signature) */
11 extern char *maildir; /* User's mail directory (~/mail) */
12 extern char *mailbox; /* System mailbox (/var/spool/mail/user) */
13 extern char *userbox; /* User's mailbox (~/mbox) */
14 extern char *mailconf; /* User's own axmail configuration */
15
16 extern int local; /* Running with user privileges? */
17
18 extern char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */
19 extern char *tempRcpt; /* Temporary files: return receipt */
20 extern char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */
21 extern char *tempEdit;
22 extern char *tempMesg;
23
24 extern char *faxgate; /* Email of your E-Fax Gateway */
25 extern char *hostname;
26 extern char *sysopmail;
27 extern char *def_shell; /* Default settings for autoaccounts */
28 extern char *def_homedir;
29
30 extern int mail_allowed, identification, autocreate, login_allowed;
31 extern int first_uid, last_uid;
32 extern gid_t user_gid;
33 extern char mboxname[PATHSIZE];
34 extern long IdleTimeout;
35
36 struct cmd {
37 char *name;
38 int (*function) (int argc, char **argv);
39 };
40
41 extern struct cmd Mailcmds[];
42
43 extern void tinit(void);
44 extern int read_config(void);
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axmail 2.11
27 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
28 - Figured out how to add ClamSMTP to the mail system's MTA. Details
29 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
30 This will scan for viri both IN and OUT bound mails! Very handy!
31 - Added a define routine in config.h now. You must #define or #undef
32 CLAMSMTP based on whether or not you're running clamsmtp and have
33 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
34 create a symlink to it and you'll be fine.
35 - added the fact when #defined where mails are tagged with the fact that
36 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
37 - upped the version to 2.11 in defines.h
38 - added notes in INSTALL in regards to the new #define in config.h
39 axmail 2.10
40 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
41 - added online help for the "Delivery Receipt" command. This keeps
42 it in line with all the other online helps.
43 - modified defines.h with this version number and also increased the
44 year that I'm still working on modifications to the project.
45 axmail 2.9
46 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
47 - Removed asking for password upon new user login, instead added a new
48 field to axmail.conf for "SysopMail". Now the sysop has to put in their
49 email address as to inform the end user to request their desired password
50 into the system, especially if the sysop is running pop/imap features on
51 their system. This will prevent users from entering in plain text passwords
52 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
53 a major security fix for axMail-FAX.
54 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
55 another program changed the user's mail spool file the warning displays
56 clearer.
57 - changed version number to 2.9 in defines.h and changed the end year of
58 maintenance from 2017 to 2018.
59
60 axmail 2.8
61 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
62 Changes:
63 - added SPers as a command per the suggestion of VE1JOT. This was done in
64 command.c and was actually quite simple to impliment. The logic behind
65 it is to match the mail send command sets with those of standard PBBS
66 messaging commands.
67 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
68 urged that flags, cc, and bcc options be supressed to make it more user
69 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
70 do have compassion for those on HF. Steve gave me a different idea than
71 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
72 and command.c. If one needs a read receipt or to send cc/bcc copies of
73 their message then S still is an option.
74 - added a "spers" .hlp file to the archive.
75 - changed defines.h to reflect version 2.8.
76 - updated welcome.txt to be more generic rather than be version specific.
77 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
78 mail. This allows for a duplicate of the message to be sent to the second
79 person one wishes to copy on the mail.
80 - edited this file.
81 - while I was at it, I decided to add a "blind carbon copy" feature.
82 This will send a copy of a message to the user specified HOWEVER,
83 they will NOT be listed in the recipient listings. For those using
84 raw terminals, it's possible to NOT enter a 'cc' but still enter a
85 'bcc' address.
86 - edited help files: send.hlp and spersonal.hlp to help guide users
87 on how to best send mail.
88 - created a bypass method so that if users did not wish to use cc or bcc
89 mail, they can bypass them instead of being prompted for them - suggested
90 by VE1JOT.
91 - added online help for send/sp|cc|bcc mail.
92 - added a new signature file function to the system in both command.c and in
93 mailcmd.c. If no signature file exists, it will instruct the user on this
94 fact and also inform them how to make one using the new SIgnature command.
95 Note: If no ~/.signature file exists mail will still be sent, just without
96 a 1 line siguature (max: 79 characters).
97 - bullet proofed both the autoforward and signature file routines in command.c
98 by insuring that a null string not only halts execution of both but also
99 removes both ~/.forward and ~/.signature files respectively.
100 - cleaned up the send signature a bit and added my little spam ad even if
101 there is no signature file present. This was done in mailcmd.c.
102 - added a string in the signature prompt which informs users how to clear
103 their signature if they desire such. This was done in utils.c
104 - Added special critical instructions to INSTALL. I didn't know if I had
105 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
106 - Fixed a bug that when the mailbox file(s) weren't found for the system
107 MTA (aka: postfix) axMail would segfault. Now not only does it not
108 segfault but also instructs the user to inform the sysop of this error.
109 This bug existed since version 0.0.1. I've been wanting to do something
110 about this for IONs but didn't get to it until now. This was done in quit.c
111 - Fixed a couple of typos in README. I have a very difficult keyboard!
112 - Per the suggestion of G4APL (who gives us many great ideas - and why do
113 I refer to myself in plural? I need a DIET!) I did two things:
114 1 - when listing mail there's no message date stamp within the listing.
115 added in mailcmd.c
116 2 - reordered the mail listing fields where I felt they'd make the most
117 sense. Message subject, then message date, then message size are
118 the last 3 fields listed. They should also be kept in a column
119 justified manner of sorts.
120 3 - added a (St)atus header so the user has a better definition of
121 the status of a specific message.
122
123 axmail 2.7
124 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
125 Changes:
126 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
127 the user entered a parameter such as a message number for example,
128 it wouldn't properly function. This has been fixed. Thanks Van!
129 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
130 - I know in the past I had a 'cc' command for sending mail, and it's
131 been suck in my craw to readd it since.
132
133 axmail 2.6
134 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
135 Changes:
136 - changed version number in defines.h
137 - fixed error message when a pop client has deleted mail from the
138 main mail spool file.
139 - removed excessive receipt warning spotted by a gent who identifies
140 himself as rigor. This was in mailcmd.c in do_readmsg()
141 - while looking at the end of that routine, it just gave me an itch that
142 said "if you can look for a warning about a requested receipt, then
143 numbnutz you can offer the reader a chance to just generate a receipt
144 without having to do "SR" as previously stated at the end of the mail.
145 So, with that said and to get feeling back in my genitals, I wrote a
146 routine that asks the reader if they wish to send a receipt, and it
147 also echos where it's destined and confirmation it was sent.
148 - added an "--- end of message #* ---" tag at the end of mail when it
149 as finished displaying. This was done in mailcmd.c
150 - fixed an existing bug in the message routines where for each message
151 it wasn't resetting the receipt pointer! This bug existed since I
152 introduced the receipt "finder" in the messages. I'm shocked that
153 it wasn't reported to me by someone earlier. Now *only* if a message
154 has requested a receipt will it show that a receipt has been asked
155 for... whew!
156 - So many missing online help files! Again I'm surprised no one brought
157 this to my attention. How did we get along with them? "Oh my!" - Sulu
158 - Updated this README file.
159
160 axmail v2.5.1
161 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
162 Changes:
163 - added axmail.8 man page as per spec of Debian downstream.
164 - modified Makefile to include axmail.8 manpage installation for both
165 new and upgrade options.
166 - modified defines.h and this document to reflect maintenance release.
167
168 axmail v2.5
169 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
170 Changes:
171 - added new delivery receipt function to the send routine. This
172 compliments the read receipt function in the event of high
173 priority mail. Typically the read receipt is an option generated
174 by the recipient who may not decide to generate one. At least this
175 modification ensures with an ESMTP delivery that the sender using
176 axMail will get a reciept from "MAILER-DAEMON" which will verify
177 the status of delivered mail. This change was done in mailcmd.c
178 and is designed with the sendmail binary included with postfix.
179 - updated this README file.
180 - updated version number in defines.h
181
182 axmail v2.4
183 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
184 Changes:
185 - cleaned up mbox.c where I had originally placed the receipt checker
186 routine in. This caused loops within the buffer that displayed the
187 message. The true routine lives in mailcmd.c
188 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
189 downstream compiles to make packages.
190 - changed version in defines.h
191 - major change in command.c, added a new Autofwd command to allow users to
192 auto-forward mail from a remote system to their "home" axMail-FAX base
193 system. Could also be used to forward mail to their internet accounts.
194 - added autofwd.hlp file.
195 - alphabetized the commandset listing, removed redundantly spelled commands.
196 - reworked Makefile and added an "upgrade" option so new files ONLY are
197 deployed after make. Execute using: "make upgrade"
198 - updated this file.
199
200 axmail v2.3.1
201 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
202 Changes:
203 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
204 message, a bell and a warning sign is generated after the message has been
205 read by the user with instructions to use SR to generate a receipt. This
206 was a difficult routine for me to think of considering the various race
207 conditions that can be expected and met.
208 - updated welcome.txt with version upgrade and new feature list.
209 - updated README.
210
211 axmail v2.3
212 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
213 Changes:
214 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
215 This defaults to NO but when flagged to YES, a request will be sent to the
216 remote client's agent. If the agent supports such, they will be prompted
217 whether or not to honor your receipt request. This is history as NO AGENT
218 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
219 receipt is similar to how HylaFax generates confirmation of transmission
220 receipt mails to your mailbox. Currently mail read in axMail will NOT
221 generate a receipt back. I may work on this later, but for now it doesn't
222 exist.
223 * My thoughts of the receipt function is negative. The fact that I may be
224 sending notification that I'm in my email client to a remote destination
225 IMHO is such that a webcam may as well be turned on and watch me do email,
226 and send the stream to "Big Brother" and I don't mean the television show.
227 </rant>
228 - Updated defines.h with the new version number.
229 - Updated welcome.txt so the new version number is displayed.
230
231 axmail v2.2
232 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
233 Changes:
234 - Made some maintenance changes, but forgot to log them in here.
235 axmail v2.1.1
236 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
237 Changes:
238 - Makefile
239 Code provided by Bob Tenty VE3TOK to make it more compatable
240 with newer GCC compiler requirements.
241 - utils.c
242 Code provided by Bob Tenty VE3TOK to fix a warning produced when
243 compiling.
244 - defines.h
245 Changed version number to reflect the changes incorporated by
246 Bob Tenty VE3TOK and committed to the subversion repository.
247
248 axmail v2.1
249 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
250 Changes:
251 - axmail.c
252 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
253 the system privilege matching.
254 - global
255 axMail is now under review for considerations as standard packaging in
256 RedHat's fedora project. It appears it's going to be added as a package.
257
258 axmail v2.0
259 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
260 Changes:
261 - defines.h
262 Updated version number to reflect version release 2.0. Version 1.0.5
263 was simply a maintenance test package to try and reincorporate what
264 I had done up to version 1.0.6 which I believe was one of my last
265 releases up to 2009. Since I've done all that I can recall at this
266 point and time, I decided to match URONode's release numerics with
267 a 2.0 release version.
268
269 axmail v1.0.5
270 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
271 Changes:
272 - defines.h
273 Updated email listings to reflect the most current ones I could find
274 including my own. Also added 2013 to the years worked on axMail by
275 me.
276 - quit.c
277 Forced ALL mail, read or otherwise when user quits to save to the
278 user's system mailbox. This is for reverse compatability with those
279 who may also run a web-based email service on the internet such as
280 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
281 any read mail (and all accompanying mail in that session) to the
282 axmail ~/mbox file. We don't want this for the specific reason of
283 "reverse email client" compatability.
284
285 axmail v1.0.4
286 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
287 Changes:
288 - setpwnam.c
289 Changed the way SIGPIPE was handled. Instead of being ignored, it will
290 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
291 a shell prompt, or a node frontend. I've been noticing especially on
292 some timeouts that temp files don't flush as they should and the
293 user's directory can start to fill up.
294
295 axMail v1.0.3
296 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
297 Changes:
298 - mailcmd.c
299 Reset the way I wanted to handle the user input routine for sending faxes.
300 Commented out some more unneeded/unused code in the do_fax routine... will
301 clean it up in next release or so.
302 - mailcmd.c
303 cleaned up a bug I introduced in the never released 1.0.2 where the
304 X-Mailer was duping itself after each line of the body of a message.
305 - sfax.hlp
306 Reworded the SFax help file to help show some examples of how to format
307 the header.
308
309 axMail v1.0.2
310 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
311 Changes:
312 - mailcmd.c
313 Cleaned up some of the code in SFax. Also made some cosmetic changes.
314
315 axMail v1.0.1
316 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
317 Changes:
318 - mailcmd.c
319 Added a new routine to allow users to send faxes. This is defined by the
320 command "SF" for Send Fax. The routine was taken from the "S"end function
321 however since it's a one-way transmission, there is no reply available
322 nor is there an option for users to fax to any fax service as some I know
323 are pay services.
324 - config.h
325 added definitions for faxgate in axmail.conf
326 - config.c
327 added routine to allow for faxgate as a variable and be called from
328 mailcmd.c
329 - defines.h
330 version upgraded from v1.0.0 (unreleased - test version) to
331 v1.0.1
332 - etc/axmail.conf
333 Added new line called "FaxGate" with an example of how to properly
334 configure this line.
335 - etc/help/sfax.hlp
336 Added new file "sfax.hlp" which is an online help file for the SFax
337 command.
338
339 axMail v0.0.9
340 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
341 Changes:
342 - mailcmd.c
343 Added a new routine that prompts the sender whether or not the message
344 is of an emergency/high priority mail message. If it's emergency message
345 then the headers are appended with an X-code flagged in such a manner
346 that Eudora and Outlook will display the received mail with a red flag
347 of sorts. The idea of such came to me in thinking of "what can I do
348 to help improve means of emergency communications using TCP/IP, Linux,
349 and packet radio?" Having the ability to "red flag" an SMTP message
350 I don't believe has yet to be available in any packet messaging
351 system... axMail I hope is the first.
352
353 If a user just hits enter, or selects "no" then the mail message
354 is sent under normal send routines.
355
356 found a minor bug in my routine where if an end user answered
357 "yes" in wanting to send an emergency/high priority message the system
358 ignored the request and sent it as 'normal' delivery. Made a minor
359 change to bullet-proof the responce.
360
361 Added online help text if user is unsure about sending a message
362 flagged urgent or normal. This text is available when the user is
363 prompted for priority selection by hitting "?" at the prompt.
364 - defines.h
365 Version updated from v0.0.8 to v0.0.9
366
367 axMail v0.0.8
368 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
369
370 Changes:
371 - mailcmd.c
372 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
373 it's version number in the X-Mailer: string.
374 - mailcmd.c
375 Added an X-Origin: string to show those peeking at mail headers
376 just how the message was possibly sent... by AMATEUR RADIO!
377 - axmail.conf
378 Added config option in "AllowMail" for axhome, a rewrite of code
379 submitted by Stefano IW3IJQ. While I stripped out home directory
380 structures similar to that of qmail or axspawn, Stefano convinced
381 me that it may be easier to manage home directories for axMail users
382 who don't have shell access to branch out within a preset directory.
383 - defines.h
384 Updated version number from 0.0.7 to 0.0.8
385 - axmail.c and config.c
386 Rewrote and incorporated code to allow for the routines to use
387 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
388 While I was at it, I rewrote and shortened the error text pushed
389 to a user who doesn't have permission to use such a directory.
390 * Note: When I write error texts and menus, I try to write them for
391 users on a multi-hop 1200 baud path thus the shorter the better as
392 long as context isn't lost and for long distance hops where full
393 paclen may cause retries (worse yet timeouts!)
394
395 axMail v0.0.7
396
397 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
398
399 Changes:
400 - cosmetics
401 My usual "I like seeing this this way" type cosmetics... too many
402 to mention!
403 - adduser.c
404 changed the hard coding of user 'home' directories so that instead
405 of them going into a period delimited sort, just dump em all into
406 /home/<user> which seems to be "the norm" on most systems I've had
407 to assist with.
408 - adduser.c
409 fixed a bug where creating a user was actually causing the program to
410 segfault upon exit the first time a user went into the mailbox! The
411 node frontends hid this segfault as the program still flushed itself
412 from ram but I spotted it when running it at a command prompt. The
413 segfault came when axMail attempted to write mail back to the user's
414 system mailbox and it didn't exist. How I fixed this is listed next.
415 This may just be a new bug that appeared with the upgrading of libs,
416 this I'm unsure of and since I have no desire to go backwards I have
417 decided to actually make a minor routine...
418 - welcome.txt
419 New users are now sent a "welcome" message that the sysop can easily
420 customize to their desires. It's located at /etc/ax25/welcome.txt.
421 I figured that since axMail was segfaulting because such a file did
422 not exist, I might as well make use of this need by having the program
423 send the user a greeting.
424 - defines.h
425 Changed paths to be more in line with the more modern type configs
426 as a default. Paths can still be defined by the sysop prior to
427 compiling axMail.
428 - Makefile
429 I changed the default of make install to include all of the subroutines
430 within the Makefile yet leaving such things as "make installbin"
431 available as runtime options if just a binary refresh creation is
432 desired.
433 - other
434 I'm sure I missed a note or two *shrug*
435
436 axMail v0.0.6
437
438 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
439 I at one time had but lost and can't seem to find it. My (n1uro)
440 changes may have alread been incorporated.
441
442 axMail v0.0.5
443
444 True mailbox functionalities created by Marius Petrescu.
445 Added Mailbox save routines (compatible with the command line
446 mail agent, including ~/mbox file)
447
448 axMail v0.0.4
449
450 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
451
452 This program is free software; you can redistribute it and/or modify
453 it under the terms of the GNU General Public License as published by
454 the Free Software Foundation; either version 2 of the License, or
455 (at your option) any later version.
456
457 This program is distributed in the hope that it will be useful,
458 but WITHOUT ANY WARRANTY; without even the implied warranty of
459 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
460 GNU General Public License for more details.
461
462 You should have received a copy of the GNU General Public License
463 along with this program; if not, write to the Free Software
464 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
465
466
467 Don't give this one to anyone yet... it is NOT ready for distribution!
468
469 This is a simple mail user agent intended to provide the
470 mail functions in xNOS in a Linux ax.25 environment. If required,
471 it creates a normal user account for each new user (code mostly taken
472 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
473 on the system. axMail uses sendmail (or similar) to deliver mail, and
474 reads mail from each user's system mailbox (/var/spool/mail/username).
475 It does not provide any means of transferring mail between hosts.
476
477 axMail provides a simple, low-overhead user interface, much similar
478 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
479 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
480
481 axMail is intended to be called from node. It takes one command
482 line argument of the user's callsign (with or without SSID). It must
483 be run as root, but it setuid()'s itself to the respective user's
484 privileges as soon as possible. It might run from ax25d as well.
485 It can also be executed from a shell with user privileges.
486
487 Some code (command parser, configuration file stuff) and the internal
488 architecture was taken from the LinuxNode frontend by Tomi Manninen
489 (OH2BNS). Thanks!
490
491 INSTALLATION:
492
493 See the file: INSTALL
494
495 TODO:
496 Suggestions?
497
498 --
499 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
500 ftp://ftp.n1uro.net/pub/hamradio/packet
0 all: axmail
1
2 MAN_DIR = /usr/local/share/man
3 CC = gcc
4 LD = gcc
5 CFLAGS = -O2 -Wstrict-prototypes -g -I../lib
6 LIBS = -lcrypt
7 MODULES = utils.o config.o adduser.o command.o mailcmd.o mbox.o head.o lock.o axmail.o quit.o
8
9 .c.o:
10 $(CC) $(CFLAGS) -c $<
11
12 upgrade: installbin installhelp installman installconf
13
14 install: installbin installconf installhelp installman
15
16 installbin: all
17 install -m 0755 -s -o root -g root axmail /usr/local/sbin
18
19 installconf:
20 install -m 755 -o root -g root -d /usr/local/etc/ax25
21 install -b -m 644 -o root -g root etc/axmail.conf /usr/local/etc/ax25
22 install -m 644 -o root -g root etc/welcome.txt /usr/local/etc/ax25
23
24 installhelp:
25 install -m 755 -o root -g root -d /usr/local/var/ax25/axmail/help
26 install -m 644 -o root -g root etc/help/*.hlp /usr/local/var/ax25/axmail/help
27
28 installman:
29 install -m 644 -p man/axmail.8 $(MAN_DIR)/man8
30 install -m 644 -p man/axmail.conf.5 $(MAN_DIR)/man5
31 back:
32 rm -f ../mail.tar.gz
33 tar cvf ../mail.tar *
34 gzip ../mail.tar
35
36 clean:
37 rm -f axmail *.o *~ *.bak core etc/*~ etc/help/*~
38
39 distclean: clean
40 rm -f axmail
41
42 axmail: $(MODULES)
43 $(LD) -o axmail $(MODULES) $(LIBS) $(LDFLAGS)
44
45 utils.o: utils.h utils.c mbox.h
46 config.o: config.h config.c defines.h axmail.h utils.h
47 adduser.o: adduser.h adduser.c utils.h config.h defines.h
48 command.o: command.h command.c config.h mailcmd.h mbox.h utils.h quit.h
49 mailcmd.o: mailcmd.h mailcmd.c defines.h utils.h mbox.h config.h
50 mbox.o: mbox.h mbox.c utils.h defines.h config.h head.h
51 head.o: head.h head.c defines.h
52 utils.o: utils.h utils.c
53 lock.o: lock.h lock.c utils.h
54 quit.o: quit.h quit.c config.h lock.h
55 axmail.o: axmail.h axmail.c config.h adduser.h utils.h quit.h mbox.h
0 # /etc/ax25/axmail.conf - axMail configuration file
1 #
2 # Idle timeout (seconds).
3 IdleTimeout 900
4
5 # Local hostname.
6 HostName <your>.ampr.org
7
8 # Sysop's email address
9 SysopMail <your@email.address>
10
11 # Who (of those who are listed in /etc/passwd) are allowed to use axmail
12 # all : All users who have an account (or have just created one)
13 # nologin : Those who have "+" as password (the axmail-only accounts)
14 # passwd : Those who have a password set (NOT those with "+" as password)
15 # axhome : Those who put all ham home dirs within one branch
16 AllowMail all
17
18 # Do we ask for a password or rely on the callsign
19 # none : Trust the callsign given on command line
20 # passwd : Ask for a plaintext password (brrrr...)
21 # TODO: MDn authenthication !
22 Identification none
23
24 #
25 # ------ Parameters for automatically created user accounts
26 #
27
28 # Allow automatic creation of user accounts
29 AutoCreate yes
30
31 # Automatically created login accounts can login (through telnet, etc)
32 # yes : User is prompted for password, when the account is created
33 # no : Password is set to "+" (cannot login) (preferred, axmail-only
34 # account)
35 # crazy : Password is left empty (can login without password)
36 LoginAllowed no
37
38 # Group name or id for autoaccount
39 AutoGroup ax25
40
41 # First user id to use for automatically created accounts
42 First_uid 2000
43
44 # Maximum user id
45 Last_uid 2999
46
47 # Where to add the home directories for the new users
48 HomeDir /home
49
50 # User shell
51 Shell /bin/false
52
53 # Fax Gateway - must be defined without quotes
54 FaxGate "your@faxgate.com"
0 USAGE
1 status
2
3 DESCRIPTION
4 The STatus command shows you a very shortened list by only
5 informing you just how many total messages you have by a
6 grand total number. Ex:
7 status
8 Messages: 4
9
0 /* command.c - Commands which have nothing to do with mail... */
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <unistd.h>
6 #include <time.h>
7
8 #include "defines.h"
9 #include "command.h"
10 #include "config.h"
11 #include "mailcmd.h"
12 #include "mbox.h"
13 #include "utils.h"
14 #include "quit.h"
15
16 struct cmd Mailcmds[] = {
17 { "?", do_help },
18 { "Autofwd", do_forward },
19 { "Bye", do_exit },
20 { "Cancel", do_quit },
21 { "Delete", do_kill },
22 { "Exit", do_exit },
23 { "Help", do_help },
24 { "Info", do_help },
25 { "Kill", do_kill },
26 { "List", do_list },
27 { "Name", do_name },
28 { "Quit", do_exit },
29 { "Read", do_read },
30 { "Send", do_send },
31 { "SFax", do_fax },
32 { "SIg", do_signature },
33 { "SPers", do_psend },
34 { "SReply", do_send },
35 { "STatus", do_status },
36 { "Unkill", do_unkill },
37 { "Verbose", do_read },
38 { NULL, NULL }
39 };
40
41 int do_status(int argc, char **argv)
42 {
43 printf("Messages: %i\n", messages);
44 return 0;
45
46 }
47
48 int do_name(int argc, char **argv)
49 {
50 char name[32];
51
52 getname(name);
53
54 if (strlen(name) == 0)
55 printf("Name not changed. ");
56 else { /* Okay, save it */
57 strcpy(fullname, name);
58 }
59
60 printf("You're now known as %s.\n", fullname);
61
62 return 0;
63 }
64
65 /* int do_forward(int argc, char **argv) */
66 int do_forward(int argc, char **argv)
67 {
68 char *email;
69 char *fwdfile;
70 char fwd[79];
71 char forward[79];
72
73 getaddy(fwd);
74 FILE *fptr;
75
76 sprintf(forward, "%s/.forward", homedir);
77 fwdfile = strdup(forward);
78 fptr = fopen(fwdfile, "w+");
79 fprintf(fptr, "%s", fwd);
80 while (! *fwd) {
81 fclose(fptr);
82 remove(fwdfile);
83 printf("Forwarding halted, forward file removed.\n");
84 return 0;
85 }
86 printf("You're mail will be sent to:\n%s\nThank you.\n", fwd);
87 fclose(fptr);
88 return 0;
89 }
90
91 /* int do_signature(int argc, char **argv) */
92 int do_signature(int argc, char **argv)
93 {
94 char *sigfile;
95 char sig[79];
96 char signature[79];
97
98 getsig(sig);
99 FILE *fptr;
100
101 sprintf(signature, "%s/.signature", homedir);
102 sigfile = strdup(signature);
103 fptr = fopen(sigfile, "w+");
104 fprintf(fptr, "%s\n", sig);
105 while (! *sig) {
106 fclose(fptr);
107 remove(sigfile);
108 printf("Signature file deleted.\n");
109 return 0;
110 }
111 printf("You're signature is set to:\n%s\nThank you.\n", sig);
112 fclose(fptr);
113 return 0;
114 }
115
116 int do_help(int argc, char **argv)
117 {
118 FILE *fp;
119 char fname[80], line[256];
120 struct cmd *cmdp;
121 int i = 0;
122
123 if (*argv[0] == '?') { /* "?" */
124 printf("Commands:\n");
125 for (cmdp = Mailcmds; cmdp->name != NULL; cmdp++) {
126 printf("%s%s", i ? ", " : "", cmdp->name);
127 if (++i == 10) {
128 printf("\n");
129 i = 0;
130 }
131 }
132 if (i) printf("\n");
133 return 0;
134 }
135 strcpy(fname, DATA_AXMAIL_HELP_DIR);
136 if (*argv[0] == 'i') { /* "info" */
137 strcat(fname, "info.hlp");
138 printf("%s - %s\n", VERSION, COPYRIGHT);
139 printf("%s", LICENSE);
140 } else if (argc == 1) { /* "help" */
141 strcat(fname, "help.hlp");
142 } else { /* "help <cmd>" */
143 if (strchr(argv[1], '/') == NULL) {
144 strlwr(argv[1]);
145 strcat(fname, argv[1]);
146 strcat(fname, ".hlp");
147 }
148 }
149 if ((fp = fopen(fname, "r")) == NULL) {
150 if (*argv[0] != 'i')
151 printf("No help for command %s.\n", argv[1] ? argv[1] : "help");
152 return 0;
153 }
154 if (*argv[0] != 'i')
155 printf("Help for command %s:\n", argv[1] ? argv[1] : "help");
156 while (fgets(line, 256, fp) != NULL) {
157 printf("%s", line);
158 }
159 fclose(fp);
160 return 0;
161 }
162
163 int do_quit(int argc, char **argv)
164 {
165 quit(0, 0);
166 return 0;
167 }
168
169 int do_exit(int argc, char **argv)
170 {
171 quit(1, 0);
172 return 0;
173 }
174
0
1 extern int lock_fd(int fd);
2 extern int unlock_fd(int fd);
0
1 /* lock.c - file locking services */
2
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <sys/file.h>
8
9 #include "lock.h"
10 #include "utils.h"
11
12 /* Lock a file descriptor. */
13
14 int lock_fd(int fd)
15 {
16 if (flock(fd, LOCK_EX)) {
17 syserr("Can't lock fd\n");
18 return -1;
19 }
20
21 return 0;
22 }
23
24 /* Unlock a file descriptor. */
25
26 int unlock_fd(int fd)
27 {
28 if (flock(fd, LOCK_UN)) {
29 syserr("Can't unlockfd\n");
30 return -1;
31 }
32
33 return 0;
34 }
0
1 /* utils.c - common utilities */
2
3 #include <stdio.h>
4 #include <ctype.h>
5 #include <stdarg.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <syslog.h>
9 #include <errno.h>
10
11 #include "utils.h"
12 #include "mbox.h"
13 #include "config.h"
14
15 //extern int sys_nerr;
16
17 /* Send the prompt */
18
19 void prompt(void)
20 {
21 printf("%s@%s\nCurrent message %i of %i\n=> ", callsign, hostname, current, messages);
22 }
23
24 /* Prompt for email forwarding */
25 void getaddy(char *forward)
26 {
27 char email[79];
28 getstr(email, 79, "What email address do you want to autoforward mail to? This must be a full\nvalid email address. Example: n1uro@n1uro.com or just hit ENTER to clear.\n");
29 strcpy(forward, email);
30 }
31
32 /* Prompt for signature */
33 void getsig(char *signature)
34 {
35 char email[79];
36 getstr(email, 79, "Hit enter to remove or type your signature here:\n");
37 strcpy(signature, email);
38 }
39
40
41 /* Prompt for name */
42
43 void getname(char *uname)
44 {
45 char nam[81];
46
47 rename:
48 getstr(nam, 80, "Enter your name (? for help): ");
49
50 if (!strcmp(nam, "?")) {
51 printf("The name entered will be used in the From: header of the messages you send.\n");
52 printf("It will also be shown in finger queries and a number of other places.\n");
53 printf("It is usually set to your full name, but you may also use a nickname\n");
54 printf("your friends know.\n");
55 goto rename;
56 }
57
58 if (strlen(nam) > 30) {
59 printf("The length of the name is limited to 30 characters.\n");
60 goto rename;
61 }
62
63 if (anyof(nam, "=<>()|:;!\\\",")) {
64 printf("Characters = < > ( ) | : ; ! \\ \" , are not allowed.\n");
65 goto rename;
66 }
67
68 if (anycntrls(nam)) {
69 printf("Control characters are not allowed.\n");
70 goto rename;
71 }
72
73 strcpy(uname, nam);
74 }
75
76 /* Get a string from the user, with maximum length limit */
77
78 void getstr(char *str, int len, char *prompt)
79 {
80 char *p;
81
82 printf("%s", prompt);
83 fflush(stdout);
84 fgets(str, len, stdin);
85
86 /* Strip CR */
87 p = strchr(str, '\n');
88 if (p != NULL)
89 strcpy(p, "");
90
91 }
92
93 /* Convert a string to upper case */
94
95 char *strupr(char *s)
96 {
97 char *p;
98
99 if (s == NULL)
100 return NULL;
101
102 for (p = s; *p != '\0'; p++)
103 *p = toupper(*p);
104
105 return s;
106 }
107
108 /* Convert a string to lower case */
109
110 char *strlwr(char *s)
111 {
112 char *p;
113
114 if (s == NULL)
115 return NULL;
116
117 for (p = s; *p != '\0'; p++)
118 *p = tolower(*p);
119
120 return s;
121 }
122
123 /* Check if any of the characters in the two strings match. */
124
125 int anyof(char *s1, char *s2)
126 {
127 while (*s1)
128 if (index(s2, *s1++))
129 return 1;
130 return 0;
131 }
132
133 /* Check if there are any control characters in there. */
134
135 int anycntrls(char *s1)
136 {
137 while (*s1)
138 if (iscntrl(*s1++))
139 return 1;
140 return 0;
141 }
142
143 /* Crash, log the reason */
144
145 void panic(const char *fmt, ...)
146 {
147 va_list args;
148
149 va_start(args, fmt);
150 vprintf(fmt, args);
151 putchar('\n');
152 syslog(LOG_NOTICE, fmt, args);
153 va_end(args);
154
155 exit(1);
156 }
157
158 /* Report an error returned from a system call. */
159
160
161 void syserr(const char *fmt, ...)
162 {
163 int e = errno;
164 va_list args;
165
166 va_start(args, fmt);
167 vprintf(fmt, args);
168 va_end(args);
169
170 /* routine changed by VE3TOK */
171 printf("Error number: %d\n", e);
172 perror("The following error occured: ");
173
174 }
175
0 USAGE
1 list
2
3 DESCRIPTION
4 Use this command to list your mail messages. Each message will
5 be flagged as N(ew), U(nread), or blank for read. Use the "read"
6 command to read each message.
0
1 /*
2 * Structure used to return a break down of a head
3 * line (hats off to Bill Joy!)
4 */
5
6 struct headline {
7 char *l_from; /* The name of the sender */
8 char *l_tty; /* His tty string (if any) */
9 char *l_date; /* The entire date string */
10 };
11
12 /* in head.c */
13 extern char *nextword(char *wp, char *wbuf);
14 extern char *copyin(char *src, char **space);
15 extern void parse(char line[], struct headline *hl, char pbuf[]);
16 extern int ishead(char linebuf[]);
17 extern int isdate(char date[]);
18
0 USAGE
1 SI
2
3 DESCRIPTION
4
5 This creates a signature file which would get appended to your
6 outgoing mail so you don't have to keep typing your closings
7 when you send mail. If you don't have a signature file it will
8 inform you of such but it will not prevent mail from being sent.
9 This is limited to just 1 line (79 characters).
0 /* setpwnam.c edit an entry in a password database. */
1
2 /* because I use getpwent(), putpwent(), etc... */
3 #define _SVID_SOURCE
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <signal.h>
13 #include <sys/resource.h>
14 #ifdef BSD43
15 #include <sys/file.h>
16 #endif
17 #include <paths.h>
18
19 #include "setpwnam.h"
20
21 extern int errno;
22
23 typedef int boolean;
24 #define false 0
25 #define true 1
26
27 #define PASSWD_FILE _PATH_PASSWD
28 #define PTMP_FILE _PATH_PTMP
29 #define PTMPTMP_FILE _PATH_PTMPTMP
30
31 static int copy_pwd (struct passwd *src, struct passwd *dest);
32 static char *xstrdup (char *str);
33 static void pw_init(void);
34
35 /*
36 * setpwnam () --
37 * takes a struct passwd in which every field is filled in and valid.
38 * If the given username exists in the passwd file, his entry is
39 * replaced with the given entry.
40 */
41 int setpwnam (struct passwd *pwd)
42 {
43 FILE *fp;
44 int x, save_errno, fd, ret;
45 struct passwd *entry;
46 boolean found;
47 struct passwd spwd;
48 int oldumask;
49
50 /* getpwent() returns a pointer to a static buffer.
51 * "pwd" might have some from getpwent(), so we have to copy it to
52 * some other buffer before calling getpwent().
53 */
54 if (copy_pwd (pwd, &spwd) < 0)
55 return (-1);
56
57 oldumask = umask(0); /* Create with exact permissions */
58 pw_init();
59
60 /* sanity check */
61 for (x = 0; x < 3; x++) {
62 if (x > 0) sleep (1);
63 fd = open (PTMPTMP_FILE, O_WRONLY|O_CREAT, 0644);
64 if(fd == -1) {
65 perror(PTMPTMP_FILE);
66 umask(oldumask);
67 return (-1);
68 }
69 ret = link(PTMPTMP_FILE, PTMP_FILE);
70 unlink(PTMPTMP_FILE);
71 if(ret == -1)
72 close(fd);
73 else
74 break;
75 }
76
77 umask(oldumask);
78 if (ret == -1) return (-1);
79
80 /* ptmp should be owned by root.root or root.wheel */
81 if (chown (PTMP_FILE, (uid_t) 0, (gid_t) 0) < 0)
82 perror ("chown");
83
84 /* open ptmp for writing and passwd for reading */
85 fp = fdopen (fd, "w");
86 if (! fp) goto fail;
87
88 setpwent ();
89
90 /* parse the passwd file */
91 found = false;
92 while ((entry = getpwent ()) != NULL) {
93 if (! strcmp (spwd.pw_name, entry->pw_name)) {
94 entry = &spwd;
95 found = true;
96 }
97 if (putpwent (entry, fp) < 0) goto fail;
98 }
99 if (fclose (fp) < 0) goto fail;
100 close (fd);
101 endpwent ();
102
103 if (! found) {
104 errno = ENOENT; /* give me something better */
105 goto fail;
106 }
107
108 /* we don't care if we can't remove the backup file */
109 unlink (PASSWD_FILE".OLD");
110 /* we don't care if we can't create the backup file */
111 link (PASSWD_FILE, PASSWD_FILE".OLD");
112 /* we DO care if we can't rename to the passwd file */
113 if (rename (PTMP_FILE, PASSWD_FILE) < 0)
114 goto fail;
115 /* finally: success */
116 return 0;
117
118 fail:
119 save_errno = errno;
120 if (fp) fclose (fp);
121 if (fd >= 0) close (fd);
122 endpwent ();
123 unlink (PTMP_FILE);
124 errno = save_errno;
125 return (-1);
126 }
127
128 #define memzero(ptr, size) memset((char *) ptr, 0, size)
129 static int failed;
130
131 static int copy_pwd (struct passwd *src, struct passwd *dest)
132 {
133 /* this routine destroys abstraction barriers. it's not portable
134 * across systems, or even across different versions of the C library
135 * on a given system. it's dangerous and evil and wrong and I dispise
136 * getpwent() for forcing me to write this.
137 */
138 failed = 0;
139 memzero (dest, sizeof (struct passwd));
140 dest->pw_name = xstrdup (src->pw_name);
141 dest->pw_passwd = xstrdup (src->pw_passwd);
142 dest->pw_uid = src->pw_uid;
143 dest->pw_gid = src->pw_gid;
144 dest->pw_gecos = xstrdup (src->pw_gecos);
145 dest->pw_dir = xstrdup (src->pw_dir);
146 dest->pw_shell = xstrdup (src->pw_shell);
147 return (failed);
148 }
149
150 static char *xstrdup (char *str)
151 {
152 char *dup;
153
154 if (! str)
155 return NULL;
156 dup = (char *) malloc (strlen (str) + 1);
157 if (! dup) {
158 failed = -1;
159 return NULL;
160 }
161 strcpy (dup, str);
162 return dup;
163 }
164
165 #ifdef NO_PUTPWENT
166
167 int putpwent (const struct passwd *p, FILE *stream)
168 {
169 if (p == NULL || stream == NULL) {
170 errno = EINVAL;
171 return (-1);
172 }
173 if (fprintf (stream, "%s:%s:%u:%u:%s:%s:%s\n",
174 p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
175 p->pw_gecos, p->pw_dir, p->pw_shell) < 0)
176 return (-1);
177 return(0);
178 }
179
180 #endif
181
182 static void
183 pw_init()
184 {
185 struct rlimit rlim;
186
187 /* Unlimited resource limits. */
188 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
189 (void)setrlimit(RLIMIT_CPU, &rlim);
190 (void)setrlimit(RLIMIT_FSIZE, &rlim);
191 (void)setrlimit(RLIMIT_STACK, &rlim);
192 (void)setrlimit(RLIMIT_DATA, &rlim);
193 (void)setrlimit(RLIMIT_RSS, &rlim);
194
195 /* Don't drop core (not really necessary, but GP's). */
196 rlim.rlim_cur = rlim.rlim_max = 0;
197 (void)setrlimit(RLIMIT_CORE, &rlim);
198
199 /* Turn off signals. */
200 (void)signal(SIGALRM, SIG_IGN);
201 (void)signal(SIGHUP, SIG_IGN);
202 (void)signal(SIGINT, SIG_IGN);
203 (void)signal(SIGPIPE, SIGQUIT);
204 (void)signal(SIGQUIT, SIG_IGN);
205 (void)signal(SIGTERM, SIG_IGN);
206 (void)signal(SIGTSTP, SIG_IGN);
207 (void)signal(SIGTTOU, SIG_IGN);
208
209 /* Create with exact permissions. */
210 (void)umask(0);
211 }
0
1 /* adduser.c - create an user account (yecch) */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <strings.h>
6 #include <pwd.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <sys/file.h>
10 #include <errno.h>
11 #include <crypt.h>
12 #include <string.h>
13
14 #include "adduser.h"
15 #include "utils.h"
16 #include "config.h"
17 #include "defines.h"
18
19 /* Ask for a new password, and keep it sane */
20
21 void get_passwd(char *newuser, char *passw)
22 {
23 printf("Please email %s with your callsign and desired password.\n", sysopmail);
24
25 char passi[12];
26
27 repass: /* Get password */
28 getstr(passi, 10, "Enter password for the new account (6-8 characters, ? for help): ");
29
30 if (!strcmp(passi, "?")) {
31 printf("Your password must be 6 to 8 characters long, and it may not be the same as\n");
32 printf("your login name (in this case, your callsign).\n");
33 goto repass;
34 }
35 if ((strlen(passi) > 8) || (strlen(passi) < 6)) {
36 printf("Password must be 6-8 characters long.\n");
37 goto repass;
38 }
39 if (!strcasecmp(passi, newuser)) {
40 printf("Password may not be your login name (callsign).\n");
41 goto repass;
42 }
43
44 /* Crypt password */
45 strcpy(passw, crypt(passi, "ax")); /* Okay, salt _should_ be random... */
46 }
47
48 /* add a new user to /etc/passwd and do some init */
49
50 int new_user(char *newuser)
51 {
52 struct passwd pw, *pwp;
53 uid_t uid;
54 FILE *fp;
55 char homedir[256], userdir[256];
56 char buf[4096];
57 char subdir[4];
58 char passw[20];
59 char str[LINESIZE + 1];
60 int cnt = 0;
61 unsigned char *p, *q;
62 struct stat fst;
63 int fd_a, fd_b, fd_l;
64
65 /* Build path for home directory */
66
67 strncpy(subdir, newuser, 3);
68 subdir[3] = '\0';
69 sprintf(homedir, "%s/%s", def_homedir, newuser);
70 strcpy(userdir, homedir);
71
72 getname(fullname);
73
74 if (strlen(fullname) == 0) {
75 printf("Okay, using your callsign as your name. You may change it later.\n");
76 strcpy(fullname, newuser);
77 }
78
79 /* Get password */
80
81 switch (login_allowed) {
82 case 0: strcpy(passw, "*");
83 break;
84 case 1: get_passwd(newuser, passw);
85 break;
86 case 2: strcpy(passw, ""); /* Yuck! */
87 break;
88 }
89
90 /* Lock */
91 fd_l = open(LOCK_AXMAIL_FILE, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
92 flock(fd_l, LOCK_EX);
93
94 retry:
95 /* Find first free UID */
96 cnt++;
97
98 for (uid = first_uid; uid < 65535; uid++)
99 {
100 pwp = getpwuid(uid);
101 if (pwp == NULL)
102 break;
103 }
104
105 if (uid >= 65535 || uid < first_uid)
106 return -1;
107
108 /* build directories for home */
109
110 p = homedir;
111
112 while (*p == '/') p++;
113
114 chdir("/");
115
116 while(p)
117 {
118 q = strchr(p, '/');
119 if (q)
120 {
121 *q = '\0';
122 q++;
123 while (*q == '/') q++;
124 if (*q == 0) q = NULL;
125 }
126
127 if (stat(p, &fst) < 0)
128 {
129 if (errno == ENOENT)
130 {
131 mkdir(p, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
132
133 if (q == NULL)
134 {
135 chown(p, uid, user_gid);
136 chmod(p, S_IRUSR|S_IWUSR|S_IXUSR);
137 }
138 }
139 else
140 return -1;
141 }
142
143 if (chdir(p) < 0)
144 return -1;
145 p = q;
146 }
147
148 /* Add the user now */
149
150 fp = fopen(PASSWDFILE, "a+");
151 if (fp == NULL)
152 return -1;
153
154 pw.pw_name = newuser;
155 pw.pw_passwd = passw;
156 pw.pw_uid = uid;
157 pw.pw_gid = user_gid;
158 pw.pw_gecos = fullname;
159 pw.pw_dir = userdir;
160 pw.pw_shell = def_shell;
161
162 if ((getpwuid(uid) != NULL) && (cnt <= 10)) goto retry; /* oops?! */
163
164 if ((putpwent(&pw, fp) < 0) || (cnt > 10))
165 return -1;
166
167 flock(fd_l, LOCK_UN);
168 fclose(fp);
169
170 /* Copy ax25.profile */
171
172 fd_a = open(CONF_AXMAIL_PROF_FILE, O_RDONLY);
173
174 if (fd_a > 0)
175 {
176 fd_b = open(USERPROFILE, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IXUSR);
177
178 if (fd_b < 0)
179 return -1;
180
181 while ( (cnt = read(fd_a, &buf, sizeof(buf))) > 0 )
182 write(fd_b, &buf, cnt);
183 close(fd_b);
184 close(fd_a);
185 chown(USERPROFILE, uid, user_gid);
186
187 }
188 /* Be nice and send the new user a welcome message :) */
189
190 sprintf(str, "%s -oem %s@%s < %s", BIN_AXMAIL_SENDMAIL, newuser, hostname, WELCOME);
191 system(str);
192 return 0;
193 }
194
0 /* axmail.c - The command parser and main function */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <unistd.h>
7 #include <signal.h>
8 #include <time.h>
9 #include <syslog.h>
10 #include <pwd.h>
11 #include <crypt.h>
12 #include <error.h>
13 #include <grp.h>
14
15 #include "config.h"
16 #include "axmail.h"
17 #include "utils.h"
18 #include "adduser.h"
19 #include "quit.h"
20 #include "mbox.h"
21
22 /* Parse c-style escapes (neat to have!) */
23
24 // int setgroups(void);
25
26 static char *parse_string(char *str)
27 {
28 char *cp = str;
29 unsigned long num;
30
31 while (*str != '\0' && *str != '\"') {
32 if (*str == '\\') {
33 str++;
34 switch (*str++) {
35 case 'n':
36 *cp++ = '\n';
37 break;
38 case 't':
39 *cp++ = '\t';
40 break;
41 case 'v':
42 *cp++ = '\v';
43 break;
44 case 'b':
45 *cp++ = '\b';
46 break;
47 case 'r':
48 *cp++ = '\r';
49 break;
50 case 'f':
51 *cp++ = '\f';
52 break;
53 case 'a':
54 *cp++ = '\007';
55 break;
56 case '\\':
57 *cp++ = '\\';
58 break;
59 case '\"':
60 *cp++ = '\"';
61 break;
62 case 'x':
63 num = strtoul(--str, &str, 16);
64 *cp++ = (char) num;
65 break;
66 case '0':
67 case '1':
68 case '2':
69 case '3':
70 case '4':
71 case '5':
72 case '6':
73 case '7':
74 num = strtoul(--str, &str, 8);
75 *cp++ = (char) num;
76 break;
77 case '\0':
78 return NULL;
79 default:
80 *cp++ = *(str - 1);
81 break;
82 };
83 } else {
84 *cp++ = *str++;
85 }
86 }
87 if (*str == '\"')
88 str++; /* skip final quote */
89 *cp = '\0'; /* terminate string */
90 return str;
91 }
92
93 /* Parse command line to argv, honoring quotes and such */
94
95 int parse_args(char *argv[],char *cmd)
96 {
97 int ct = 0;
98 int quoted;
99
100 while (ct < 31)
101 {
102 quoted = 0;
103 while (*cmd && isspace(*cmd))
104 cmd++;
105 if (*cmd == 0)
106 break;
107 if (*cmd == '"') {
108 quoted++;
109 cmd++;
110 }
111 argv[ct++] = cmd;
112 if (quoted) {
113 if ((cmd = parse_string(cmd)) == NULL)
114 return 0;
115 } else {
116 while (*cmd && !isspace(*cmd))
117 cmd++;
118 }
119 if (*cmd)
120 *cmd++ = 0;
121 }
122 argv[ct] = NULL;
123 return ct;
124 }
125
126 /* Find the command from the command table and execute it. */
127
128 int cmdparse(struct cmd *cmds, char *cmdline)
129 {
130 struct cmd *cmdp;
131 int argc;
132 char *argv[32];
133
134 if ((argc = parse_args(argv, cmdline)) == 0 || *argv[0] == '#')
135 return 0;
136 strlwr(argv[0]);
137 for (cmdp = cmds; cmdp->function != NULL; cmdp++)
138 if (strncasecmp(cmdp->name, argv[0], strlen(argv[0])) == 0)
139 break;
140 if (cmdp->function == NULL)
141 return -1;
142 return (*cmdp->function)(argc, argv);
143 }
144
145 /* Signal handlers (which don't do all the things they SHOULD do) */
146
147 static void alarm_handler(int sig)
148 {
149 printf("\nTimeout! Closing...\n");
150 exit(1);
151 }
152
153 static void term_handler(int sig)
154 {
155 printf("System going down! Closing...\n");
156 exit(1);
157 }
158
159 /* Initialisation for the user */
160
161 int init_user(char *call)
162 {
163 struct passwd *pw;
164 char pass[13], salt[3];
165 char *p;
166 char axhome[64];
167
168 /* Strip SSID */
169 if (local) {
170 pw = getpwuid(getuid());
171 } else {
172 strcpy(callsign, call);
173 strcpy(username, callsign);
174 strlwr(username);
175 p = strchr(username, '-');
176 if (p) *p = '\0';
177 pw = getpwnam(username);
178 }
179
180 if (!pw) {
181 if (local)
182 panic("Ouch, you don't seem to be in the password file.\n");
183 if (autocreate) {
184 syslog(LOG_NOTICE, "Adding new user %s", username);
185 if (new_user(username) < 0) {
186 syslog(LOG_NOTICE, "Could not add new user %s", username);
187 printf("Sorry, could not add new user.\n");
188 return -1;
189 }
190 printf("You have been added to the user list of %s.\nWelcome.\n", hostname);
191 pw = getpwnam(username);
192 } else {
193 syslog(LOG_NOTICE, "New user %s not accepted", username);
194 printf("Sorry, new users are not accepted at this time.\n");
195 return -1;
196 }
197 } else {
198 if (local) {
199 strcpy(username, pw->pw_name);
200 strcpy(callsign, username);
201 }
202 /* Strip full name from the gecos field... */
203 if (strchr(pw->pw_gecos, ',') == NULL)
204 strcpy(fullname, pw->pw_gecos);
205 else
206 strcpy(fullname, strtok(pw->pw_gecos, ","));
207 }
208
209 if (!local) {
210 if ((mail_allowed == 1) && (strcmp(pw->pw_passwd, "*"))) {
211 printf("Sorry, you are not allowed to use axmail (you have a password set).\n");
212 return -1;
213 }
214
215 if ((mail_allowed == 2) && (!strcmp(pw->pw_passwd, "*"))) {
216 printf("Sorry, you are not allowed to use axmail (locked out in password file).\n");
217 return -1;
218 }
219 if (mail_allowed == 3) {
220 sprintf(axhome, "%s/%s", def_homedir, username);
221 if (strcmp(pw->pw_dir, axhome)) {
222 printf("Sorry, you are not allowed to use axmail - bad axhome.\n");
223 return -1;
224 }
225 }
226
227 if (identification == 1) {
228 getstr(pass, 12, "Password: ");
229 strncpy(salt, pw->pw_passwd, 2);
230 salt[2] = '\0';
231 if (strcmp(pw->pw_passwd, (char *)crypt(pass, salt))) {
232 printf("Login incorrect.\n");
233 return -1;
234 }
235 }
236
237 /* code supplied by Jaroslav Skarvada */
238 if ( (setgroups(0, NULL) == -1) || (setgid(pw->pw_gid) == -1) || (setuid(pw->pw_uid) == -1) )
239 panic("init_user: Argh, cannot setuid() or setgid() to %i.%i", pw->pw_uid, pw->pw_gid);
240 }
241
242 homedir = strdup(pw->pw_dir);
243 return 0;
244 }
245
246 int main(int argc, char **argv)
247 {
248 char *p;
249
250 signal(SIGALRM, alarm_handler);
251 signal(SIGTERM, term_handler);
252 openlog("axmail", LOG_PID, LOG_DAEMON);
253
254 if (getuid() != 0)
255 local = 1; /* Hey, we're being executed by a "normal"
256 * user, with user privileges!
257 */
258
259 if ((!local) && (argc != 2)) {
260 printf("axmail: Callsign not found as a parameter.\n");
261 syslog(LOG_NOTICE, "Callsign not found as a parameter\n");
262 return 1;
263 }
264
265 if (read_config() == -1) /* Read axmail.conf */
266 return 1;
267
268 printf("%s\n", VERSION);
269
270 if (init_user(argv[1]) == -1) /* Get user specific data, create user account */
271 return 1;
272
273 tinit(); /* Filenames etc */
274 getmail(); /* Scan mailbox */
275
276 if ((newm) || (messages))
277 printf("You have %i messages (%i new).\n", messages, newm);
278
279 prompt();
280 fflush(stdout);
281
282 p = malloc(1024);
283
284 while (1)
285 {
286 fgets(p, 1023, stdin);
287
288 if (p == NULL)
289 quit(0, 0);
290
291 if (cmdparse(Mailcmds, p) == -1)
292 printf("Unknown command. Type ? for a list.\n");
293
294 prompt();
295 fflush(stdout);
296 }
297
298 }
299
0 axMail - an SMTP mailbox for the various linux node frontends
1 and outbound FAX engine.
2
3 Current author: Brian Rogers (N1URO) <n1uro@n1uro.com>
4 Past author: Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>
5 Creator: Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
6
7 Additional Submissions: Stefano (IW3IJQ) <ziotibia1@libero.it>
8
9 As with any of the softwares I tweek n geek, *use at your own risk*!
10 With that said, and the fact that this is GPL software if you find
11 something that's borked... don't just submit a bug report. Fix it if
12 you can. Rerelease it under your own callsign if you wish, or feel free
13 to send me your code and I'll import it in.
14
15 This is probably one of the simplest packages to install and configure!
16 After you run tar zxvf axmail-###.tgz cd axmail-#### (which is where
17 you should be now if you're reading this :) ) and run:
18
19 First, edit config.h and if you have /etc/clamsmtpd.conf and installed
20 clamsmtp, define CLAMSMTP, otherwise leave it undefined. Then run:
21 make; make install
22 Note: If your clamsmtpd.conf is in /usr/local/etc, symlink it to /etc.
23
24 (on newer gcc/libs I do know that there's a warning after it makes but
25 it doesn't prevent the binary from compiling and so far it seems to test
26 ok. I'll fix that if and when I get the chance but don't hold your breath
27 on it hi!)
28
29 cd /usr/local/etc/ax25 and using your favorite editor (vi, joe, pico, etc) and
30 edit axmail.conf. In here you can specify how you wish the mailbox
31 to handle accounting for end users. On *most* linux systems, the default
32 should be "ok" but if you wish to have users contact you first, or if
33 you wish to have the system auto-create a standard shell login, or popmail
34 account for the users, etc... you may do so in the file. Double check your
35 settings (it *is* possible you can configure axmail.conf so that everyone
36 has root-group access... but why would you wish to do that? You've been
37 *warned* so double check your config settings for auto-creation of
38 accounts before saving!) The file is well commented to assist you. When
39 you're finished and have become an expert, if you wish to you can delete
40 the comment lines.
41
42 You may also customize the file "welcome.txt" in /usr/local/etc/ax25/ if you
43 wish to also. I suggest leaving the first line as-is as this is the so called
44 "new user" welcome greeting email. I've supplied a basic and short
45 greeting email message that users will get once they've created their
46 mailbox. If you would rather new users email your mail account directly
47 instead of root, you may wish to change that line.
48
49 For the software itself... believe it or not, you're *DONE*! That's all!
50 However... now we need to get it hooked into which ever node frontend you
51 run so that users have a way of accessing it. axMail runs as an external
52 process (ExtCmd) to the node. I've tested it with URONode (obviously) and
53 with LinuxNode by Tomi. To do this cd /usr/local/etc/ax25 and using your
54 favorite editor open node.conf and add the following line to your ExtCmds:
55
56 ExtCmd MAil 1 root /usr/local/sbin/axmail axmail %u
57 (note: MA in the word MAil is in CAPS)
58
59 Save uronode.conf and telnet in to test! It should work just fine. Since you
60 would have an existing account on your server, it's unlikely that you'll
61 get the welcome message, but since you can edit it, you'll know what it
62 says :)
63
64 **ERROR 1**
65 *** Note:
66 If you're installing axMail-FAX via source, but your MTA (aka: postfix)
67 was installed from repository packaging, you may need to create a symlink
68 to your users mail file directory... typically:
69 /var/spool/mail/ -> /usr/local/var/spool/mail/
70 If you don't do this, users will NOT see their incoming mail.
71 ***
72
73 Happy mailing!
74
0 USAGE
1 name
2
3 DESCRIPTION
4 Use the Name command to change your "Real name" within the mail
5 server system. It will automatically be appended to your email
6 address when you send mail out.
0 USAGE
1 Autofwd
2
3 DESCRIPTION
4 This command will set the system to auto-forward any incoming
5 mail to this address to a "home" axMail-FAX system you would
6 usually use, OR you could set it to forward any mails from
7 this system to any SMTP based system ie: xNOS, internet, etc.
8 Just hitting the enter key will clear your mail forwarding
9 and your incoming mail to this system will be held here for you.
10
0 USAGE
1 SReply (short for "send reply")
2
3 DESCRIPTION
4 This command allows you to send a reply to the message number
5 the prompt tells you that you're on. Subject and destination
6 will be preserved.
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axMail 2.12.2
27 Updated January 18, 2021
28 - Fixed bug in mailcmd.c where sending acted funky on 64 bit systems.
29 axMail would segfault out before properly returning the user back to
30 the mailbox prompt.
31 - While at it also fixed some compiler warnings in mailcmd.c
32 - edited defines.h to fix old path from /var/ax25 to /var/lib/ax25
33 - edited defines.h to reflect this version.
34
35 axMail 2.12.1
36 Updated January 17, 2021
37 - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail
38 to honor linux file system rules.
39 - Changed defines.h to reflect this version.
40 axMail 2.12
41 Updated August 17, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
42 - After fussing with an updated ClamSMTP system that appears to have some
43 issues at least in regards to the Debian repositories I have come to
44 learn that the MTA used (postfix) beginning with version 2.3 now may
45 use milter (mail filter) systems. Details on how to configure the newer
46 ClamAV-Milter system are at https://uronode.n1uro.com/linux/ under the
47 ClamSMTP link at the bottom of the page. This is quite a major enhancement
48 to axMail-Fax!
49
50 Since now it will scan for either clamsmtp OR clamav-milter the outputs
51 on mails show only that the mail has been scanned by ClamAV.
52 axMail 2.11.1
53 Updated February 21, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
54 - removed the #ifdef CLAMSMTP routine from config.h
55 - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer
56 needs to be previously defined in config.h and auto senses now in mailcmd.c.
57 It dawned on me that the reason it was segfaulting if there was no .conf
58 file that trying to fclose() a file that did not exist was the reason that
59 it was causing axmail to segfault.
60 - made this version 2.11.1 in defines.h.
61 - updated INSTALL and README to reflect history and instructions.
62 - updated Makefile so make upgrade does not replace config files since
63 it's not required if you're simply upgrading from axmail-2.9 or greater.
64 axmail 2.11
65 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
66 - Figured out how to add ClamSMTP to the mail system's MTA. Details
67 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
68 This will scan for viri both IN and OUT bound mails! Very handy!
69 - Added a define routine in config.h now. You must #define or #undef
70 CLAMSMTP based on whether or not you're running clamsmtp and have
71 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
72 create a symlink to it and you'll be fine.
73 - added the fact when #defined where mails are tagged with the fact that
74 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
75 - upped the version to 2.11 in defines.h
76 - added notes in INSTALL in regards to the new #define in config.h
77 axmail 2.10
78 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
79 - added online help for the "Delivery Receipt" command. This keeps
80 it in line with all the other online helps.
81 - modified defines.h with this version number and also increased the
82 year that I'm still working on modifications to the project.
83 axmail 2.9
84 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
85 - Removed asking for password upon new user login, instead added a new
86 field to axmail.conf for "SysopMail". Now the sysop has to put in their
87 email address as to inform the end user to request their desired password
88 into the system, especially if the sysop is running pop/imap features on
89 their system. This will prevent users from entering in plain text passwords
90 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
91 a major security fix for axMail-FAX.
92 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
93 another program changed the user's mail spool file the warning displays
94 clearer.
95 - changed version number to 2.9 in defines.h and changed the end year of
96 maintenance from 2017 to 2018.
97
98 axmail 2.8
99 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
100 Changes:
101 - added SPers as a command per the suggestion of VE1JOT. This was done in
102 command.c and was actually quite simple to impliment. The logic behind
103 it is to match the mail send command sets with those of standard PBBS
104 messaging commands.
105 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
106 urged that flags, cc, and bcc options be supressed to make it more user
107 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
108 do have compassion for those on HF. Steve gave me a different idea than
109 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
110 and command.c. If one needs a read receipt or to send cc/bcc copies of
111 their message then S still is an option.
112 - added a "spers" .hlp file to the archive.
113 - changed defines.h to reflect version 2.8.
114 - updated welcome.txt to be more generic rather than be version specific.
115 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
116 mail. This allows for a duplicate of the message to be sent to the second
117 person one wishes to copy on the mail.
118 - edited this file.
119 - while I was at it, I decided to add a "blind carbon copy" feature.
120 This will send a copy of a message to the user specified HOWEVER,
121 they will NOT be listed in the recipient listings. For those using
122 raw terminals, it's possible to NOT enter a 'cc' but still enter a
123 'bcc' address.
124 - edited help files: send.hlp and spersonal.hlp to help guide users
125 on how to best send mail.
126 - created a bypass method so that if users did not wish to use cc or bcc
127 mail, they can bypass them instead of being prompted for them - suggested
128 by VE1JOT.
129 - added online help for send/sp|cc|bcc mail.
130 - added a new signature file function to the system in both command.c and in
131 mailcmd.c. If no signature file exists, it will instruct the user on this
132 fact and also inform them how to make one using the new SIgnature command.
133 Note: If no ~/.signature file exists mail will still be sent, just without
134 a 1 line siguature (max: 79 characters).
135 - bullet proofed both the autoforward and signature file routines in command.c
136 by insuring that a null string not only halts execution of both but also
137 removes both ~/.forward and ~/.signature files respectively.
138 - cleaned up the send signature a bit and added my little spam ad even if
139 there is no signature file present. This was done in mailcmd.c.
140 - added a string in the signature prompt which informs users how to clear
141 their signature if they desire such. This was done in utils.c
142 - Added special critical instructions to INSTALL. I didn't know if I had
143 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
144 - Fixed a bug that when the mailbox file(s) weren't found for the system
145 MTA (aka: postfix) axMail would segfault. Now not only does it not
146 segfault but also instructs the user to inform the sysop of this error.
147 This bug existed since version 0.0.1. I've been wanting to do something
148 about this for IONs but didn't get to it until now. This was done in quit.c
149 - Fixed a couple of typos in README. I have a very difficult keyboard!
150 - Per the suggestion of G4APL (who gives us many great ideas - and why do
151 I refer to myself in plural? I need a DIET!) I did two things:
152 1 - when listing mail there's no message date stamp within the listing.
153 added in mailcmd.c
154 2 - reordered the mail listing fields where I felt they'd make the most
155 sense. Message subject, then message date, then message size are
156 the last 3 fields listed. They should also be kept in a column
157 justified manner of sorts.
158 3 - added a (St)atus header so the user has a better definition of
159 the status of a specific message.
160
161 axmail 2.7
162 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
163 Changes:
164 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
165 the user entered a parameter such as a message number for example,
166 it wouldn't properly function. This has been fixed. Thanks Van!
167 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
168 - I know in the past I had a 'cc' command for sending mail, and it's
169 been suck in my craw to readd it since.
170
171 axmail 2.6
172 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
173 Changes:
174 - changed version number in defines.h
175 - fixed error message when a pop client has deleted mail from the
176 main mail spool file.
177 - removed excessive receipt warning spotted by a gent who identifies
178 himself as rigor. This was in mailcmd.c in do_readmsg()
179 - while looking at the end of that routine, it just gave me an itch that
180 said "if you can look for a warning about a requested receipt, then
181 numbnutz you can offer the reader a chance to just generate a receipt
182 without having to do "SR" as previously stated at the end of the mail.
183 So, with that said and to get feeling back in my genitals, I wrote a
184 routine that asks the reader if they wish to send a receipt, and it
185 also echos where it's destined and confirmation it was sent.
186 - added an "--- end of message #* ---" tag at the end of mail when it
187 as finished displaying. This was done in mailcmd.c
188 - fixed an existing bug in the message routines where for each message
189 it wasn't resetting the receipt pointer! This bug existed since I
190 introduced the receipt "finder" in the messages. I'm shocked that
191 it wasn't reported to me by someone earlier. Now *only* if a message
192 has requested a receipt will it show that a receipt has been asked
193 for... whew!
194 - So many missing online help files! Again I'm surprised no one brought
195 this to my attention. How did we get along with them? "Oh my!" - Sulu
196 - Updated this README file.
197
198 axmail v2.5.1
199 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
200 Changes:
201 - added axmail.8 man page as per spec of Debian downstream.
202 - modified Makefile to include axmail.8 manpage installation for both
203 new and upgrade options.
204 - modified defines.h and this document to reflect maintenance release.
205
206 axmail v2.5
207 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
208 Changes:
209 - added new delivery receipt function to the send routine. This
210 compliments the read receipt function in the event of high
211 priority mail. Typically the read receipt is an option generated
212 by the recipient who may not decide to generate one. At least this
213 modification ensures with an ESMTP delivery that the sender using
214 axMail will get a reciept from "MAILER-DAEMON" which will verify
215 the status of delivered mail. This change was done in mailcmd.c
216 and is designed with the sendmail binary included with postfix.
217 - updated this README file.
218 - updated version number in defines.h
219
220 axmail v2.4
221 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
222 Changes:
223 - cleaned up mbox.c where I had originally placed the receipt checker
224 routine in. This caused loops within the buffer that displayed the
225 message. The true routine lives in mailcmd.c
226 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
227 downstream compiles to make packages.
228 - changed version in defines.h
229 - major change in command.c, added a new Autofwd command to allow users to
230 auto-forward mail from a remote system to their "home" axMail-FAX base
231 system. Could also be used to forward mail to their internet accounts.
232 - added autofwd.hlp file.
233 - alphabetized the commandset listing, removed redundantly spelled commands.
234 - reworked Makefile and added an "upgrade" option so new files ONLY are
235 deployed after make. Execute using: "make upgrade"
236 - updated this file.
237
238 axmail v2.3.1
239 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
240 Changes:
241 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
242 message, a bell and a warning sign is generated after the message has been
243 read by the user with instructions to use SR to generate a receipt. This
244 was a difficult routine for me to think of considering the various race
245 conditions that can be expected and met.
246 - updated welcome.txt with version upgrade and new feature list.
247 - updated README.
248
249 axmail v2.3
250 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
251 Changes:
252 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
253 This defaults to NO but when flagged to YES, a request will be sent to the
254 remote client's agent. If the agent supports such, they will be prompted
255 whether or not to honor your receipt request. This is history as NO AGENT
256 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
257 receipt is similar to how HylaFax generates confirmation of transmission
258 receipt mails to your mailbox. Currently mail read in axMail will NOT
259 generate a receipt back. I may work on this later, but for now it doesn't
260 exist.
261 * My thoughts of the receipt function is negative. The fact that I may be
262 sending notification that I'm in my email client to a remote destination
263 IMHO is such that a webcam may as well be turned on and watch me do email,
264 and send the stream to "Big Brother" and I don't mean the television show.
265 </rant>
266 - Updated defines.h with the new version number.
267 - Updated welcome.txt so the new version number is displayed.
268
269 axmail v2.2
270 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
271 Changes:
272 - Made some maintenance changes, but forgot to log them in here.
273 axmail v2.1.1
274 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
275 Changes:
276 - Makefile
277 Code provided by Bob Tenty VE3TOK to make it more compatable
278 with newer GCC compiler requirements.
279 - utils.c
280 Code provided by Bob Tenty VE3TOK to fix a warning produced when
281 compiling.
282 - defines.h
283 Changed version number to reflect the changes incorporated by
284 Bob Tenty VE3TOK and committed to the subversion repository.
285
286 axmail v2.1
287 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
288 Changes:
289 - axmail.c
290 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
291 the system privilege matching.
292 - global
293 axMail is now under review for considerations as standard packaging in
294 RedHat's fedora project. It appears it's going to be added as a package.
295
296 axmail v2.0
297 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
298 Changes:
299 - defines.h
300 Updated version number to reflect version release 2.0. Version 1.0.5
301 was simply a maintenance test package to try and reincorporate what
302 I had done up to version 1.0.6 which I believe was one of my last
303 releases up to 2009. Since I've done all that I can recall at this
304 point and time, I decided to match URONode's release numerics with
305 a 2.0 release version.
306
307 axmail v1.0.5
308 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
309 Changes:
310 - defines.h
311 Updated email listings to reflect the most current ones I could find
312 including my own. Also added 2013 to the years worked on axMail by
313 me.
314 - quit.c
315 Forced ALL mail, read or otherwise when user quits to save to the
316 user's system mailbox. This is for reverse compatability with those
317 who may also run a web-based email service on the internet such as
318 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
319 any read mail (and all accompanying mail in that session) to the
320 axmail ~/mbox file. We don't want this for the specific reason of
321 "reverse email client" compatability.
322
323 axmail v1.0.4
324 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
325 Changes:
326 - setpwnam.c
327 Changed the way SIGPIPE was handled. Instead of being ignored, it will
328 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
329 a shell prompt, or a node frontend. I've been noticing especially on
330 some timeouts that temp files don't flush as they should and the
331 user's directory can start to fill up.
332
333 axMail v1.0.3
334 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
335 Changes:
336 - mailcmd.c
337 Reset the way I wanted to handle the user input routine for sending faxes.
338 Commented out some more unneeded/unused code in the do_fax routine... will
339 clean it up in next release or so.
340 - mailcmd.c
341 cleaned up a bug I introduced in the never released 1.0.2 where the
342 X-Mailer was duping itself after each line of the body of a message.
343 - sfax.hlp
344 Reworded the SFax help file to help show some examples of how to format
345 the header.
346
347 axMail v1.0.2
348 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
349 Changes:
350 - mailcmd.c
351 Cleaned up some of the code in SFax. Also made some cosmetic changes.
352
353 axMail v1.0.1
354 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
355 Changes:
356 - mailcmd.c
357 Added a new routine to allow users to send faxes. This is defined by the
358 command "SF" for Send Fax. The routine was taken from the "S"end function
359 however since it's a one-way transmission, there is no reply available
360 nor is there an option for users to fax to any fax service as some I know
361 are pay services.
362 - config.h
363 added definitions for faxgate in axmail.conf
364 - config.c
365 added routine to allow for faxgate as a variable and be called from
366 mailcmd.c
367 - defines.h
368 version upgraded from v1.0.0 (unreleased - test version) to
369 v1.0.1
370 - etc/axmail.conf
371 Added new line called "FaxGate" with an example of how to properly
372 configure this line.
373 - etc/help/sfax.hlp
374 Added new file "sfax.hlp" which is an online help file for the SFax
375 command.
376
377 axMail v0.0.9
378 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
379 Changes:
380 - mailcmd.c
381 Added a new routine that prompts the sender whether or not the message
382 is of an emergency/high priority mail message. If it's emergency message
383 then the headers are appended with an X-code flagged in such a manner
384 that Eudora and Outlook will display the received mail with a red flag
385 of sorts. The idea of such came to me in thinking of "what can I do
386 to help improve means of emergency communications using TCP/IP, Linux,
387 and packet radio?" Having the ability to "red flag" an SMTP message
388 I don't believe has yet to be available in any packet messaging
389 system... axMail I hope is the first.
390
391 If a user just hits enter, or selects "no" then the mail message
392 is sent under normal send routines.
393
394 found a minor bug in my routine where if an end user answered
395 "yes" in wanting to send an emergency/high priority message the system
396 ignored the request and sent it as 'normal' delivery. Made a minor
397 change to bullet-proof the responce.
398
399 Added online help text if user is unsure about sending a message
400 flagged urgent or normal. This text is available when the user is
401 prompted for priority selection by hitting "?" at the prompt.
402 - defines.h
403 Version updated from v0.0.8 to v0.0.9
404
405 axMail v0.0.8
406 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
407
408 Changes:
409 - mailcmd.c
410 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
411 it's version number in the X-Mailer: string.
412 - mailcmd.c
413 Added an X-Origin: string to show those peeking at mail headers
414 just how the message was possibly sent... by AMATEUR RADIO!
415 - axmail.conf
416 Added config option in "AllowMail" for axhome, a rewrite of code
417 submitted by Stefano IW3IJQ. While I stripped out home directory
418 structures similar to that of qmail or axspawn, Stefano convinced
419 me that it may be easier to manage home directories for axMail users
420 who don't have shell access to branch out within a preset directory.
421 - defines.h
422 Updated version number from 0.0.7 to 0.0.8
423 - axmail.c and config.c
424 Rewrote and incorporated code to allow for the routines to use
425 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
426 While I was at it, I rewrote and shortened the error text pushed
427 to a user who doesn't have permission to use such a directory.
428 * Note: When I write error texts and menus, I try to write them for
429 users on a multi-hop 1200 baud path thus the shorter the better as
430 long as context isn't lost and for long distance hops where full
431 paclen may cause retries (worse yet timeouts!)
432
433 axMail v0.0.7
434
435 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
436
437 Changes:
438 - cosmetics
439 My usual "I like seeing this this way" type cosmetics... too many
440 to mention!
441 - adduser.c
442 changed the hard coding of user 'home' directories so that instead
443 of them going into a period delimited sort, just dump em all into
444 /home/<user> which seems to be "the norm" on most systems I've had
445 to assist with.
446 - adduser.c
447 fixed a bug where creating a user was actually causing the program to
448 segfault upon exit the first time a user went into the mailbox! The
449 node frontends hid this segfault as the program still flushed itself
450 from ram but I spotted it when running it at a command prompt. The
451 segfault came when axMail attempted to write mail back to the user's
452 system mailbox and it didn't exist. How I fixed this is listed next.
453 This may just be a new bug that appeared with the upgrading of libs,
454 this I'm unsure of and since I have no desire to go backwards I have
455 decided to actually make a minor routine...
456 - welcome.txt
457 New users are now sent a "welcome" message that the sysop can easily
458 customize to their desires. It's located at /etc/ax25/welcome.txt.
459 I figured that since axMail was segfaulting because such a file did
460 not exist, I might as well make use of this need by having the program
461 send the user a greeting.
462 - defines.h
463 Changed paths to be more in line with the more modern type configs
464 as a default. Paths can still be defined by the sysop prior to
465 compiling axMail.
466 - Makefile
467 I changed the default of make install to include all of the subroutines
468 within the Makefile yet leaving such things as "make installbin"
469 available as runtime options if just a binary refresh creation is
470 desired.
471 - other
472 I'm sure I missed a note or two *shrug*
473
474 axMail v0.0.6
475
476 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
477 I at one time had but lost and can't seem to find it. My (n1uro)
478 changes may have alread been incorporated.
479
480 axMail v0.0.5
481
482 True mailbox functionalities created by Marius Petrescu.
483 Added Mailbox save routines (compatible with the command line
484 mail agent, including ~/mbox file)
485
486 axMail v0.0.4
487
488 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
489
490 This program is free software; you can redistribute it and/or modify
491 it under the terms of the GNU General Public License as published by
492 the Free Software Foundation; either version 2 of the License, or
493 (at your option) any later version.
494
495 This program is distributed in the hope that it will be useful,
496 but WITHOUT ANY WARRANTY; without even the implied warranty of
497 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
498 GNU General Public License for more details.
499
500 You should have received a copy of the GNU General Public License
501 along with this program; if not, write to the Free Software
502 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
503
504
505 Don't give this one to anyone yet... it is NOT ready for distribution!
506
507 This is a simple mail user agent intended to provide the
508 mail functions in xNOS in a Linux ax.25 environment. If required,
509 it creates a normal user account for each new user (code mostly taken
510 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
511 on the system. axMail uses sendmail (or similar) to deliver mail, and
512 reads mail from each user's system mailbox (/var/spool/mail/username).
513 It does not provide any means of transferring mail between hosts.
514
515 axMail provides a simple, low-overhead user interface, much similar
516 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
517 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
518
519 axMail is intended to be called from node. It takes one command
520 line argument of the user's callsign (with or without SSID). It must
521 be run as root, but it setuid()'s itself to the respective user's
522 privileges as soon as possible. It might run from ax25d as well.
523 It can also be executed from a shell with user privileges.
524
525 Some code (command parser, configuration file stuff) and the internal
526 architecture was taken from the LinuxNode frontend by Tomi Manninen
527 (OH2BNS). Thanks!
528
529 INSTALLATION:
530
531 See the file: INSTALL
532
533 TODO:
534 Suggestions?
535
536 --
537 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
538 ftp://ftp.n1uro.net/pub/hamradio/packet
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.9"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2018 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axMail 2.12
27 Updated August 17, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
28 - After fussing with an updated ClamSMTP system that appears to have some
29 issues at least in regards to the Debian repositories I have come to
30 learn that the MTA used (postfix) beginning with version 2.3 now may
31 use milter (mail filter) systems. Details on how to configure the newer
32 ClamAV-Milter system are at https://uronode.n1uro.com/linux/ under the
33 ClamSMTP link at the bottom of the page. This is quite a major enhancement
34 to axMail-Fax!
35
36 Since now it will scan for either clamsmtp OR clamav-milter the outputs
37 on mails show only that the mail has been scanned by ClamAV.
38 axMail 2.11.1
39 Updated February 21, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
40 - removed the #ifdef CLAMSMTP routine from config.h
41 - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer
42 needs to be previously defined in config.h and auto senses now in mailcmd.c.
43 It dawned on me that the reason it was segfaulting if there was no .conf
44 file that trying to fclose() a file that did not exist was the reason that
45 it was causing axmail to segfault.
46 - made this version 2.11.1 in defines.h.
47 - updated INSTALL and README to reflect history and instructions.
48 - updated Makefile so make upgrade does not replace config files since
49 it's not required if you're simply upgrading from axmail-2.9 or greater.
50 axmail 2.11
51 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
52 - Figured out how to add ClamSMTP to the mail system's MTA. Details
53 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
54 This will scan for viri both IN and OUT bound mails! Very handy!
55 - Added a define routine in config.h now. You must #define or #undef
56 CLAMSMTP based on whether or not you're running clamsmtp and have
57 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
58 create a symlink to it and you'll be fine.
59 - added the fact when #defined where mails are tagged with the fact that
60 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
61 - upped the version to 2.11 in defines.h
62 - added notes in INSTALL in regards to the new #define in config.h
63 axmail 2.10
64 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
65 - added online help for the "Delivery Receipt" command. This keeps
66 it in line with all the other online helps.
67 - modified defines.h with this version number and also increased the
68 year that I'm still working on modifications to the project.
69 axmail 2.9
70 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
71 - Removed asking for password upon new user login, instead added a new
72 field to axmail.conf for "SysopMail". Now the sysop has to put in their
73 email address as to inform the end user to request their desired password
74 into the system, especially if the sysop is running pop/imap features on
75 their system. This will prevent users from entering in plain text passwords
76 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
77 a major security fix for axMail-FAX.
78 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
79 another program changed the user's mail spool file the warning displays
80 clearer.
81 - changed version number to 2.9 in defines.h and changed the end year of
82 maintenance from 2017 to 2018.
83
84 axmail 2.8
85 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
86 Changes:
87 - added SPers as a command per the suggestion of VE1JOT. This was done in
88 command.c and was actually quite simple to impliment. The logic behind
89 it is to match the mail send command sets with those of standard PBBS
90 messaging commands.
91 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
92 urged that flags, cc, and bcc options be supressed to make it more user
93 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
94 do have compassion for those on HF. Steve gave me a different idea than
95 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
96 and command.c. If one needs a read receipt or to send cc/bcc copies of
97 their message then S still is an option.
98 - added a "spers" .hlp file to the archive.
99 - changed defines.h to reflect version 2.8.
100 - updated welcome.txt to be more generic rather than be version specific.
101 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
102 mail. This allows for a duplicate of the message to be sent to the second
103 person one wishes to copy on the mail.
104 - edited this file.
105 - while I was at it, I decided to add a "blind carbon copy" feature.
106 This will send a copy of a message to the user specified HOWEVER,
107 they will NOT be listed in the recipient listings. For those using
108 raw terminals, it's possible to NOT enter a 'cc' but still enter a
109 'bcc' address.
110 - edited help files: send.hlp and spersonal.hlp to help guide users
111 on how to best send mail.
112 - created a bypass method so that if users did not wish to use cc or bcc
113 mail, they can bypass them instead of being prompted for them - suggested
114 by VE1JOT.
115 - added online help for send/sp|cc|bcc mail.
116 - added a new signature file function to the system in both command.c and in
117 mailcmd.c. If no signature file exists, it will instruct the user on this
118 fact and also inform them how to make one using the new SIgnature command.
119 Note: If no ~/.signature file exists mail will still be sent, just without
120 a 1 line siguature (max: 79 characters).
121 - bullet proofed both the autoforward and signature file routines in command.c
122 by insuring that a null string not only halts execution of both but also
123 removes both ~/.forward and ~/.signature files respectively.
124 - cleaned up the send signature a bit and added my little spam ad even if
125 there is no signature file present. This was done in mailcmd.c.
126 - added a string in the signature prompt which informs users how to clear
127 their signature if they desire such. This was done in utils.c
128 - Added special critical instructions to INSTALL. I didn't know if I had
129 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
130 - Fixed a bug that when the mailbox file(s) weren't found for the system
131 MTA (aka: postfix) axMail would segfault. Now not only does it not
132 segfault but also instructs the user to inform the sysop of this error.
133 This bug existed since version 0.0.1. I've been wanting to do something
134 about this for IONs but didn't get to it until now. This was done in quit.c
135 - Fixed a couple of typos in README. I have a very difficult keyboard!
136 - Per the suggestion of G4APL (who gives us many great ideas - and why do
137 I refer to myself in plural? I need a DIET!) I did two things:
138 1 - when listing mail there's no message date stamp within the listing.
139 added in mailcmd.c
140 2 - reordered the mail listing fields where I felt they'd make the most
141 sense. Message subject, then message date, then message size are
142 the last 3 fields listed. They should also be kept in a column
143 justified manner of sorts.
144 3 - added a (St)atus header so the user has a better definition of
145 the status of a specific message.
146
147 axmail 2.7
148 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
149 Changes:
150 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
151 the user entered a parameter such as a message number for example,
152 it wouldn't properly function. This has been fixed. Thanks Van!
153 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
154 - I know in the past I had a 'cc' command for sending mail, and it's
155 been suck in my craw to readd it since.
156
157 axmail 2.6
158 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
159 Changes:
160 - changed version number in defines.h
161 - fixed error message when a pop client has deleted mail from the
162 main mail spool file.
163 - removed excessive receipt warning spotted by a gent who identifies
164 himself as rigor. This was in mailcmd.c in do_readmsg()
165 - while looking at the end of that routine, it just gave me an itch that
166 said "if you can look for a warning about a requested receipt, then
167 numbnutz you can offer the reader a chance to just generate a receipt
168 without having to do "SR" as previously stated at the end of the mail.
169 So, with that said and to get feeling back in my genitals, I wrote a
170 routine that asks the reader if they wish to send a receipt, and it
171 also echos where it's destined and confirmation it was sent.
172 - added an "--- end of message #* ---" tag at the end of mail when it
173 as finished displaying. This was done in mailcmd.c
174 - fixed an existing bug in the message routines where for each message
175 it wasn't resetting the receipt pointer! This bug existed since I
176 introduced the receipt "finder" in the messages. I'm shocked that
177 it wasn't reported to me by someone earlier. Now *only* if a message
178 has requested a receipt will it show that a receipt has been asked
179 for... whew!
180 - So many missing online help files! Again I'm surprised no one brought
181 this to my attention. How did we get along with them? "Oh my!" - Sulu
182 - Updated this README file.
183
184 axmail v2.5.1
185 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
186 Changes:
187 - added axmail.8 man page as per spec of Debian downstream.
188 - modified Makefile to include axmail.8 manpage installation for both
189 new and upgrade options.
190 - modified defines.h and this document to reflect maintenance release.
191
192 axmail v2.5
193 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
194 Changes:
195 - added new delivery receipt function to the send routine. This
196 compliments the read receipt function in the event of high
197 priority mail. Typically the read receipt is an option generated
198 by the recipient who may not decide to generate one. At least this
199 modification ensures with an ESMTP delivery that the sender using
200 axMail will get a reciept from "MAILER-DAEMON" which will verify
201 the status of delivered mail. This change was done in mailcmd.c
202 and is designed with the sendmail binary included with postfix.
203 - updated this README file.
204 - updated version number in defines.h
205
206 axmail v2.4
207 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
208 Changes:
209 - cleaned up mbox.c where I had originally placed the receipt checker
210 routine in. This caused loops within the buffer that displayed the
211 message. The true routine lives in mailcmd.c
212 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
213 downstream compiles to make packages.
214 - changed version in defines.h
215 - major change in command.c, added a new Autofwd command to allow users to
216 auto-forward mail from a remote system to their "home" axMail-FAX base
217 system. Could also be used to forward mail to their internet accounts.
218 - added autofwd.hlp file.
219 - alphabetized the commandset listing, removed redundantly spelled commands.
220 - reworked Makefile and added an "upgrade" option so new files ONLY are
221 deployed after make. Execute using: "make upgrade"
222 - updated this file.
223
224 axmail v2.3.1
225 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
226 Changes:
227 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
228 message, a bell and a warning sign is generated after the message has been
229 read by the user with instructions to use SR to generate a receipt. This
230 was a difficult routine for me to think of considering the various race
231 conditions that can be expected and met.
232 - updated welcome.txt with version upgrade and new feature list.
233 - updated README.
234
235 axmail v2.3
236 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
237 Changes:
238 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
239 This defaults to NO but when flagged to YES, a request will be sent to the
240 remote client's agent. If the agent supports such, they will be prompted
241 whether or not to honor your receipt request. This is history as NO AGENT
242 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
243 receipt is similar to how HylaFax generates confirmation of transmission
244 receipt mails to your mailbox. Currently mail read in axMail will NOT
245 generate a receipt back. I may work on this later, but for now it doesn't
246 exist.
247 * My thoughts of the receipt function is negative. The fact that I may be
248 sending notification that I'm in my email client to a remote destination
249 IMHO is such that a webcam may as well be turned on and watch me do email,
250 and send the stream to "Big Brother" and I don't mean the television show.
251 </rant>
252 - Updated defines.h with the new version number.
253 - Updated welcome.txt so the new version number is displayed.
254
255 axmail v2.2
256 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
257 Changes:
258 - Made some maintenance changes, but forgot to log them in here.
259 axmail v2.1.1
260 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
261 Changes:
262 - Makefile
263 Code provided by Bob Tenty VE3TOK to make it more compatable
264 with newer GCC compiler requirements.
265 - utils.c
266 Code provided by Bob Tenty VE3TOK to fix a warning produced when
267 compiling.
268 - defines.h
269 Changed version number to reflect the changes incorporated by
270 Bob Tenty VE3TOK and committed to the subversion repository.
271
272 axmail v2.1
273 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
274 Changes:
275 - axmail.c
276 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
277 the system privilege matching.
278 - global
279 axMail is now under review for considerations as standard packaging in
280 RedHat's fedora project. It appears it's going to be added as a package.
281
282 axmail v2.0
283 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
284 Changes:
285 - defines.h
286 Updated version number to reflect version release 2.0. Version 1.0.5
287 was simply a maintenance test package to try and reincorporate what
288 I had done up to version 1.0.6 which I believe was one of my last
289 releases up to 2009. Since I've done all that I can recall at this
290 point and time, I decided to match URONode's release numerics with
291 a 2.0 release version.
292
293 axmail v1.0.5
294 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
295 Changes:
296 - defines.h
297 Updated email listings to reflect the most current ones I could find
298 including my own. Also added 2013 to the years worked on axMail by
299 me.
300 - quit.c
301 Forced ALL mail, read or otherwise when user quits to save to the
302 user's system mailbox. This is for reverse compatability with those
303 who may also run a web-based email service on the internet such as
304 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
305 any read mail (and all accompanying mail in that session) to the
306 axmail ~/mbox file. We don't want this for the specific reason of
307 "reverse email client" compatability.
308
309 axmail v1.0.4
310 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
311 Changes:
312 - setpwnam.c
313 Changed the way SIGPIPE was handled. Instead of being ignored, it will
314 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
315 a shell prompt, or a node frontend. I've been noticing especially on
316 some timeouts that temp files don't flush as they should and the
317 user's directory can start to fill up.
318
319 axMail v1.0.3
320 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
321 Changes:
322 - mailcmd.c
323 Reset the way I wanted to handle the user input routine for sending faxes.
324 Commented out some more unneeded/unused code in the do_fax routine... will
325 clean it up in next release or so.
326 - mailcmd.c
327 cleaned up a bug I introduced in the never released 1.0.2 where the
328 X-Mailer was duping itself after each line of the body of a message.
329 - sfax.hlp
330 Reworded the SFax help file to help show some examples of how to format
331 the header.
332
333 axMail v1.0.2
334 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
335 Changes:
336 - mailcmd.c
337 Cleaned up some of the code in SFax. Also made some cosmetic changes.
338
339 axMail v1.0.1
340 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
341 Changes:
342 - mailcmd.c
343 Added a new routine to allow users to send faxes. This is defined by the
344 command "SF" for Send Fax. The routine was taken from the "S"end function
345 however since it's a one-way transmission, there is no reply available
346 nor is there an option for users to fax to any fax service as some I know
347 are pay services.
348 - config.h
349 added definitions for faxgate in axmail.conf
350 - config.c
351 added routine to allow for faxgate as a variable and be called from
352 mailcmd.c
353 - defines.h
354 version upgraded from v1.0.0 (unreleased - test version) to
355 v1.0.1
356 - etc/axmail.conf
357 Added new line called "FaxGate" with an example of how to properly
358 configure this line.
359 - etc/help/sfax.hlp
360 Added new file "sfax.hlp" which is an online help file for the SFax
361 command.
362
363 axMail v0.0.9
364 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
365 Changes:
366 - mailcmd.c
367 Added a new routine that prompts the sender whether or not the message
368 is of an emergency/high priority mail message. If it's emergency message
369 then the headers are appended with an X-code flagged in such a manner
370 that Eudora and Outlook will display the received mail with a red flag
371 of sorts. The idea of such came to me in thinking of "what can I do
372 to help improve means of emergency communications using TCP/IP, Linux,
373 and packet radio?" Having the ability to "red flag" an SMTP message
374 I don't believe has yet to be available in any packet messaging
375 system... axMail I hope is the first.
376
377 If a user just hits enter, or selects "no" then the mail message
378 is sent under normal send routines.
379
380 found a minor bug in my routine where if an end user answered
381 "yes" in wanting to send an emergency/high priority message the system
382 ignored the request and sent it as 'normal' delivery. Made a minor
383 change to bullet-proof the responce.
384
385 Added online help text if user is unsure about sending a message
386 flagged urgent or normal. This text is available when the user is
387 prompted for priority selection by hitting "?" at the prompt.
388 - defines.h
389 Version updated from v0.0.8 to v0.0.9
390
391 axMail v0.0.8
392 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
393
394 Changes:
395 - mailcmd.c
396 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
397 it's version number in the X-Mailer: string.
398 - mailcmd.c
399 Added an X-Origin: string to show those peeking at mail headers
400 just how the message was possibly sent... by AMATEUR RADIO!
401 - axmail.conf
402 Added config option in "AllowMail" for axhome, a rewrite of code
403 submitted by Stefano IW3IJQ. While I stripped out home directory
404 structures similar to that of qmail or axspawn, Stefano convinced
405 me that it may be easier to manage home directories for axMail users
406 who don't have shell access to branch out within a preset directory.
407 - defines.h
408 Updated version number from 0.0.7 to 0.0.8
409 - axmail.c and config.c
410 Rewrote and incorporated code to allow for the routines to use
411 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
412 While I was at it, I rewrote and shortened the error text pushed
413 to a user who doesn't have permission to use such a directory.
414 * Note: When I write error texts and menus, I try to write them for
415 users on a multi-hop 1200 baud path thus the shorter the better as
416 long as context isn't lost and for long distance hops where full
417 paclen may cause retries (worse yet timeouts!)
418
419 axMail v0.0.7
420
421 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
422
423 Changes:
424 - cosmetics
425 My usual "I like seeing this this way" type cosmetics... too many
426 to mention!
427 - adduser.c
428 changed the hard coding of user 'home' directories so that instead
429 of them going into a period delimited sort, just dump em all into
430 /home/<user> which seems to be "the norm" on most systems I've had
431 to assist with.
432 - adduser.c
433 fixed a bug where creating a user was actually causing the program to
434 segfault upon exit the first time a user went into the mailbox! The
435 node frontends hid this segfault as the program still flushed itself
436 from ram but I spotted it when running it at a command prompt. The
437 segfault came when axMail attempted to write mail back to the user's
438 system mailbox and it didn't exist. How I fixed this is listed next.
439 This may just be a new bug that appeared with the upgrading of libs,
440 this I'm unsure of and since I have no desire to go backwards I have
441 decided to actually make a minor routine...
442 - welcome.txt
443 New users are now sent a "welcome" message that the sysop can easily
444 customize to their desires. It's located at /etc/ax25/welcome.txt.
445 I figured that since axMail was segfaulting because such a file did
446 not exist, I might as well make use of this need by having the program
447 send the user a greeting.
448 - defines.h
449 Changed paths to be more in line with the more modern type configs
450 as a default. Paths can still be defined by the sysop prior to
451 compiling axMail.
452 - Makefile
453 I changed the default of make install to include all of the subroutines
454 within the Makefile yet leaving such things as "make installbin"
455 available as runtime options if just a binary refresh creation is
456 desired.
457 - other
458 I'm sure I missed a note or two *shrug*
459
460 axMail v0.0.6
461
462 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
463 I at one time had but lost and can't seem to find it. My (n1uro)
464 changes may have alread been incorporated.
465
466 axMail v0.0.5
467
468 True mailbox functionalities created by Marius Petrescu.
469 Added Mailbox save routines (compatible with the command line
470 mail agent, including ~/mbox file)
471
472 axMail v0.0.4
473
474 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
475
476 This program is free software; you can redistribute it and/or modify
477 it under the terms of the GNU General Public License as published by
478 the Free Software Foundation; either version 2 of the License, or
479 (at your option) any later version.
480
481 This program is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
484 GNU General Public License for more details.
485
486 You should have received a copy of the GNU General Public License
487 along with this program; if not, write to the Free Software
488 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
489
490
491 Don't give this one to anyone yet... it is NOT ready for distribution!
492
493 This is a simple mail user agent intended to provide the
494 mail functions in xNOS in a Linux ax.25 environment. If required,
495 it creates a normal user account for each new user (code mostly taken
496 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
497 on the system. axMail uses sendmail (or similar) to deliver mail, and
498 reads mail from each user's system mailbox (/var/spool/mail/username).
499 It does not provide any means of transferring mail between hosts.
500
501 axMail provides a simple, low-overhead user interface, much similar
502 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
503 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
504
505 axMail is intended to be called from node. It takes one command
506 line argument of the user's callsign (with or without SSID). It must
507 be run as root, but it setuid()'s itself to the respective user's
508 privileges as soon as possible. It might run from ax25d as well.
509 It can also be executed from a shell with user privileges.
510
511 Some code (command parser, configuration file stuff) and the internal
512 architecture was taken from the LinuxNode frontend by Tomi Manninen
513 (OH2BNS). Thanks!
514
515 INSTALLATION:
516
517 See the file: INSTALL
518
519 TODO:
520 Suggestions?
521
522 --
523 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
524 ftp://ftp.n1uro.net/pub/hamradio/packet
0
1 /* quit.c - clean things up on exit. */
2
3 #include <stdio.h>
4 #include <sys/stat.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 #include "utils.h"
10 #include "quit.h"
11 #include "config.h"
12 #include "lock.h"
13 #include "mbox.h"
14
15 /* Remove a temporary file, if it exists */
16
17 void cleartmp(char *fname)
18 {
19 struct stat fst;
20
21 if (!stat(fname, &fst))
22 if (remove(fname))
23 printf("Ouch, couldn't remove %s.\n", fname);
24 }
25
26 /* Update system and user mailbox
27 (yo2loj - 13 april 2003) */
28
29 int save_mbox(void)
30 {
31 FILE *mb;
32 FILE *nm;
33 FILE *ub;
34 FILE *tmp;
35 FILE *dest;
36
37 long mblen=0;
38 int havenew = 0;
39
40 char buf[LINESIZE];
41 int count;
42
43 int i, line;
44 int inhdr;
45 char *status;
46 int hasstatus;
47
48 mb = fopen(mailbox, "r");
49 /* Segfault protection if mailbox file doesn't exist. */
50 if(mb == NULL) {
51 printf("***\nSystem error, I can't see mail files.\nPlease inform your sysop - Error 1.\n***\n");
52 return -1;
53 }
54
55 if (lock_fd(fileno(mb)))
56 return -1;
57
58 fseek(mb, 0, SEEK_END);
59 mblen = ftell(mb);
60
61 if (mblen < sysboxlen) {
62 printf("Mailbox changed by another program.\nMailbox not saved.\n");
63 unlock_fd(fileno(mb));
64 fclose(mb);
65 return -1;
66 }
67
68 if (mblen > sysboxlen) {
69 printf("New mail has arrived.\n");
70 havenew = 1;
71
72 /* copy new mail to a temp file, will append to system mailbox later */
73
74 if ((nm = fopen(tempNewMail, "w+")) == NULL)
75 panic("save_mbox: Could not create temporary file");
76
77 fseek(mb, sysboxlen, SEEK_SET);
78
79 while (fgets(buf, LINESIZE, mb) != NULL) {
80 count = strlen(buf);
81 fwrite(buf, sizeof *buf, count, nm);
82 if (ferror(nm))
83 panic("save_mbox: Could not write temporary file");
84 }
85
86 }
87
88 if ((tmp = fopen(tempMail, "r")) == NULL)
89 panic("save_mbox: Could not open temporary mail file");
90
91 if (freopen(mailbox, "w", mb) == NULL)
92 panic("save_mbox: Could not open system mailbox for writing");
93
94 if ((ub = fopen(userbox, "w")) == NULL) {
95 /* error on user mailbox,
96 dump all to the system mailbox as last resort */
97
98 while (fgets(buf, LINESIZE, tmp) != NULL) {
99 count = strlen(buf);
100 fwrite(buf, sizeof *buf, count, mb);
101 if (ferror(mb))
102 panic("save_mbox: Could not write to system mailbox.");
103 }
104 fclose(tmp);
105 if (havenew) {
106 fseek(nm, 0, SEEK_SET);
107 while (fgets(buf, LINESIZE, nm) != NULL) {
108 count = strlen(buf);
109 fwrite(buf, sizeof *buf, count, mb);
110 if (ferror(mb))
111 panic("save_mbox: Could not write to system mailbox.");
112 }
113 fclose(nm);
114 }
115 unlock_fd(fileno(mb));
116 fclose(mb);
117 printf("Could not open user mailbox, dumping to system mailbox\n");
118 return -1;
119 }
120
121 /*
122 we have all processed messages in tmp and
123 any newly arrived (if any) in nm.
124 System mailbox is locked, empty and opened for write (mb),
125 User Mailbox is empty and opened for writing (ub).
126
127 - read message go to ~/mbox with status RO
128 - not read go back to system mailbox with status O
129 - deleted are purged
130 - any arrived go to system mailbox as they are
131 */
132
133 for (i=0; i<messages; i++) {
134 dot = &message[i];
135 if (fseek(tmp, dot->m_offset, SEEK_SET)) {
136 printf("save_mbox: Could not find message %i.\n", i);
137 continue;
138 }
139
140 if (dot->m_flag & MDELETED) {
141 dest = NULL;
142 status = NULL;
143 }
144 else if (dot->m_flag & MREAD) {
145 dest = mb;
146 status = "RO";
147 }
148 else if (dot->m_flag & MNEW) {
149 dest = mb;
150 status = "O";
151 }
152 else {
153 dest = mb;
154 status = NULL;
155 }
156
157 line = 0;
158 hasstatus = 0;
159 inhdr = 1;
160
161 for (;;) {
162 if (!dest) break;
163 if (fgets(buf, LINESIZE, tmp) == NULL) {
164 /* End of file */
165 break;
166 }
167 line ++;
168 if (inhdr) {
169 /* Header */
170 if (!strncasecmp(buf, "Status: ", 8)) {
171 hasstatus = 1;
172 if (status) sprintf(buf, "Status: %s\n", status);
173 } else if (!strcmp("\n", buf)) {
174 inhdr = 0;
175 if (!hasstatus) {
176 if (status) sprintf(buf, "Status: %s\n", status);
177 fwrite(buf, sizeof *buf, strlen(buf), dest);
178 }
179 strcpy(buf, "\n");
180 }
181 } else {
182 /* Data */
183 if (line == dot->m_lines + 1) break;
184 }
185 fwrite(buf, sizeof *buf, strlen(buf), dest);
186 }
187 }
188
189 fclose(tmp);
190
191 if (havenew) {
192 /* append the newly arrived mail */
193 fseek(nm, 0, SEEK_SET);
194 freopen(mailbox, "a+", mb);
195 while (fgets(buf, LINESIZE, nm) != NULL) {
196 count = strlen(buf);
197 fwrite(buf, sizeof *buf, count, mb);
198 if (ferror(mb))
199 panic("save_mbox: Could not write to system mailbox.");
200 }
201
202 fclose(nm);
203 }
204
205 unlock_fd(fileno(mb));
206 fclose(mb);
207 fclose(ub);
208
209 return 0;
210 }
211
212 /* On quit without save: check and announce if new mail has arrived */
213
214 int chk_new_msg(void)
215 {
216 FILE *mb;
217 long mblen=0;
218
219 mb = fopen(mailbox, "r");
220 if (lock_fd(fileno(mb)))
221 return -1;
222
223 fseek(mb, 0, SEEK_END);
224 mblen = ftell(mb);
225
226 if (mblen != sysboxlen) printf("New mail has arrived.\n");
227
228 unlock_fd(fileno(mb));
229 fclose(mb);
230
231 return 0;
232 }
233
234 /* quit. */
235
236 void quit(int save, int code)
237 {
238 if (save) {
239 printf("Exiting, saving changes in mailbox.\n");
240 } else
241 printf("Cancelling changes, mailbox not changed.\n");
242 if (save) {
243 save_mbox();
244 }
245 else
246 chk_new_msg();
247 printf("Bye %s!.. from axMail@%s.\n", username, hostname);
248 cleartmp(tempMail);
249 cleartmp(tempNewMail);
250 cleartmp(tempEdit);
251 cleartmp(tempMesg);
252
253 exit(code);
254 }
255
0 USAGE
1 bye | exit | quit
2
3 DESCRIPTION
4 Any of these commands will exit axMail-FAX and preserve any
5 mail that you haven't killed or deleted.
0
1 #include <pwd.h>
2
3 extern int setpwnam (struct passwd *pwd);
4
0
1 #include <utmp.h>
2 #include "defines.h"
3
4 extern char callsign[20];
5 extern char username[20];
6 extern char fullname[31];
7 extern char forward[79];
8
9 extern char *homedir; /* User's home directory */
10 extern char *fwdfile; /* User's .forward file (~/.forward) */
11 extern char *sigfile; /* User's .signature file (~/.signature) */
12 extern char *maildir; /* User's mail directory (~/mail) */
13 extern char *mailbox; /* System mailbox (/var/spool/mail/user) */
14 extern char *userbox; /* User's mailbox (~/mbox) */
15 extern char *mailconf; /* User's own axmail configuration */
16
17 extern int local; /* Running with user privileges? */
18
19 extern char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */
20 extern char *tempRcpt; /* Temporary files: return receipt */
21 extern char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */
22 extern char *tempEdit;
23 extern char *tempMesg;
24
25 extern char *faxgate; /* Email of your E-Fax Gateway */
26 extern char *hostname;
27 extern char *sysopmail;
28 extern char *def_shell; /* Default settings for autoaccounts */
29 extern char *def_homedir;
30
31 extern int mail_allowed, identification, autocreate, login_allowed;
32 extern int first_uid, last_uid;
33 extern gid_t user_gid;
34 extern char mboxname[PATHSIZE];
35 extern long IdleTimeout;
36
37 struct cmd {
38 char *name;
39 int (*function) (int argc, char **argv);
40 };
41
42 extern struct cmd Mailcmds[];
43
44 extern void tinit(void);
45 extern int read_config(void);
0
1 /* config.c - read configuration */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <pwd.h>
8 #include <grp.h>
9 #include <utmp.h>
10 #include <unistd.h>
11 #include <sys/stat.h>
12
13 #include "config.h"
14 #include "defines.h"
15 #include "axmail.h"
16 #include "utils.h"
17
18 char callsign[20];
19 char username[20];
20 char fullname[31];
21 char *homedir; /* User's home directory */
22 char *maildir; /* User's mail directory (~/mail) */
23 char *mailbox; /* System mailbox (/var/spool/mail/user) */
24 char *userbox; /* User's mailbox (~/mbox) */
25 char *sysopmail; /* Sysop's email address */
26 char *mailconf; /* User's own axmail configuration */
27
28 int local = 0; /* Running with user privileges? */
29
30 char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */
31 char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */
32 char *tempEdit;
33 char *tempMesg;
34 char *tempRcpt;
35
36 char *hostname = NULL;
37 char *def_shell = NULL;
38 char *def_homedir = NULL;
39 char *faxgate = NULL;
40
41 int mail_allowed = 0;
42 int identification = 0;
43
44 int autocreate = FALSE;
45 int login_allowed = FALSE;
46 int first_uid = 400;
47 int last_uid = 65535;
48 gid_t user_gid = 0;
49
50 long IdleTimeout = 900L; /* default to 15 mins */
51
52 static int do_allowmail(int, char **);
53 static int do_autocreate(int, char **);
54 static int do_autogroup(int, char **);
55 static int do_first_uid(int, char **);
56 static int do_homedir(int, char **);
57 static int do_faxgate(int, char **);
58 static int do_hostname(int, char **);
59 static int do_sysopmail(int, char **);
60 static int do_identification(int, char **);
61 static int do_idletimeout(int, char **);
62 static int do_loginallowed(int, char **);
63 static int do_last_uid(int, char **);
64 static int do_shell(int, char **);
65
66 static struct cmd cfg_cmds[] = {
67 { "allowmail", do_allowmail },
68 { "autocreate", do_autocreate },
69 { "autogroup", do_autogroup },
70 { "faxgate", do_faxgate },
71 { "first_uid", do_first_uid },
72 { "homedir", do_homedir },
73 { "hostname", do_hostname },
74 { "identification", do_identification },
75 { "idletimeout", do_idletimeout },
76 { "loginallowed", do_loginallowed },
77 { "last_uid", do_last_uid },
78 { "shell", do_shell },
79 { "sysopmail", do_sysopmail },
80 { NULL, NULL }
81 };
82
83 /* ***************************************************************** */
84
85 static int do_allowmail(int argc, char **argv)
86 {
87 if (argc < 2)
88 return -1;
89 if (!strcasecmp(argv[1], "all"))
90 mail_allowed = 0;
91 else if (!strcasecmp(argv[1], "nologin"))
92 mail_allowed = 1;
93 else if (!strcasecmp(argv[1], "passwd"))
94 mail_allowed = 2;
95 else if (!strcasecmp(argv[1], "axhome"))
96 mail_allowed = 3;
97 else
98 return -1;
99 return 0;
100 }
101
102 static int do_autocreate(int argc, char **argv)
103 {
104 if (argc < 2)
105 return -1;
106 if (!strcasecmp(argv[1], "yes"))
107 autocreate = 1;
108 else
109 autocreate = 0;
110 return 0;
111 }
112
113 static int do_autogroup(int argc, char **argv)
114 {
115 if (argc < 2)
116 return -1;
117
118 user_gid = atoi(argv[1]);
119
120 if (user_gid == 0) {
121 struct group * gp = getgrnam(argv[1]);
122 if (gp != NULL)
123 user_gid = gp->gr_gid;
124 else {
125 printf("Group %s not found.\n", argv[1]);
126 return -1;
127 }
128 endgrent();
129 }
130
131 if (user_gid == 0) {
132 printf("Default GID for new users must be set and non-zero.\n");
133 return -1;
134 }
135 return 0;
136 }
137
138 static int do_faxgate(int argc, char **argv)
139 {
140 if (argc < 2)
141 return -1;
142 faxgate = strdup(argv[1]);
143 return 0;
144 }
145
146 static int do_first_uid(int argc, char **argv)
147 {
148 if (argc < 2)
149 return -1;
150 first_uid = atoi(argv[1]);
151 return 0;
152 }
153
154 static int do_last_uid(int argc, char **argv)
155 {
156 if (argc < 2)
157 return -1;
158 last_uid = atol(argv[1]);
159 return 0;
160 }
161
162 static int do_idletimeout(int argc, char **argv)
163 {
164 if (argc < 2)
165 return -1;
166 IdleTimeout = atol(argv[1]);
167 return 0;
168 }
169
170 static int do_homedir(int argc, char **argv)
171 {
172 if (argc < 2)
173 return -1;
174 def_homedir = strdup(argv[1]);
175 return 0;
176 }
177
178 static int do_hostname(int argc, char **argv)
179 {
180 if (argc < 2)
181 return -1;
182 hostname = strdup(argv[1]);
183 return 0;
184 }
185
186 static int do_sysopmail(int argc, char **argv)
187 {
188 if (argc < 2)
189 return -1;
190 sysopmail = strdup(argv[1]);
191 return 0;
192 }
193
194 static int do_identification(int argc, char **argv)
195 {
196 if (argc < 2)
197 return -1;
198 if (!strcasecmp(argv[1], "none"))
199 identification = 0;
200 else if (!strcasecmp(argv[1], "passwd"))
201 identification = 1;
202 else
203 return -1;
204 return 0;
205 }
206
207 static int do_loginallowed(int argc, char **argv)
208 {
209 if (argc < 2)
210 return -1;
211 if (!strcasecmp(argv[1], "yes"))
212 login_allowed = 1;
213 else if (!strcasecmp(argv[1], "crazy"))
214 login_allowed = 2;
215 else
216 login_allowed = 0;
217 return 0;
218 }
219
220 static int do_shell(int argc, char **argv)
221 {
222 if (argc < 2)
223 return -1;
224 def_shell = strdup(argv[1]);
225 return 0;
226 }
227
228 /* ***************************************************************** */
229
230 /* Set the temporary file names, paths and such, and make sure
231 they're available for us to use... */
232
233 void tinit(void)
234 {
235 int pid;
236 char pat[PATHSIZE];
237 struct stat fst;
238
239 umask(077);
240 pid = getpid();
241
242 sprintf(pat, "%s/mail", homedir);
243 maildir = strdup(pat);
244
245 sprintf(pat, "%s/axM%05d", maildir, pid);
246 tempMail = strdup(pat);
247 sprintf(pat, "%s/axnewM%05d", maildir, pid);
248 tempNewMail = strdup(pat);
249 sprintf(pat, "%s/axE%05d", maildir, pid);
250 tempEdit = strdup(pat);
251 sprintf(pat, "%s/axT%05d", maildir, pid);
252 tempMesg = strdup(pat);
253
254 sprintf(pat, "%s/mbox", homedir);
255 userbox = strdup(pat);
256
257 sprintf(pat, "%s%s", DATA_AXMAIL_MAIL_DIR, username);
258 mailbox = strdup(pat);
259
260 // sprintf(pat, "%s%s", homedir, CONF_AXMAIL_USER_FILE);
261 // mailconf = strdup(pat);
262
263 if (stat(maildir, &fst) < 0) {
264 printf("Creating directory %s...\n", maildir);
265 if (mkdir(maildir, S_IRUSR|S_IWUSR|S_IXUSR))
266 panic("tinit: Cannot create mail directory");
267 }
268 }
269
270 /* Read configuration */
271
272 int read_config(void)
273 {
274 FILE *fp;
275 char line[256];
276 int ret, n = 0;
277
278 if ((fp = fopen(CONF_AXMAIL_FILE, "r")) == NULL) {
279 printf("Cannot read axmail.conf\n");
280 return -1;
281 }
282 while (fgets(line, 256, fp) != NULL) {
283 n++;
284 ret = cmdparse(cfg_cmds, line);
285 if (ret == -1)
286 printf("Syntax error in config file at line %d: %s\n", n, line);
287 if (ret < 0) {
288 fclose(fp);
289 return -1;
290 }
291 }
292 fclose(fp);
293 return 0;
294 }
295
0 USAGE
1 spers
2
3 DESCRIPTION
4 This command sends message. If no mail recipient is specified,
5 then you will be asked. This is a clone of the "Send" command,
6 with initial flags, cc, and bcc prompts disabled. You will still
7 be asked if you wish to receive a delivery receipt since the
8 remote reader isn't given an option to ignore it. Mail will also
9 default as highest priority since it's coming from amateur radio.
10
11 You may enter multiple addresses on each line if you desire too.
12 Separate them with a comma (,). Ex:
13 To: n1uro@email.com, user@foo.net, noone@bar.org
0
1 /*
2 * mbox.c - Read, parse and write the system mailbox
3 *
4 * Much taken from mailx-5.3b, which is
5 * Copyright (c) 1980 Regents of the University of California.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <ctype.h>
11 #include <fcntl.h>
12 #include <syslog.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <string.h>
16
17 #include "mbox.h"
18 #include "utils.h"
19 #include "defines.h"
20 #include "config.h"
21 #include "head.h"
22
23 FILE *mbox; /* Temporary mailbox in /tmp */
24 struct message *message; /* Message list */
25 struct message *dot; /* Current message pointer */
26 int messages = 0; /* Amount of messages in list */
27 int current = 0; /* Current message index */
28 int newm = 0; /* New messages */
29
30 long sysboxlen = 0; /* Length of the system mailbox at reading */
31 /* It will increase if new arrives */
32
33 /* Check if we have this message in the message list yet */
34
35 int havemessage(char *id)
36 {
37 int i;
38
39 for (i = 0; i < messages; i++) {
40 if (!strcmp(message[i].id, id))
41 return 1;
42 }
43
44 return 0;
45 }
46
47 /* Open a temp file by creating and unlinking.
48 Return the open file descriptor. */
49
50 int opentemp(char file[])
51 {
52 int f;
53
54 if ((f = open(file, O_CREAT|O_EXCL|O_RDWR, 0600)) < 0)
55 panic("opentemp: could not open file");
56 remove(file);
57 return f;
58 }
59
60 /* Take the data out of the passed ghost file and toss it into
61 a dynamically allocated message structure. */
62
63 void makemessage(FILE *f)
64 {
65 int size = (messages + 1) * sizeof (struct message);
66
67 if (message != 0)
68 free((char *) message);
69 if ((message = (struct message *) malloc((unsigned) size)) == 0)
70 panic("Insufficient memory for %d messages", messages);
71 dot = message;
72 size -= sizeof (struct message);
73 fflush(f);
74 lseek(fileno(f), (long) sizeof *message, 0);
75 if (read(fileno(f), (char *) message, size) != size)
76 panic("Message temporary file corrupted");
77 message[messages].m_size = 0;
78 message[messages].m_lines = 0;
79 message[messages].receipt = NULL;
80 message[messages].from = NULL;
81 message[messages].date = NULL;
82 message[messages].subj = NULL;
83 message[messages].id = NULL;
84 fclose(f);
85 }
86
87 /* Append the passed message descriptor onto the temp file.
88 If the write fails, return 1, else 0 */
89
90 void append(struct message *mp, FILE *f)
91 {
92 if (fwrite((char *) mp, sizeof *mp, 1, f) != 1)
93 panic("append: Could not append message");
94 }
95
96 /* Copy mailbox from ~/mail/mbox and /var/spool/mail to /tmp
97 (yo2loj - 13 april 2003) */
98
99 int getmail(void)
100 {
101 struct stat stb;
102
103 FILE *ibuf;
104 FILE *mestmp;
105
106 char buf[LINESIZE];
107 int count;
108
109 long offset = 0;
110 int inheader = 0;
111 int maybe = 1;
112 char *cp = NULL;
113 char c;
114
115
116 struct message this = { MUSED|MNEW, 0, 0, 0 };
117
118
119 if ((mbox = fopen(tempMail, "w")) == NULL)
120 panic("getmail: Could not create temporary file");
121
122
123 if ((ibuf = fopen(userbox, "r")) == NULL) goto sysbox;
124
125 if (fstat(fileno(ibuf), &stb) < 0) {
126 printf("Ouch, could not fstat() mailbox.\n");
127 syslog(LOG_NOTICE, "getmail: Could not fstat()");
128 fclose(ibuf);
129 goto sysbox;;
130 }
131
132 switch (stb.st_mode & S_IFMT) {
133 case S_IFREG: /* Good, a regular file */
134 break;
135 default: /* Yuck, i won't eat THAT! */
136 fclose(ibuf);
137 goto sysbox;
138 }
139
140 if (stb.st_size == 0) { /* Zero-sized mailbox? */
141 fclose(ibuf);
142 goto sysbox;;
143 }
144
145 /* copy old read mail */
146
147 while (fgets(buf, LINESIZE, ibuf) != NULL) {
148 count = strlen(buf);
149 fwrite(buf, sizeof *buf, count, mbox);
150 if (ferror(mbox))
151 panic("getmail: Could not write temporary file");
152 }
153
154 fclose(ibuf);
155
156 sysbox:
157 if ((ibuf = fopen(mailbox, "r")) == NULL) goto rdexit;
158
159 if (fstat(fileno(ibuf), &stb) < 0) {
160 printf("Ouch, could not fstat() mailbox.\n");
161 syslog(LOG_NOTICE, "getmail: Could not fstat()");
162 fclose(ibuf);
163 goto rdexit;
164 }
165
166 switch (stb.st_mode & S_IFMT) {
167 case S_IFREG: /* Good, a regular file */
168 break;
169 default: /* Yuck, i won't eat THAT! */
170 fclose(ibuf);
171 goto rdexit;
172 }
173
174 if (stb.st_size == 0) { /* Zero-sized mailbox? */
175 fclose(ibuf);
176 goto rdexit;
177 }
178
179 /* copy unread and new mail */
180
181 while (fgets(buf, LINESIZE, ibuf) != NULL) {
182 count = strlen(buf);
183 fwrite(buf, sizeof *buf, count, mbox);
184 sysboxlen += count;
185 if (ferror(mbox))
186 panic("getmail: Could not write temporary file");
187 }
188
189 fclose(ibuf);
190
191 rdexit:
192 fclose(mbox); /* all mail is now in temp file - digest it! */
193
194 if ((c = opentemp(tempMesg)) < 0)
195 exit(1);
196
197 if ((mestmp = fdopen(c, "r+")) == NULL)
198 panic("getmail: Could not open temporary file");
199
200 if ((mbox = fopen(tempMail, "r")) == NULL)
201 panic("getmail: Could not open temporary file");
202
203
204 for (;;) {
205 if (fgets(buf, LINESIZE, mbox) == NULL) {
206 /* End of file */
207 append(&this, mestmp);
208 makemessage(mestmp);
209 if (fclose(mbox))
210 panic("getmail: Could not close temporary mailbox");
211 return 0;
212 }
213 count = strlen(buf);
214 buf[count - 1] = '\0';
215 if (maybe && buf[0] == 'F' && ishead(buf)) {
216 messages++;
217 newm++;
218 append(&this, mestmp);
219 this.m_flag = MUSED|MNEW;
220 this.m_size = 0;
221 this.m_lines = 0;
222 this.m_offset = offset;
223 this.receipt = NULL;
224 this.subj = NULL;
225 this.from = NULL;
226 this.date = NULL;
227 this.id = NULL;
228 inheader = 1;
229 } else if (buf[0] == 0) {
230 inheader = 0;
231 } else if (inheader) {
232 if (!strncasecmp(buf, "Status: ", 8)) {
233 cp = &buf[8];
234 if (strchr(cp, 'R') != NULL)
235 this.m_flag |= MREAD;
236 if (strchr(cp, 'O') != NULL) {
237 this.m_flag &= ~MNEW;
238 newm--;
239 }
240 }
241
242 if ((!strncasecmp(buf, "Disposition-Notification-To:", 28)) && (this.receipt == NULL)) {
243 cp = &buf[28];
244 while ((*cp) && (isspace(*cp)))
245 cp++;
246 this.receipt = strdup(cp);
247 }
248
249 if ((!strncasecmp(buf, "Subject:", 8)) && (this.subj == NULL)) {
250 cp = &buf[8];
251 while ((*cp) && (isspace(*cp)))
252 cp++;
253 this.subj = strdup(cp);
254 }
255
256 if ((!strncasecmp(buf, "From:", 5)) && (this.from == NULL)) {
257 cp = &buf[5];
258 while ((*cp) && (isspace(*cp)))
259 cp++;
260 this.from = strdup(cp);
261 }
262
263 if ((!strncasecmp(buf, "Date:", 5)) && (this.date == NULL)) {
264 cp = &buf[5];
265 while ((*cp) && (isspace(*cp)))
266 cp++;
267 this.date = strdup(cp);
268 }
269
270 if ((!strncasecmp(buf, "Message-ID:", 11)) && (this.id == NULL)) {
271 cp = &buf[11];
272 while ((*cp) && (isspace(*cp)))
273 cp++;
274 this.id = strdup(cp);
275 }
276 }
277 offset += count;
278 this.m_size += count;
279 this.m_lines++;
280 maybe = buf[0] == 0;
281
282 }
283
284
285 return 0;
286 }
287
288 /* Read a message */
289
290 int readmesg(int msg, int verbose)
291 {
292 int i, line = 0;
293 int inhdr = 1;
294 char buf[LINESIZE];
295 if ((msg < 1) || (msg > messages)) {
296 printf("There's no message %i.\n", msg);
297 return -1;
298 }
299
300 if ((mbox = fopen(tempMail, "r")) == NULL) {
301 printf("Could not open temporary mailbox.\n");
302 return -1;
303 }
304
305 i = msg - 1;
306 dot = &message[i];
307
308 if (fseek(mbox, dot->m_offset, SEEK_SET)) {
309 printf("readmesg: Could not fseek to message %i.\n", msg);
310 return -1;
311 }
312
313 current = msg;
314
315 printf("Message %i:%s%s%s\n", msg,
316 ((dot->m_flag & (MREAD|MNEW)) == MNEW) ? " (New)" : "",
317 ((dot->m_flag & (MREAD|MNEW)) == 0) ? " (Unread)": "",
318 ((dot->m_flag & (MDELETED)) == MDELETED) ? " (Deleted)" : ""
319 );
320
321 dot->m_flag |= MREAD;
322 dot->m_flag ^= (dot->m_flag & MNEW);
323
324 for (;;) {
325 if (fgets(buf, LINESIZE, mbox) == NULL) {
326 /* End of file */
327 fclose(mbox);
328 return 0;
329 }
330 line++;
331 if (inhdr) {
332 /* Headers */
333 if (((verbose) && (line != 1) && (strncasecmp(buf, "Status: ", 8)) && (strncasecmp(buf, "X-Status: ", 10)) ) ||
334 (!strncasecmp(buf, "Date:", 5)) ||
335 (!strncasecmp(buf, "From:", 5)) ||
336 (!strncasecmp(buf, "To:", 3)) ||
337 (!strncasecmp(buf, "Cc:", 3)) ||
338 // (!strncasecmp(buf, "Disposition-Notification-To:", 3)) ||
339 (!strncasecmp(buf, "Subject:", 8)))
340 printf("%s", buf);
341
342 if (!strcmp("\n", buf)) {
343 inhdr = 0;
344 }
345 } else {
346 /* Data */
347 if (line == dot->m_lines) {
348 fclose(mbox);
349 return 0;
350 }
351 printf("%s", buf);
352 }
353
354 }
355 return 0;
356
357 }
0 /*
1 * flag bits.
2 */
3
4 #define MUSED (1<<0) /* entry is used, but this bit isn't */
5 #define MDELETED (1<<1) /* entry has been deleted */
6 #define MSAVED (1<<2) /* entry has been saved */
7 #define MTOUCH (1<<3) /* entry has been noticed */
8 #define MPRESERVE (1<<4) /* keep entry in sys mailbox */
9 #define MMARK (1<<5) /* message is marked! */
10 #define MODIFY (1<<6) /* message has been modified */
11 #define MNEW (1<<7) /* message has never been seen */
12 #define MREAD (1<<8) /* message has been read sometime. */
13 #define MSTATUS (1<<9) /* message status has changed */
14
15 /*
16 * Structure used in the message list
17 */
18
19 struct message {
20 short m_flag; /* flags, see below */
21 long m_offset; /* offset of message */
22 long m_size; /* Bytes in the message */
23 short m_lines; /* Lines in the message */
24 char *receipt; /* Receipt request */
25 char *notify; /* Delivery notify */
26 char *from; /* From */
27 char *date; /* Date string */
28 char *subj; /* Subject line */
29 char *id; /* Message ID */
30 char *whoti; /* Who to send a fax to */
31 char *phone; /* Phone to fax */
32 char *note; /* Note for fax cover */
33 };
34
35 extern FILE *mbox; /* Temporary mailbox in /tmp */
36 extern struct message *message; /* Message list */
37 extern struct message *dot; /* Current message pointer */
38 extern int messages; /* Amount of messages in list */
39 extern int current; /* Current message index */
40 extern int newm; /* New messages */
41
42 extern long sysboxlen; /* System mailbox length at start */
43
44 extern int getmail(void);
45 extern int readmesg(int msg, int verbose);
0 all: axmail
1
2 MAN_DIR = /usr/local/share/man
3 CC = gcc
4 LD = gcc
5 CFLAGS = -O2 -Wstrict-prototypes -g -I../lib
6 LIBS = -lcrypt
7 MODULES = utils.o config.o adduser.o command.o mailcmd.o mbox.o head.o lock.o axmail.o quit.o
8
9 .c.o:
10 $(CC) $(CFLAGS) -c $<
11
12 upgrade: installbin installhelp installman
13
14 install: installbin installconf installhelp installman
15
16 installbin: all
17 install -m 0755 -s -o root -g root axmail /usr/local/sbin
18
19 installconf:
20 install -m 755 -o root -g root -d /usr/local/etc/ax25
21 install -b -m 644 -o root -g root etc/axmail.conf /usr/local/etc/ax25
22 install -m 644 -o root -g root etc/welcome.txt /usr/local/etc/ax25
23
24 installhelp:
25 install -m 755 -o root -g root -d /usr/local/var/ax25/axmail/help
26 install -m 644 -o root -g root etc/help/*.hlp /usr/local/var/ax25/axmail/help
27
28 installman:
29 install -m 644 -p man/axmail.8 $(MAN_DIR)/man8
30 install -m 644 -p man/axmail.conf.5 $(MAN_DIR)/man5
31 back:
32 rm -f ../mail.tar.gz
33 tar cvf ../mail.tar *
34 gzip ../mail.tar
35
36 clean:
37 rm -f axmail *.o *~ *.bak core etc/*~ etc/help/*~
38
39 distclean: clean
40 rm -f axmail
41
42 axmail: $(MODULES)
43 $(LD) -o axmail $(MODULES) $(LIBS) $(LDFLAGS)
44
45 utils.o: utils.h utils.c mbox.h
46 config.o: config.h config.c defines.h axmail.h utils.h
47 adduser.o: adduser.h adduser.c utils.h config.h defines.h
48 command.o: command.h command.c config.h mailcmd.h mbox.h utils.h quit.h
49 mailcmd.o: mailcmd.h mailcmd.c defines.h utils.h mbox.h config.h
50 mbox.o: mbox.h mbox.c utils.h defines.h config.h head.h
51 head.o: head.h head.c defines.h
52 utils.o: utils.h utils.c
53 lock.o: lock.h lock.c utils.h
54 quit.o: quit.h quit.c config.h lock.h
55 axmail.o: axmail.h axmail.c config.h adduser.h utils.h quit.h mbox.h
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.11.1"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2020 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 USAGE
1 read <msg #>
2
3 DESCRIPTION
4 Use this command to read your mail. This command requires a
5 parameter of a message number to read. Ex: to read your mail
6 message 3 you would enter: R 3.
0 This is an SMTP mail agent node plug-in for packet radio systems
1 using linuxnode or URONode.
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axMail 2.12.1
27 Updated January 17, 2021
28 - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail
29 to honor linux file system rules.
30 - Changed defines.h to reflect this version.
31 axMail 2.12
32 Updated August 17, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
33 - After fussing with an updated ClamSMTP system that appears to have some
34 issues at least in regards to the Debian repositories I have come to
35 learn that the MTA used (postfix) beginning with version 2.3 now may
36 use milter (mail filter) systems. Details on how to configure the newer
37 ClamAV-Milter system are at https://uronode.n1uro.com/linux/ under the
38 ClamSMTP link at the bottom of the page. This is quite a major enhancement
39 to axMail-Fax!
40
41 Since now it will scan for either clamsmtp OR clamav-milter the outputs
42 on mails show only that the mail has been scanned by ClamAV.
43 axMail 2.11.1
44 Updated February 21, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
45 - removed the #ifdef CLAMSMTP routine from config.h
46 - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer
47 needs to be previously defined in config.h and auto senses now in mailcmd.c.
48 It dawned on me that the reason it was segfaulting if there was no .conf
49 file that trying to fclose() a file that did not exist was the reason that
50 it was causing axmail to segfault.
51 - made this version 2.11.1 in defines.h.
52 - updated INSTALL and README to reflect history and instructions.
53 - updated Makefile so make upgrade does not replace config files since
54 it's not required if you're simply upgrading from axmail-2.9 or greater.
55 axmail 2.11
56 Updated February 18, 2020 by Brian Rogers (N1URO) <n1uro@n1uro.net>
57 - Figured out how to add ClamSMTP to the mail system's MTA. Details
58 are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml
59 This will scan for viri both IN and OUT bound mails! Very handy!
60 - Added a define routine in config.h now. You must #define or #undef
61 CLAMSMTP based on whether or not you're running clamsmtp and have
62 /etc/clamsmtpd.conf in existance. If it's elsewhere on your system
63 create a symlink to it and you'll be fine.
64 - added the fact when #defined where mails are tagged with the fact that
65 your mail is being scanned by CLAMSMTP. This was done in mailcmd.c
66 - upped the version to 2.11 in defines.h
67 - added notes in INSTALL in regards to the new #define in config.h
68 axmail 2.10
69 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
70 - added online help for the "Delivery Receipt" command. This keeps
71 it in line with all the other online helps.
72 - modified defines.h with this version number and also increased the
73 year that I'm still working on modifications to the project.
74 axmail 2.9
75 Updated March, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
76 - Removed asking for password upon new user login, instead added a new
77 field to axmail.conf for "SysopMail". Now the sysop has to put in their
78 email address as to inform the end user to request their desired password
79 into the system, especially if the sysop is running pop/imap features on
80 their system. This will prevent users from entering in plain text passwords
81 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
82 a major security fix for axMail-FAX.
83 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
84 another program changed the user's mail spool file the warning displays
85 clearer.
86 - changed version number to 2.9 in defines.h and changed the end year of
87 maintenance from 2017 to 2018.
88
89 axmail 2.8
90 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
91 Changes:
92 - added SPers as a command per the suggestion of VE1JOT. This was done in
93 command.c and was actually quite simple to impliment. The logic behind
94 it is to match the mail send command sets with those of standard PBBS
95 messaging commands.
96 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
97 urged that flags, cc, and bcc options be supressed to make it more user
98 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
99 do have compassion for those on HF. Steve gave me a different idea than
100 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
101 and command.c. If one needs a read receipt or to send cc/bcc copies of
102 their message then S still is an option.
103 - added a "spers" .hlp file to the archive.
104 - changed defines.h to reflect version 2.8.
105 - updated welcome.txt to be more generic rather than be version specific.
106 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
107 mail. This allows for a duplicate of the message to be sent to the second
108 person one wishes to copy on the mail.
109 - edited this file.
110 - while I was at it, I decided to add a "blind carbon copy" feature.
111 This will send a copy of a message to the user specified HOWEVER,
112 they will NOT be listed in the recipient listings. For those using
113 raw terminals, it's possible to NOT enter a 'cc' but still enter a
114 'bcc' address.
115 - edited help files: send.hlp and spersonal.hlp to help guide users
116 on how to best send mail.
117 - created a bypass method so that if users did not wish to use cc or bcc
118 mail, they can bypass them instead of being prompted for them - suggested
119 by VE1JOT.
120 - added online help for send/sp|cc|bcc mail.
121 - added a new signature file function to the system in both command.c and in
122 mailcmd.c. If no signature file exists, it will instruct the user on this
123 fact and also inform them how to make one using the new SIgnature command.
124 Note: If no ~/.signature file exists mail will still be sent, just without
125 a 1 line siguature (max: 79 characters).
126 - bullet proofed both the autoforward and signature file routines in command.c
127 by insuring that a null string not only halts execution of both but also
128 removes both ~/.forward and ~/.signature files respectively.
129 - cleaned up the send signature a bit and added my little spam ad even if
130 there is no signature file present. This was done in mailcmd.c.
131 - added a string in the signature prompt which informs users how to clear
132 their signature if they desire such. This was done in utils.c
133 - Added special critical instructions to INSTALL. I didn't know if I had
134 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
135 - Fixed a bug that when the mailbox file(s) weren't found for the system
136 MTA (aka: postfix) axMail would segfault. Now not only does it not
137 segfault but also instructs the user to inform the sysop of this error.
138 This bug existed since version 0.0.1. I've been wanting to do something
139 about this for IONs but didn't get to it until now. This was done in quit.c
140 - Fixed a couple of typos in README. I have a very difficult keyboard!
141 - Per the suggestion of G4APL (who gives us many great ideas - and why do
142 I refer to myself in plural? I need a DIET!) I did two things:
143 1 - when listing mail there's no message date stamp within the listing.
144 added in mailcmd.c
145 2 - reordered the mail listing fields where I felt they'd make the most
146 sense. Message subject, then message date, then message size are
147 the last 3 fields listed. They should also be kept in a column
148 justified manner of sorts.
149 3 - added a (St)atus header so the user has a better definition of
150 the status of a specific message.
151
152 axmail 2.7
153 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
154 Changes:
155 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
156 the user entered a parameter such as a message number for example,
157 it wouldn't properly function. This has been fixed. Thanks Van!
158 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
159 - I know in the past I had a 'cc' command for sending mail, and it's
160 been suck in my craw to readd it since.
161
162 axmail 2.6
163 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
164 Changes:
165 - changed version number in defines.h
166 - fixed error message when a pop client has deleted mail from the
167 main mail spool file.
168 - removed excessive receipt warning spotted by a gent who identifies
169 himself as rigor. This was in mailcmd.c in do_readmsg()
170 - while looking at the end of that routine, it just gave me an itch that
171 said "if you can look for a warning about a requested receipt, then
172 numbnutz you can offer the reader a chance to just generate a receipt
173 without having to do "SR" as previously stated at the end of the mail.
174 So, with that said and to get feeling back in my genitals, I wrote a
175 routine that asks the reader if they wish to send a receipt, and it
176 also echos where it's destined and confirmation it was sent.
177 - added an "--- end of message #* ---" tag at the end of mail when it
178 as finished displaying. This was done in mailcmd.c
179 - fixed an existing bug in the message routines where for each message
180 it wasn't resetting the receipt pointer! This bug existed since I
181 introduced the receipt "finder" in the messages. I'm shocked that
182 it wasn't reported to me by someone earlier. Now *only* if a message
183 has requested a receipt will it show that a receipt has been asked
184 for... whew!
185 - So many missing online help files! Again I'm surprised no one brought
186 this to my attention. How did we get along with them? "Oh my!" - Sulu
187 - Updated this README file.
188
189 axmail v2.5.1
190 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
191 Changes:
192 - added axmail.8 man page as per spec of Debian downstream.
193 - modified Makefile to include axmail.8 manpage installation for both
194 new and upgrade options.
195 - modified defines.h and this document to reflect maintenance release.
196
197 axmail v2.5
198 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
199 Changes:
200 - added new delivery receipt function to the send routine. This
201 compliments the read receipt function in the event of high
202 priority mail. Typically the read receipt is an option generated
203 by the recipient who may not decide to generate one. At least this
204 modification ensures with an ESMTP delivery that the sender using
205 axMail will get a reciept from "MAILER-DAEMON" which will verify
206 the status of delivered mail. This change was done in mailcmd.c
207 and is designed with the sendmail binary included with postfix.
208 - updated this README file.
209 - updated version number in defines.h
210
211 axmail v2.4
212 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
213 Changes:
214 - cleaned up mbox.c where I had originally placed the receipt checker
215 routine in. This caused loops within the buffer that displayed the
216 message. The true routine lives in mailcmd.c
217 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
218 downstream compiles to make packages.
219 - changed version in defines.h
220 - major change in command.c, added a new Autofwd command to allow users to
221 auto-forward mail from a remote system to their "home" axMail-FAX base
222 system. Could also be used to forward mail to their internet accounts.
223 - added autofwd.hlp file.
224 - alphabetized the commandset listing, removed redundantly spelled commands.
225 - reworked Makefile and added an "upgrade" option so new files ONLY are
226 deployed after make. Execute using: "make upgrade"
227 - updated this file.
228
229 axmail v2.3.1
230 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
231 Changes:
232 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
233 message, a bell and a warning sign is generated after the message has been
234 read by the user with instructions to use SR to generate a receipt. This
235 was a difficult routine for me to think of considering the various race
236 conditions that can be expected and met.
237 - updated welcome.txt with version upgrade and new feature list.
238 - updated README.
239
240 axmail v2.3
241 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
242 Changes:
243 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
244 This defaults to NO but when flagged to YES, a request will be sent to the
245 remote client's agent. If the agent supports such, they will be prompted
246 whether or not to honor your receipt request. This is history as NO AGENT
247 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
248 receipt is similar to how HylaFax generates confirmation of transmission
249 receipt mails to your mailbox. Currently mail read in axMail will NOT
250 generate a receipt back. I may work on this later, but for now it doesn't
251 exist.
252 * My thoughts of the receipt function is negative. The fact that I may be
253 sending notification that I'm in my email client to a remote destination
254 IMHO is such that a webcam may as well be turned on and watch me do email,
255 and send the stream to "Big Brother" and I don't mean the television show.
256 </rant>
257 - Updated defines.h with the new version number.
258 - Updated welcome.txt so the new version number is displayed.
259
260 axmail v2.2
261 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
262 Changes:
263 - Made some maintenance changes, but forgot to log them in here.
264 axmail v2.1.1
265 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
266 Changes:
267 - Makefile
268 Code provided by Bob Tenty VE3TOK to make it more compatable
269 with newer GCC compiler requirements.
270 - utils.c
271 Code provided by Bob Tenty VE3TOK to fix a warning produced when
272 compiling.
273 - defines.h
274 Changed version number to reflect the changes incorporated by
275 Bob Tenty VE3TOK and committed to the subversion repository.
276
277 axmail v2.1
278 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
279 Changes:
280 - axmail.c
281 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
282 the system privilege matching.
283 - global
284 axMail is now under review for considerations as standard packaging in
285 RedHat's fedora project. It appears it's going to be added as a package.
286
287 axmail v2.0
288 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
289 Changes:
290 - defines.h
291 Updated version number to reflect version release 2.0. Version 1.0.5
292 was simply a maintenance test package to try and reincorporate what
293 I had done up to version 1.0.6 which I believe was one of my last
294 releases up to 2009. Since I've done all that I can recall at this
295 point and time, I decided to match URONode's release numerics with
296 a 2.0 release version.
297
298 axmail v1.0.5
299 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
300 Changes:
301 - defines.h
302 Updated email listings to reflect the most current ones I could find
303 including my own. Also added 2013 to the years worked on axMail by
304 me.
305 - quit.c
306 Forced ALL mail, read or otherwise when user quits to save to the
307 user's system mailbox. This is for reverse compatability with those
308 who may also run a web-based email service on the internet such as
309 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
310 any read mail (and all accompanying mail in that session) to the
311 axmail ~/mbox file. We don't want this for the specific reason of
312 "reverse email client" compatability.
313
314 axmail v1.0.4
315 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
316 Changes:
317 - setpwnam.c
318 Changed the way SIGPIPE was handled. Instead of being ignored, it will
319 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
320 a shell prompt, or a node frontend. I've been noticing especially on
321 some timeouts that temp files don't flush as they should and the
322 user's directory can start to fill up.
323
324 axMail v1.0.3
325 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
326 Changes:
327 - mailcmd.c
328 Reset the way I wanted to handle the user input routine for sending faxes.
329 Commented out some more unneeded/unused code in the do_fax routine... will
330 clean it up in next release or so.
331 - mailcmd.c
332 cleaned up a bug I introduced in the never released 1.0.2 where the
333 X-Mailer was duping itself after each line of the body of a message.
334 - sfax.hlp
335 Reworded the SFax help file to help show some examples of how to format
336 the header.
337
338 axMail v1.0.2
339 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
340 Changes:
341 - mailcmd.c
342 Cleaned up some of the code in SFax. Also made some cosmetic changes.
343
344 axMail v1.0.1
345 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
346 Changes:
347 - mailcmd.c
348 Added a new routine to allow users to send faxes. This is defined by the
349 command "SF" for Send Fax. The routine was taken from the "S"end function
350 however since it's a one-way transmission, there is no reply available
351 nor is there an option for users to fax to any fax service as some I know
352 are pay services.
353 - config.h
354 added definitions for faxgate in axmail.conf
355 - config.c
356 added routine to allow for faxgate as a variable and be called from
357 mailcmd.c
358 - defines.h
359 version upgraded from v1.0.0 (unreleased - test version) to
360 v1.0.1
361 - etc/axmail.conf
362 Added new line called "FaxGate" with an example of how to properly
363 configure this line.
364 - etc/help/sfax.hlp
365 Added new file "sfax.hlp" which is an online help file for the SFax
366 command.
367
368 axMail v0.0.9
369 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
370 Changes:
371 - mailcmd.c
372 Added a new routine that prompts the sender whether or not the message
373 is of an emergency/high priority mail message. If it's emergency message
374 then the headers are appended with an X-code flagged in such a manner
375 that Eudora and Outlook will display the received mail with a red flag
376 of sorts. The idea of such came to me in thinking of "what can I do
377 to help improve means of emergency communications using TCP/IP, Linux,
378 and packet radio?" Having the ability to "red flag" an SMTP message
379 I don't believe has yet to be available in any packet messaging
380 system... axMail I hope is the first.
381
382 If a user just hits enter, or selects "no" then the mail message
383 is sent under normal send routines.
384
385 found a minor bug in my routine where if an end user answered
386 "yes" in wanting to send an emergency/high priority message the system
387 ignored the request and sent it as 'normal' delivery. Made a minor
388 change to bullet-proof the responce.
389
390 Added online help text if user is unsure about sending a message
391 flagged urgent or normal. This text is available when the user is
392 prompted for priority selection by hitting "?" at the prompt.
393 - defines.h
394 Version updated from v0.0.8 to v0.0.9
395
396 axMail v0.0.8
397 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
398
399 Changes:
400 - mailcmd.c
401 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
402 it's version number in the X-Mailer: string.
403 - mailcmd.c
404 Added an X-Origin: string to show those peeking at mail headers
405 just how the message was possibly sent... by AMATEUR RADIO!
406 - axmail.conf
407 Added config option in "AllowMail" for axhome, a rewrite of code
408 submitted by Stefano IW3IJQ. While I stripped out home directory
409 structures similar to that of qmail or axspawn, Stefano convinced
410 me that it may be easier to manage home directories for axMail users
411 who don't have shell access to branch out within a preset directory.
412 - defines.h
413 Updated version number from 0.0.7 to 0.0.8
414 - axmail.c and config.c
415 Rewrote and incorporated code to allow for the routines to use
416 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
417 While I was at it, I rewrote and shortened the error text pushed
418 to a user who doesn't have permission to use such a directory.
419 * Note: When I write error texts and menus, I try to write them for
420 users on a multi-hop 1200 baud path thus the shorter the better as
421 long as context isn't lost and for long distance hops where full
422 paclen may cause retries (worse yet timeouts!)
423
424 axMail v0.0.7
425
426 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
427
428 Changes:
429 - cosmetics
430 My usual "I like seeing this this way" type cosmetics... too many
431 to mention!
432 - adduser.c
433 changed the hard coding of user 'home' directories so that instead
434 of them going into a period delimited sort, just dump em all into
435 /home/<user> which seems to be "the norm" on most systems I've had
436 to assist with.
437 - adduser.c
438 fixed a bug where creating a user was actually causing the program to
439 segfault upon exit the first time a user went into the mailbox! The
440 node frontends hid this segfault as the program still flushed itself
441 from ram but I spotted it when running it at a command prompt. The
442 segfault came when axMail attempted to write mail back to the user's
443 system mailbox and it didn't exist. How I fixed this is listed next.
444 This may just be a new bug that appeared with the upgrading of libs,
445 this I'm unsure of and since I have no desire to go backwards I have
446 decided to actually make a minor routine...
447 - welcome.txt
448 New users are now sent a "welcome" message that the sysop can easily
449 customize to their desires. It's located at /etc/ax25/welcome.txt.
450 I figured that since axMail was segfaulting because such a file did
451 not exist, I might as well make use of this need by having the program
452 send the user a greeting.
453 - defines.h
454 Changed paths to be more in line with the more modern type configs
455 as a default. Paths can still be defined by the sysop prior to
456 compiling axMail.
457 - Makefile
458 I changed the default of make install to include all of the subroutines
459 within the Makefile yet leaving such things as "make installbin"
460 available as runtime options if just a binary refresh creation is
461 desired.
462 - other
463 I'm sure I missed a note or two *shrug*
464
465 axMail v0.0.6
466
467 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
468 I at one time had but lost and can't seem to find it. My (n1uro)
469 changes may have alread been incorporated.
470
471 axMail v0.0.5
472
473 True mailbox functionalities created by Marius Petrescu.
474 Added Mailbox save routines (compatible with the command line
475 mail agent, including ~/mbox file)
476
477 axMail v0.0.4
478
479 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
480
481 This program is free software; you can redistribute it and/or modify
482 it under the terms of the GNU General Public License as published by
483 the Free Software Foundation; either version 2 of the License, or
484 (at your option) any later version.
485
486 This program is distributed in the hope that it will be useful,
487 but WITHOUT ANY WARRANTY; without even the implied warranty of
488 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
489 GNU General Public License for more details.
490
491 You should have received a copy of the GNU General Public License
492 along with this program; if not, write to the Free Software
493 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
494
495
496 Don't give this one to anyone yet... it is NOT ready for distribution!
497
498 This is a simple mail user agent intended to provide the
499 mail functions in xNOS in a Linux ax.25 environment. If required,
500 it creates a normal user account for each new user (code mostly taken
501 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
502 on the system. axMail uses sendmail (or similar) to deliver mail, and
503 reads mail from each user's system mailbox (/var/spool/mail/username).
504 It does not provide any means of transferring mail between hosts.
505
506 axMail provides a simple, low-overhead user interface, much similar
507 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
508 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
509
510 axMail is intended to be called from node. It takes one command
511 line argument of the user's callsign (with or without SSID). It must
512 be run as root, but it setuid()'s itself to the respective user's
513 privileges as soon as possible. It might run from ax25d as well.
514 It can also be executed from a shell with user privileges.
515
516 Some code (command parser, configuration file stuff) and the internal
517 architecture was taken from the LinuxNode frontend by Tomi Manninen
518 (OH2BNS). Thanks!
519
520 INSTALLATION:
521
522 See the file: INSTALL
523
524 TODO:
525 Suggestions?
526
527 --
528 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
529 ftp://ftp.n1uro.net/pub/hamradio/packet
0
1 /* adduser.c - create an user account (yecch) */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <strings.h>
6 #include <pwd.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <sys/file.h>
10 #include <errno.h>
11 #include <crypt.h>
12 #include <string.h>
13
14 #include "adduser.h"
15 #include "utils.h"
16 #include "config.h"
17 #include "defines.h"
18
19 /* Ask for a new password, and keep it sane */
20
21 void get_passwd(char *newuser, char *passw)
22 {
23 printf("Please email %s with your callsign and desired password.\n", sysopmail);
24
25 /* char passi[12]; */
26
27 //repass: /* Get password */
28 // getstr(passi, 10, "Enter password for the new account (6-8 characters, ? for help): ");
29 //
30 // if (!strcmp(passi, "?")) {
31 // printf("Your password must be 6 to 8 characters long, and it may not be the same as\n");
32 // printf("your login name (in this case, your callsign).\n");
33 // goto repass;
34 // }
35 // if ((strlen(passi) > 8) || (strlen(passi) < 6)) {
36 // printf("Password must be 6-8 characters long.\n");
37 // goto repass;
38 // }
39 // if (!strcasecmp(passi, newuser)) {
40 // printf("Password may not be your login name (callsign).\n");
41 // goto repass;
42 // }
43
44 /* Crypt password */
45 // strcpy(passw, crypt(passi, "ax")); /* Okay, salt _should_ be random... */
46 }
47
48 /* add a new user to /etc/passwd and do some init */
49
50 int new_user(char *newuser)
51 {
52 struct passwd pw, *pwp;
53 uid_t uid;
54 FILE *fp;
55 char homedir[256], userdir[256];
56 char buf[4096];
57 char subdir[4];
58 char passw[20];
59 char str[LINESIZE + 1];
60 int cnt = 0;
61 unsigned char *p, *q;
62 struct stat fst;
63 int fd_a, fd_b, fd_l;
64
65 /* Build path for home directory */
66
67 strncpy(subdir, newuser, 3);
68 subdir[3] = '\0';
69 sprintf(homedir, "%s/%s", def_homedir, newuser);
70 strcpy(userdir, homedir);
71
72 getname(fullname);
73
74 if (strlen(fullname) == 0) {
75 printf("Okay, using your callsign as your name. You may change it later.\n");
76 strcpy(fullname, newuser);
77 }
78
79 /* Get password */
80
81 switch (login_allowed) {
82 case 0: strcpy(passw, "*");
83 break;
84 case 1: get_passwd(newuser, passw);
85 break;
86 case 2: strcpy(passw, ""); /* Yuck! */
87 break;
88 }
89
90 /* Lock */
91 fd_l = open(LOCK_AXMAIL_FILE, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
92 flock(fd_l, LOCK_EX);
93
94 retry:
95 /* Find first free UID */
96 cnt++;
97
98 for (uid = first_uid; uid < 65535; uid++)
99 {
100 pwp = getpwuid(uid);
101 if (pwp == NULL)
102 break;
103 }
104
105 if (uid >= 65535 || uid < first_uid)
106 return -1;
107
108 /* build directories for home */
109
110 p = homedir;
111
112 while (*p == '/') p++;
113
114 chdir("/");
115
116 while(p)
117 {
118 q = strchr(p, '/');
119 if (q)
120 {
121 *q = '\0';
122 q++;
123 while (*q == '/') q++;
124 if (*q == 0) q = NULL;
125 }
126
127 if (stat(p, &fst) < 0)
128 {
129 if (errno == ENOENT)
130 {
131 mkdir(p, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
132
133 if (q == NULL)
134 {
135 chown(p, uid, user_gid);
136 chmod(p, S_IRUSR|S_IWUSR|S_IXUSR);
137 }
138 }
139 else
140 return -1;
141 }
142
143 if (chdir(p) < 0)
144 return -1;
145 p = q;
146 }
147
148 /* Add the user now */
149
150 fp = fopen(PASSWDFILE, "a+");
151 if (fp == NULL)
152 return -1;
153
154 pw.pw_name = newuser;
155 pw.pw_passwd = passw;
156 pw.pw_uid = uid;
157 pw.pw_gid = user_gid;
158 pw.pw_gecos = fullname;
159 pw.pw_dir = userdir;
160 pw.pw_shell = def_shell;
161
162 if ((getpwuid(uid) != NULL) && (cnt <= 10)) goto retry; /* oops?! */
163
164 if ((putpwent(&pw, fp) < 0) || (cnt > 10))
165 return -1;
166
167 flock(fd_l, LOCK_UN);
168 fclose(fp);
169
170 /* Copy ax25.profile */
171
172 fd_a = open(CONF_AXMAIL_PROF_FILE, O_RDONLY);
173
174 if (fd_a > 0)
175 {
176 fd_b = open(USERPROFILE, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IXUSR);
177
178 if (fd_b < 0)
179 return -1;
180
181 while ( (cnt = read(fd_a, &buf, sizeof(buf))) > 0 )
182 write(fd_b, &buf, cnt);
183 close(fd_b);
184 close(fd_a);
185 chown(USERPROFILE, uid, user_gid);
186
187 }
188 /* Be nice and send the new user a welcome message :) */
189
190 sprintf(str, "%s -oem %s@%s < %s", BIN_AXMAIL_SENDMAIL, newuser, hostname, WELCOME);
191 system(str);
192 return 0;
193 }
194
0
1 /*
2 * defines.h - Compile-time configuration
3 */
4
5 #define VERSION "axMail-Fax v2.12"
6 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2020 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
7 #define PROMPT "=> "
8
9 #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf"
10 #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile"
11 // #define CONF_AXMAIL_USER_FILE ".axmailrc"
12 #define DATA_AXMAIL_HELP_DIR "/usr/local/var/ax25/axmail/help/"
13 #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/"
14 #define LOCK_AXMAIL_FILE "/var/lock/axmail"
15 #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail"
16
17
18 #define FORWARDFILE ".forward"
19 #define SIGNATUREFILE ".signature"
20 #define USERPROFILE ".profile"
21 #define PASSWDFILE "/etc/passwd"
22
23 #define WELCOME "/usr/local/etc/ax25/welcome.txt"
24
25 #define PATHSIZE 1024
26 #define LINESIZE 1024 /* Maximum length of a line in a message */
27
28 #define TRUE 1
29 #define FALSE 0
30
31 #define LICENSE "\n This program is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation; either version 2 of the License, or\n (at your option) any later version. Usage may vary based on location.\n\n"
0 /* axmail.c - The command parser and main function */
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <unistd.h>
7 #include <signal.h>
8 #include <time.h>
9 #include <syslog.h>
10 #include <pwd.h>
11 #include <crypt.h>
12 #include <error.h>
13
14 #include "config.h"
15 #include "axmail.h"
16 #include "utils.h"
17 #include "adduser.h"
18 #include "quit.h"
19 #include "mbox.h"
20
21 /* Parse c-style escapes (neat to have!) */
22
23 static char *parse_string(char *str)
24 {
25 char *cp = str;
26 unsigned long num;
27
28 while (*str != '\0' && *str != '\"') {
29 if (*str == '\\') {
30 str++;
31 switch (*str++) {
32 case 'n':
33 *cp++ = '\n';
34 break;
35 case 't':
36 *cp++ = '\t';
37 break;
38 case 'v':
39 *cp++ = '\v';
40 break;
41 case 'b':
42 *cp++ = '\b';
43 break;
44 case 'r':
45 *cp++ = '\r';
46 break;
47 case 'f':
48 *cp++ = '\f';
49 break;
50 case 'a':
51 *cp++ = '\007';
52 break;
53 case '\\':
54 *cp++ = '\\';
55 break;
56 case '\"':
57 *cp++ = '\"';
58 break;
59 case 'x':
60 num = strtoul(--str, &str, 16);
61 *cp++ = (char) num;
62 break;
63 case '0':
64 case '1':
65 case '2':
66 case '3':
67 case '4':
68 case '5':
69 case '6':
70 case '7':
71 num = strtoul(--str, &str, 8);
72 *cp++ = (char) num;
73 break;
74 case '\0':
75 return NULL;
76 default:
77 *cp++ = *(str - 1);
78 break;
79 };
80 } else {
81 *cp++ = *str++;
82 }
83 }
84 if (*str == '\"')
85 str++; /* skip final quote */
86 *cp = '\0'; /* terminate string */
87 return str;
88 }
89
90 /* Parse command line to argv, honoring quotes and such */
91
92 int parse_args(char *argv[],char *cmd)
93 {
94 int ct = 0;
95 int quoted;
96
97 while (ct < 31)
98 {
99 quoted = 0;
100 while (*cmd && isspace(*cmd))
101 cmd++;
102 if (*cmd == 0)
103 break;
104 if (*cmd == '"') {
105 quoted++;
106 cmd++;
107 }
108 argv[ct++] = cmd;
109 if (quoted) {
110 if ((cmd = parse_string(cmd)) == NULL)
111 return 0;
112 } else {
113 while (*cmd && !isspace(*cmd))
114 cmd++;
115 }
116 if (*cmd)
117 *cmd++ = 0;
118 }
119 argv[ct] = NULL;
120 return ct;
121 }
122
123 /* Find the command from the command table and execute it. */
124
125 int cmdparse(struct cmd *cmds, char *cmdline)
126 {
127 struct cmd *cmdp;
128 int argc;
129 char *argv[32];
130
131 if ((argc = parse_args(argv, cmdline)) == 0 || *argv[0] == '#')
132 return 0;
133 strlwr(argv[0]);
134 for (cmdp = cmds; cmdp->function != NULL; cmdp++)
135 if (strncasecmp(cmdp->name, argv[0], strlen(argv[0])) == 0)
136 break;
137 if (cmdp->function == NULL)
138 return -1;
139 return (*cmdp->function)(argc, argv);
140 }
141
142 /* Signal handlers (which don't do all the things they SHOULD do) */
143
144 static void alarm_handler(int sig)
145 {
146 printf("\nTimeout! Closing...\n");
147 exit(1);
148 }
149
150 static void term_handler(int sig)
151 {
152 printf("System going down! Closing...\n");
153 exit(1);
154 }
155
156 /* Initialisation for the user */
157
158 int init_user(char *call)
159 {
160 struct passwd *pw;
161 char pass[13], salt[3];
162 char *p;
163 char axhome[64];
164
165 /* Strip SSID */
166 if (local) {
167 pw = getpwuid(getuid());
168 } else {
169 strcpy(callsign, call);
170 strcpy(username, callsign);
171 strlwr(username);
172 p = strchr(username, '-');
173 if (p) *p = '\0';
174 pw = getpwnam(username);
175 }
176
177 if (!pw) {
178 if (local)
179 panic("Ouch, you don't seem to be in the password file.\n");
180 if (autocreate) {
181 syslog(LOG_NOTICE, "Adding new user %s", username);
182 if (new_user(username) < 0) {
183 syslog(LOG_NOTICE, "Could not add new user %s", username);
184 printf("Sorry, could not add new user.\n");
185 return -1;
186 }
187 printf("You have been added to the user list of %s.\nWelcome.\n", hostname);
188 pw = getpwnam(username);
189 } else {
190 syslog(LOG_NOTICE, "New user %s not accepted", username);
191 printf("Sorry, new users are not accepted at this time.\n");
192 return -1;
193 }
194 } else {
195 if (local) {
196 strcpy(username, pw->pw_name);
197 strcpy(callsign, username);
198 }
199 /* Strip full name from the gecos field... */
200 if (strchr(pw->pw_gecos, ',') == NULL)
201 strcpy(fullname, pw->pw_gecos);
202 else
203 strcpy(fullname, strtok(pw->pw_gecos, ","));
204 }
205
206 if (!local) {
207 if ((mail_allowed == 1) && (strcmp(pw->pw_passwd, "*"))) {
208 printf("Sorry, you are not allowed to use axmail (you have a password set).\n");
209 return -1;
210 }
211
212 if ((mail_allowed == 2) && (!strcmp(pw->pw_passwd, "*"))) {
213 printf("Sorry, you are not allowed to use axmail (locked out in password file).\n");
214 return -1;
215 }
216 if (mail_allowed == 3) {
217 sprintf(axhome, "%s/%s", def_homedir, username);
218 if (strcmp(pw->pw_dir, axhome)) {
219 printf("Sorry, you are not allowed to use axmail - bad axhome.\n");
220 return -1;
221 }
222 }
223
224 if (identification == 1) {
225 getstr(pass, 12, "Password: ");
226 strncpy(salt, pw->pw_passwd, 2);
227 salt[2] = '\0';
228 if (strcmp(pw->pw_passwd, (char *)crypt(pass, salt))) {
229 printf("Login incorrect.\n");
230 return -1;
231 }
232 }
233
234 /* code supplied by Jaroslav Skarvada */
235 if ( (setgroups(0, NULL) == -1) || (setgid(pw->pw_gid) == -1) || (setuid(pw->pw_uid) == -1) )
236 panic("init_user: Argh, cannot setuid() or setgid() to %i.%i", pw->pw_uid, pw->pw_gid);
237 }
238
239 homedir = strdup(pw->pw_dir);
240 return 0;
241 }
242
243 int main(int argc, char **argv)
244 {
245 char *p;
246
247 signal(SIGALRM, alarm_handler);
248 signal(SIGTERM, term_handler);
249 openlog("axmail", LOG_PID, LOG_DAEMON);
250
251 if (getuid() != 0)
252 local = 1; /* Hey, we're being executed by a "normal"
253 * user, with user privileges!
254 */
255
256 if ((!local) && (argc != 2)) {
257 printf("axmail: Callsign not found as a parameter.\n");
258 syslog(LOG_NOTICE, "Callsign not found as a parameter\n");
259 return 1;
260 }
261
262 if (read_config() == -1) /* Read axmail.conf */
263 return 1;
264
265 printf("%s\n", VERSION);
266
267 if (init_user(argv[1]) == -1) /* Get user specific data, create user account */
268 return 1;
269
270 tinit(); /* Filenames etc */
271 getmail(); /* Scan mailbox */
272
273 if ((newm) || (messages))
274 printf("You have %i messages (%i new).\n", messages, newm);
275
276 prompt();
277 fflush(stdout);
278
279 p = malloc(1024);
280
281 while (1)
282 {
283 fgets(p, 1023, stdin);
284
285 if (p == NULL)
286 quit(0, 0);
287
288 if (cmdparse(Mailcmds, p) == -1)
289 printf("Unknown command. Type ? for a list.\n");
290
291 prompt();
292 fflush(stdout);
293 }
294
295 }
296
0 axMail - an SMTP mailbox for the various linux node frontends
1 and outbound FAX engine.
2
3 Current author: Brian Rogers (N1URO) <n1uro@n1uro.com>
4 Past author: Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>
5 Creator: Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
6
7 Additional Submissions: Stefano (IW3IJQ) <ziotibia1@libero.it>
8
9 As with any of the softwares I tweek n geek, *use at your own risk*!
10 With that said, and the fact that this is GPL software if you find
11 something that's borked... don't just submit a bug report. Fix it if
12 you can. Rerelease it under your own callsign if you wish, or feel free
13 to send me your code and I'll import it in.
14
15 This is probably one of the simplest packages to install and configure!
16 After you run tar zxvf axmail-###.tgz cd axmail-#### (which is where
17 you should be now if you're reading this :) ) and run:
18
19 make; make install
20 Note: If you have clamsmtp and your clamsmtpd.conf is in /usr/local/etc,
21 symlink it to /etc.
22
23 (on newer gcc/libs I do know that there's a warning after it makes but
24 it doesn't prevent the binary from compiling and so far it seems to test
25 ok. I'll fix that if and when I get the chance but don't hold your breath
26 on it hi!)
27
28 cd /usr/local/etc/ax25 and using your favorite editor (vi, joe, pico, etc) and
29 edit axmail.conf. In here you can specify how you wish the mailbox
30 to handle accounting for end users. On *most* linux systems, the default
31 should be "ok" but if you wish to have users contact you first, or if
32 you wish to have the system auto-create a standard shell login, or popmail
33 account for the users, etc... you may do so in the file. Double check your
34 settings (it *is* possible you can configure axmail.conf so that everyone
35 has root-group access... but why would you wish to do that? You've been
36 *warned* so double check your config settings for auto-creation of
37 accounts before saving!) The file is well commented to assist you. When
38 you're finished and have become an expert, if you wish to you can delete
39 the comment lines.
40
41 You may also customize the file "welcome.txt" in /usr/local/etc/ax25/ if you
42 wish to also. I suggest leaving the first line as-is as this is the so called
43 "new user" welcome greeting email. I've supplied a basic and short
44 greeting email message that users will get once they've created their
45 mailbox. If you would rather new users email your mail account directly
46 instead of root, you may wish to change that line.
47
48 For the software itself... believe it or not, you're *DONE*! That's all!
49 However... now we need to get it hooked into which ever node frontend you
50 run so that users have a way of accessing it. axMail runs as an external
51 process (ExtCmd) to the node. I've tested it with URONode (obviously) and
52 with LinuxNode by Tomi. To do this cd /usr/local/etc/ax25 and using your
53 favorite editor open node.conf and add the following line to your ExtCmds:
54
55 ExtCmd MAil 1 root /usr/local/sbin/axmail axmail %u
56 (note: MA in the word MAil is in CAPS)
57
58 Save uronode.conf and telnet in to test! It should work just fine. Since you
59 would have an existing account on your server, it's unlikely that you'll
60 get the welcome message, but since you can edit it, you'll know what it
61 says :)
62
63 **ERROR 1**
64 *** Note:
65 If you're installing axMail-FAX via source, but your MTA (aka: postfix)
66 was installed from repository packaging, you may need to create a symlink
67 to your users mail file directory... typically:
68 /var/spool/mail/ -> /usr/local/var/spool/mail/
69 If you don't do this, users will NOT see their incoming mail.
70 ***
71
72 Happy mailing!
73
0 axMail - an SMTP mailbox for the various linux node frontends.
1
2 PREFACE:
3
4 First off, sincere thanks to those who have written to tell me that
5 they use axMail, like what I've done to axMail, and for the
6 enthusiasm shown via words and/or code contributions for the program
7 in hopes of keeping packet radio networks around the world alive!
8
9 INTRO:
10
11 Greetings and thanks for taking a look at the program. Below I've posted
12 a kind of history of the program to the best of my knowledge taking text
13 from existing files. Rather than trying to reinvent the wheel and after
14 seeing this program before on Labrat's radio.linux.org.au site, I decided
15 to try and give some life into it... partially with the assistance of Phil
16 N1XTB nudging me pretty consistantly for many months in helping him get an
17 SMTP agent in his linux based packet node server without having to install
18 an xNOS overhead node ontop it. :)
19
20 Please do take a moment and read the text based files included with this
21 package so you're a bit familiar with what it does so that you don't get a
22 false perception as to what it can and/or can not do. axMail just might
23 not be what you're looking for or expecting for a node based plugin
24
25 CHANGE HISTORY:
26 axmail 2.10
27 Updated April, 2019 by Brian Rogers (N1URO) <n1uro@n1uro.net>
28 - added online help for the "Delivery Receipt" command. This keeps
29 it in line with all the other online helps.
30 - modified defines.h with this version number and also increased the
31 year that I'm still working on modifications to the project.
32 axmail 2.9
33 Updated May, 2018 by Brian Rogers (N1URO) <n1uro@n1uro.net>
34 - Removed asking for password upon new user login, instead added a new
35 field to axmail.conf for "SysopMail". Now the sysop has to put in their
36 email address as to inform the end user to request their desired password
37 into the system, especially if the sysop is running pop/imap features on
38 their system. This will prevent users from entering in plain text passwords
39 via unencrypted RF paths unlike other systems such as WL2K. I feel this is
40 a major security fix for axMail-FAX.
41 - added some line feeds in quit.c per suggestion of Tomasz SP2L so if
42 another program changed the user's mail spool file the warning displays
43 clearer.
44 - edited "welcome.txt" as to give the end user a better feel for what the
45 system is capable of doing along with other add-ons the sysop may have
46 on their system available to them such as Pop/Webmail.
47 - changed version number to 2.9 in defines.h and changed the end year of
48 maintenance from 2017 to 2018.
49
50 axmail 2.8
51 Updated November, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
52 Changes:
53 - added SPers as a command per the suggestion of VE1JOT. This was done in
54 command.c and was actually quite simple to impliment. The logic behind
55 it is to match the mail send command sets with those of standard PBBS
56 messaging commands.
57 * Note: The station who mainly requested this feature via VE1JOT, KB9PVH
58 urged that flags, cc, and bcc options be supressed to make it more user
59 friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I
60 do have compassion for those on HF. Steve gave me a different idea than
61 what I was going to do but I did impliment it into mailcmd.c, mailcmd.h
62 and command.c. If one needs a read receipt or to send cc/bcc copies of
63 their message then S still is an option.
64 - added a "spers" .hlp file to the archive.
65 - changed defines.h to reflect version 2.8.
66 - updated welcome.txt to be more generic rather than be version specific.
67 - modified mailcmd.c to now prompt for a "carbon copy" address when sending
68 mail. This allows for a duplicate of the message to be sent to the second
69 person one wishes to copy on the mail.
70 - edited this file.
71 - while I was at it, I decided to add a "blind carbon copy" feature.
72 This will send a copy of a message to the user specified HOWEVER,
73 they will NOT be listed in the recipient listings. For those using
74 raw terminals, it's possible to NOT enter a 'cc' but still enter a
75 'bcc' address.
76 - edited help files: send.hlp and spersonal.hlp to help guide users
77 on how to best send mail.
78 - created a bypass method so that if users did not wish to use cc or bcc
79 mail, they can bypass them instead of being prompted for them - suggested
80 by VE1JOT.
81 - added online help for send/sp|cc|bcc mail.
82 - added a new signature file function to the system in both command.c and in
83 mailcmd.c. If no signature file exists, it will instruct the user on this
84 fact and also inform them how to make one using the new SIgnature command.
85 Note: If no ~/.signature file exists mail will still be sent, just without
86 a 1 line siguature (max: 79 characters).
87 - bullet proofed both the autoforward and signature file routines in command.c
88 by insuring that a null string not only halts execution of both but also
89 removes both ~/.forward and ~/.signature files respectively.
90 - cleaned up the send signature a bit and added my little spam ad even if
91 there is no signature file present. This was done in mailcmd.c.
92 - added a string in the signature prompt which informs users how to clear
93 their signature if they desire such. This was done in utils.c
94 - Added special critical instructions to INSTALL. I didn't know if I had
95 these in there or not but SP2L informs me I did not. Thanks to Tomasz.
96 - Fixed a bug that when the mailbox file(s) weren't found for the system
97 MTA (aka: postfix) axMail would segfault. Now not only does it not
98 segfault but also instructs the user to inform the sysop of this error.
99 This bug existed since version 0.0.1. I've been wanting to do something
100 about this for IONs but didn't get to it until now. This was done in quit.c
101 - Fixed a couple of typos in README. I have a very difficult keyboard!
102 - Per the suggestion of G4APL (who gives us many great ideas - and why do
103 I refer to myself in plural? I need a DIET!) I did two things:
104 1 - when listing mail there's no message date stamp within the listing.
105 added in mailcmd.c
106 2 - reordered the mail listing fields where I felt they'd make the most
107 sense. Message subject, then message date, then message size are
108 the last 3 fields listed. They should also be kept in a column
109 justified manner of sorts.
110 3 - added a (St)atus header so the user has a better definition of
111 the status of a specific message.
112
113 axmail 2.7
114 Updated 18 May, 2017 by Brian Rogers (N1URO) <n1uro@n1uro.net>
115 Changes:
116 - Thanks to Van W1WCG, a bug was spotted in the SR command where if
117 the user entered a parameter such as a message number for example,
118 it wouldn't properly function. This has been fixed. Thanks Van!
119 - Forgot to take the "beta" tag out for 2.6. Oops. Fixed.
120 - I know in the past I had a 'cc' command for sending mail, and it's
121 been suck in my craw to readd it since.
122
123 axmail 2.6
124 Updated 22 September, 2016 by Brian Rogers (N1URO) <n1uro@n1uro.net>
125 Changes:
126 - changed version number in defines.h
127 - fixed error message when a pop client has deleted mail from the
128 main mail spool file.
129 - removed excessive receipt warning spotted by a gent who identifies
130 himself as rigor. This was in mailcmd.c in do_readmsg()
131 - while looking at the end of that routine, it just gave me an itch that
132 said "if you can look for a warning about a requested receipt, then
133 numbnutz you can offer the reader a chance to just generate a receipt
134 without having to do "SR" as previously stated at the end of the mail.
135 So, with that said and to get feeling back in my genitals, I wrote a
136 routine that asks the reader if they wish to send a receipt, and it
137 also echos where it's destined and confirmation it was sent.
138 - added an "--- end of message #* ---" tag at the end of mail when it
139 as finished displaying. This was done in mailcmd.c
140 - fixed an existing bug in the message routines where for each message
141 it wasn't resetting the receipt pointer! This bug existed since I
142 introduced the receipt "finder" in the messages. I'm shocked that
143 it wasn't reported to me by someone earlier. Now *only* if a message
144 has requested a receipt will it show that a receipt has been asked
145 for... whew!
146 - So many missing online help files! Again I'm surprised no one brought
147 this to my attention. How did we get along with them? "Oh my!" - Sulu
148 - Updated this README file.
149
150 axmail v2.5.1
151 Updated 28 September, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
152 Changes:
153 - added axmail.8 man page as per spec of Debian downstream.
154 - modified Makefile to include axmail.8 manpage installation for both
155 new and upgrade options.
156 - modified defines.h and this document to reflect maintenance release.
157
158 axmail v2.5
159 Updated 30 May, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
160 Changes:
161 - added new delivery receipt function to the send routine. This
162 compliments the read receipt function in the event of high
163 priority mail. Typically the read receipt is an option generated
164 by the recipient who may not decide to generate one. At least this
165 modification ensures with an ESMTP delivery that the sender using
166 axMail will get a reciept from "MAILER-DAEMON" which will verify
167 the status of delivered mail. This change was done in mailcmd.c
168 and is designed with the sendmail binary included with postfix.
169 - updated this README file.
170 - updated version number in defines.h
171
172 axmail v2.4
173 Updated 25 April, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
174 Changes:
175 - cleaned up mbox.c where I had originally placed the receipt checker
176 routine in. This caused loops within the buffer that displayed the
177 message. The true routine lives in mailcmd.c
178 - added patch to Makefile provided by Jaroslav at Red Hat for distribution
179 downstream compiles to make packages.
180 - changed version in defines.h
181 - major change in command.c, added a new Autofwd command to allow users to
182 auto-forward mail from a remote system to their "home" axMail-FAX base
183 system. Could also be used to forward mail to their internet accounts.
184 - added autofwd.hlp file.
185 - alphabetized the commandset listing, removed redundantly spelled commands.
186 - reworked Makefile and added an "upgrade" option so new files ONLY are
187 deployed after make. Execute using: "make upgrade"
188 - updated this file.
189
190 axmail v2.3.1
191 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
192 Changes:
193 - added a flag in mailcmd.c where if the request for a receipt exists in a mail
194 message, a bell and a warning sign is generated after the message has been
195 read by the user with instructions to use SR to generate a receipt. This
196 was a difficult routine for me to think of considering the various race
197 conditions that can be expected and met.
198 - updated welcome.txt with version upgrade and new feature list.
199 - updated README.
200
201 axmail v2.3
202 Updated 5 February, 2015 by Brian Rogers (N1URO) <n1uro@n1uro.net>
203 Changes:
204 - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW.
205 This defaults to NO but when flagged to YES, a request will be sent to the
206 remote client's agent. If the agent supports such, they will be prompted
207 whether or not to honor your receipt request. This is history as NO AGENT
208 FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read
209 receipt is similar to how HylaFax generates confirmation of transmission
210 receipt mails to your mailbox. Currently mail read in axMail will NOT
211 generate a receipt back. I may work on this later, but for now it doesn't
212 exist.
213 * My thoughts of the receipt function is negative. The fact that I may be
214 sending notification that I'm in my email client to a remote destination
215 IMHO is such that a webcam may as well be turned on and watch me do email,
216 and send the stream to "Big Brother" and I don't mean the television show.
217 </rant>
218 - Updated defines.h with the new version number.
219 - Updated welcome.txt so the new version number is displayed.
220
221 axmail v2.2
222 Updated 25 December, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
223 Changes:
224 - Made some maintenance changes, but forgot to log them in here.
225 axmail v2.1.1
226 Updated 30 October, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
227 Changes:
228 - Makefile
229 Code provided by Bob Tenty VE3TOK to make it more compatable
230 with newer GCC compiler requirements.
231 - utils.c
232 Code provided by Bob Tenty VE3TOK to fix a warning produced when
233 compiling.
234 - defines.h
235 Changed version number to reflect the changes incorporated by
236 Bob Tenty VE3TOK and committed to the subversion repository.
237
238 axmail v2.1
239 Updated 31 July, 2014 by Brian Rogers (N1URO) <n1uro@n1uro.net>
240 Changes:
241 - axmail.c
242 Code provided by Jaroslov OK2JRQ fixes a potential security hole in
243 the system privilege matching.
244 - global
245 axMail is now under review for considerations as standard packaging in
246 RedHat's fedora project. It appears it's going to be added as a package.
247
248 axmail v2.0
249 Updated 8 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
250 Changes:
251 - defines.h
252 Updated version number to reflect version release 2.0. Version 1.0.5
253 was simply a maintenance test package to try and reincorporate what
254 I had done up to version 1.0.6 which I believe was one of my last
255 releases up to 2009. Since I've done all that I can recall at this
256 point and time, I decided to match URONode's release numerics with
257 a 2.0 release version.
258
259 axmail v1.0.5
260 Updated 5 July, 2013 by Brian Rogers (N1URO) <n1uro@n1uro.net>
261 Changes:
262 - defines.h
263 Updated email listings to reflect the most current ones I could find
264 including my own. Also added 2013 to the years worked on axMail by
265 me.
266 - quit.c
267 Forced ALL mail, read or otherwise when user quits to save to the
268 user's system mailbox. This is for reverse compatability with those
269 who may also run a web-based email service on the internet such as
270 NeoMail, EMUMail, etc. Prior, the system was supposed to separate
271 any read mail (and all accompanying mail in that session) to the
272 axmail ~/mbox file. We don't want this for the specific reason of
273 "reverse email client" compatability.
274
275 axmail v1.0.4
276 Updated 23 May, 2008 by Brian Rogers (N1URO) <brian@support.uroweb.net>
277 Changes:
278 - setpwnam.c
279 Changed the way SIGPIPE was handled. Instead of being ignored, it will
280 now read a SIGQUIT properly if a QUIT is signaled to axmail either via
281 a shell prompt, or a node frontend. I've been noticing especially on
282 some timeouts that temp files don't flush as they should and the
283 user's directory can start to fill up.
284
285 axMail v1.0.3
286 Updated 2 December, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
287 Changes:
288 - mailcmd.c
289 Reset the way I wanted to handle the user input routine for sending faxes.
290 Commented out some more unneeded/unused code in the do_fax routine... will
291 clean it up in next release or so.
292 - mailcmd.c
293 cleaned up a bug I introduced in the never released 1.0.2 where the
294 X-Mailer was duping itself after each line of the body of a message.
295 - sfax.hlp
296 Reworded the SFax help file to help show some examples of how to format
297 the header.
298
299 axMail v1.0.2
300 Updated 24 November, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
301 Changes:
302 - mailcmd.c
303 Cleaned up some of the code in SFax. Also made some cosmetic changes.
304
305 axMail v1.0.1
306 Updated 31 October, 2007 by Brian Rogers (N1URO) <brian@support.uroweb.net>
307 Changes:
308 - mailcmd.c
309 Added a new routine to allow users to send faxes. This is defined by the
310 command "SF" for Send Fax. The routine was taken from the "S"end function
311 however since it's a one-way transmission, there is no reply available
312 nor is there an option for users to fax to any fax service as some I know
313 are pay services.
314 - config.h
315 added definitions for faxgate in axmail.conf
316 - config.c
317 added routine to allow for faxgate as a variable and be called from
318 mailcmd.c
319 - defines.h
320 version upgraded from v1.0.0 (unreleased - test version) to
321 v1.0.1
322 - etc/axmail.conf
323 Added new line called "FaxGate" with an example of how to properly
324 configure this line.
325 - etc/help/sfax.hlp
326 Added new file "sfax.hlp" which is an online help file for the SFax
327 command.
328
329 axMail v0.0.9
330 Updated 26 September, 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
331 Changes:
332 - mailcmd.c
333 Added a new routine that prompts the sender whether or not the message
334 is of an emergency/high priority mail message. If it's emergency message
335 then the headers are appended with an X-code flagged in such a manner
336 that Eudora and Outlook will display the received mail with a red flag
337 of sorts. The idea of such came to me in thinking of "what can I do
338 to help improve means of emergency communications using TCP/IP, Linux,
339 and packet radio?" Having the ability to "red flag" an SMTP message
340 I don't believe has yet to be available in any packet messaging
341 system... axMail I hope is the first.
342
343 If a user just hits enter, or selects "no" then the mail message
344 is sent under normal send routines.
345
346 found a minor bug in my routine where if an end user answered
347 "yes" in wanting to send an emergency/high priority message the system
348 ignored the request and sent it as 'normal' delivery. Made a minor
349 change to bullet-proof the responce.
350
351 Added online help text if user is unsure about sending a message
352 flagged urgent or normal. This text is available when the user is
353 prompted for priority selection by hitting "?" at the prompt.
354 - defines.h
355 Version updated from v0.0.8 to v0.0.9
356
357 axMail v0.0.8
358 Updated 2006 by Brian Rogers (N1URO) <n1uro@n1uro.com>
359
360 Changes:
361 - mailcmd.c
362 Rewrote and incorporated code provided by IW3IJQ how axMail inserts
363 it's version number in the X-Mailer: string.
364 - mailcmd.c
365 Added an X-Origin: string to show those peeking at mail headers
366 just how the message was possibly sent... by AMATEUR RADIO!
367 - axmail.conf
368 Added config option in "AllowMail" for axhome, a rewrite of code
369 submitted by Stefano IW3IJQ. While I stripped out home directory
370 structures similar to that of qmail or axspawn, Stefano convinced
371 me that it may be easier to manage home directories for axMail users
372 who don't have shell access to branch out within a preset directory.
373 - defines.h
374 Updated version number from 0.0.7 to 0.0.8
375 - axmail.c and config.c
376 Rewrote and incorporated code to allow for the routines to use
377 what Stefano IW3IJQ originally labled "newuhome" to use "axhome".
378 While I was at it, I rewrote and shortened the error text pushed
379 to a user who doesn't have permission to use such a directory.
380 * Note: When I write error texts and menus, I try to write them for
381 users on a multi-hop 1200 baud path thus the shorter the better as
382 long as context isn't lost and for long distance hops where full
383 paclen may cause retries (worse yet timeouts!)
384
385 axMail v0.0.7
386
387 Updated 2005 by Brian Rogers (N1URO) <n1uro@n1uro.com>
388
389 Changes:
390 - cosmetics
391 My usual "I like seeing this this way" type cosmetics... too many
392 to mention!
393 - adduser.c
394 changed the hard coding of user 'home' directories so that instead
395 of them going into a period delimited sort, just dump em all into
396 /home/<user> which seems to be "the norm" on most systems I've had
397 to assist with.
398 - adduser.c
399 fixed a bug where creating a user was actually causing the program to
400 segfault upon exit the first time a user went into the mailbox! The
401 node frontends hid this segfault as the program still flushed itself
402 from ram but I spotted it when running it at a command prompt. The
403 segfault came when axMail attempted to write mail back to the user's
404 system mailbox and it didn't exist. How I fixed this is listed next.
405 This may just be a new bug that appeared with the upgrading of libs,
406 this I'm unsure of and since I have no desire to go backwards I have
407 decided to actually make a minor routine...
408 - welcome.txt
409 New users are now sent a "welcome" message that the sysop can easily
410 customize to their desires. It's located at /etc/ax25/welcome.txt.
411 I figured that since axMail was segfaulting because such a file did
412 not exist, I might as well make use of this need by having the program
413 send the user a greeting.
414 - defines.h
415 Changed paths to be more in line with the more modern type configs
416 as a default. Paths can still be defined by the sysop prior to
417 compiling axMail.
418 - Makefile
419 I changed the default of make install to include all of the subroutines
420 within the Makefile yet leaving such things as "make installbin"
421 available as runtime options if just a binary refresh creation is
422 desired.
423 - other
424 I'm sure I missed a note or two *shrug*
425
426 axMail v0.0.6
427
428 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which
429 I at one time had but lost and can't seem to find it. My (n1uro)
430 changes may have alread been incorporated.
431
432 axMail v0.0.5
433
434 True mailbox functionalities created by Marius Petrescu.
435 Added Mailbox save routines (compatible with the command line
436 mail agent, including ~/mbox file)
437
438 axMail v0.0.4
439
440 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) <hessu@pspt.fi>
441
442 This program is free software; you can redistribute it and/or modify
443 it under the terms of the GNU General Public License as published by
444 the Free Software Foundation; either version 2 of the License, or
445 (at your option) any later version.
446
447 This program is distributed in the hope that it will be useful,
448 but WITHOUT ANY WARRANTY; without even the implied warranty of
449 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
450 GNU General Public License for more details.
451
452 You should have received a copy of the GNU General Public License
453 along with this program; if not, write to the Free Software
454 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
455
456
457 Don't give this one to anyone yet... it is NOT ready for distribution!
458
459 This is a simple mail user agent intended to provide the
460 mail functions in xNOS in a Linux ax.25 environment. If required,
461 it creates a normal user account for each new user (code mostly taken
462 from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail
463 on the system. axMail uses sendmail (or similar) to deliver mail, and
464 reads mail from each user's system mailbox (/var/spool/mail/username).
465 It does not provide any means of transferring mail between hosts.
466
467 axMail provides a simple, low-overhead user interface, much similar
468 to /bin/mail, xNOS and the packet BBS systems. It's useful for providing
469 good SMTP mail services for "dumb" ax.25 users over slow radio channels.
470
471 axMail is intended to be called from node. It takes one command
472 line argument of the user's callsign (with or without SSID). It must
473 be run as root, but it setuid()'s itself to the respective user's
474 privileges as soon as possible. It might run from ax25d as well.
475 It can also be executed from a shell with user privileges.
476
477 Some code (command parser, configuration file stuff) and the internal
478 architecture was taken from the LinuxNode frontend by Tomi Manninen
479 (OH2BNS). Thanks!
480
481 INSTALLATION:
482
483 See the file: INSTALL
484
485 TODO:
486 Suggestions?
487
488 --
489 Brian Rogers <n1uro@n1uro.net> [n1uro@n1uro.#cct.ct.usa.noam]
490 ftp://ftp.n1uro.net/pub/hamradio/packet
0
1 extern int parse_args(char *argv[],char *cmd);
2 extern int cmdparse(struct cmd *cmds, char *cmdline);
3
0
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 675 Mass Ave, Cambridge, MA 02139, USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12 freedom to share and change it. By contrast, the GNU General Public
13 License is intended to guarantee your freedom to share and change free
14 software--to make sure the software is free for all its users. This
15 General Public License applies to most of the Free Software
16 Foundation's software and to any other program whose authors commit to
17 using it. (Some other Free Software Foundation software is covered by
18 the GNU Library General Public License instead.) You can apply it to
19 your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22 price. Our General Public Licenses are designed to make sure that you
23 have the freedom to distribute copies of free software (and charge for
24 this service if you wish), that you receive source code or can get it
25 if you want it, that you can change the software or use pieces of it
26 in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29 anyone to deny you these rights or to ask you to surrender the rights.
30 These restrictions translate to certain responsibilities for you if you
31 distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34 gratis or for a fee, you must give the recipients all the rights that
35 you have. You must make sure that they, too, receive or can get the
36 source code. And you must show them these terms so they know their
37 rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40 (2) offer you this license which gives you legal permission to copy,
41 distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44 that everyone understands that there is no warranty for this free
45 software. If the software is modified by someone else and passed on, we
46 want its recipients to know that what they have is not the original, so
47 that any problems introduced by others will not reflect on the original
48 authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51 patents. We wish to avoid the danger that redistributors of a free
52 program will individually obtain patent licenses, in effect making the
53 program proprietary. To prevent this, we have made it clear that any
54 patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57 modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63 a notice placed by the copyright holder saying it may be distributed
64 under the terms of this General Public License. The "Program", below,
65 refers to any such program or work, and a "work based on the Program"
66 means either the Program or any derivative work under copyright law:
67 that is to say, a work containing the Program or a portion of it,
68 either verbatim or with modifications and/or translated into another
69 language. (Hereinafter, translation is included without limitation in
70 the term "modification".) Each licensee is addressed as "you".
71
72 Activities other than copying, distribution and modification are not
73 covered by this License; they are outside its scope. The act of
74 running the Program is not restricted, and the output from the Program
75 is covered only if its contents constitute a work based on the
76 Program (independent of having been made by running the Program).
77 Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80 source code as you receive it, in any medium, provided that you
81 conspicuously and appropriately publish on each copy an appropriate
82 copyright notice and disclaimer of warranty; keep intact all the
83 notices that refer to this License and to the absence of any warranty;
84 and give any other recipients of the Program a copy of this License
85 along with the Program.
86
87 You may charge a fee for the physical act of transferring a copy, and
88 you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91 of it, thus forming a work based on the Program, and copy and
92 distribute such modifications or work under the terms of Section 1
93 above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114 These requirements apply to the modified work as a whole. If
115 identifiable sections of that work are not derived from the Program,
116 and can be reasonably considered independent and separate works in
117 themselves, then this License, and its terms, do not apply to those
118 sections when you distribute them as separate works. But when you
119 distribute the same sections as part of a whole which is a work based
120 on the Program, the distribution of the whole must be on the terms of
121 this License, whose permissions for other licensees extend to the
122 entire whole, and thus to each and every part regardless of who wrote it.
123
124 Thus, it is not the intent of this section to claim rights or contest
125 your rights to work written entirely by you; rather, the intent is to
126 exercise the right to control the distribution of derivative or
127 collective works based on the Program.
128
129 In addition, mere aggregation of another work not based on the Program
130 with the Program (or with a work based on the Program) on a volume of
131 a storage or distribution medium does not bring the other work under
132 the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135 under Section 2) in object code or executable form under the terms of
136 Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155 The source code for a work means the preferred form of the work for
156 making modifications to it. For an executable work, complete source
157 code means all the source code for all modules it contains, plus any
158 associated interface definition files, plus the scripts used to
159 control compilation and installation of the executable. However, as a
160 special exception, the source code distributed need not include
161 anything that is normally distributed (in either source or binary
162 form) with the major components (compiler, kernel, and so on) of the
163 operating system on which the executable runs, unless that component
164 itself accompanies the executable.
165
166 If distribution of executable or object code is made by offering
167 access to copy from a designated place, then offering equivalent
168 access to copy the source code from the same place counts as
169 distribution of the source code, even though third parties are not
170 compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173 except as expressly provided under this License. Any attempt
174 otherwise to copy, modify, sublicense or distribute the Program is
175 void, and will automatically terminate your rights under this License.
176 However, parties who have received copies, or rights, from you under
177 this License will not have their licenses terminated so long as such
178 parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181 signed it. However, nothing else grants you permission to modify or
182 distribute the Program or its derivative works. These actions are
183 prohibited by law if you do not accept this License. Therefore, by
184 modifying or distributing the Program (or any work based on the
185 Program), you indicate your acceptance of this License to do so, and
186 all its terms and conditions for copying, distributing or modifying
187 the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190 Program), the recipient automatically receives a license from the
191 original licensor to copy, distribute or modify the Program subject to
192 these terms and conditions. You may not impose any further
193 restrictions on the recipients' exercise of the rights granted herein.
194 You are not responsible for enforcing compliance by third parties to
195 this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198 infringement or for any other reason (not limited to patent issues),
199 conditions are imposed on you (whether by court order, agreement or
200 otherwise) that contradict the conditions of this License, they do not
201 excuse you from the conditions of this License. If you cannot
202 distribute so as to satisfy simultaneously your obligations under this
203 License and any other pertinent obligations, then as a consequence you
204 may not distribute the Program at all. For example, if a patent
205 license would not permit royalty-free redistribution of the Program by
206 all those who receive copies directly or indirectly through you, then
207 the only way you could satisfy both it and this License would be to
208 refrain entirely from distribution of the Program.
209
210 If any portion of this section is held invalid or unenforceable under
211 any particular circumstance, the balance of the section is intended to
212 apply and the section as a whole is intended to apply in other
213 circumstances.
214
215 It is not the purpose of this section to induce you to infringe any
216 patents or other property right claims or to contest validity of any
217 such claims; this section has the sole purpose of protecting the
218 integrity of the free software distribution system, which is
219 implemented by public license practices. Many people have made
220 generous contributions to the wide range of software distributed
221 through that system in reliance on consistent application of that
222 system; it is up to the author/donor to decide if he or she is willing
223 to distribute software through any other system and a licensee cannot
224 impose that choice.
225
226 This section is intended to make thoroughly clear what is believed to
227 be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230 certain countries either by patents or by copyrighted interfaces, the
231 original copyright holder who places the Program under this License
232 may add an explicit geographical distribution limitation excluding
233 those countries, so that distribution is permitted only in or among
234 countries not thus excluded. In such case, this License incorporates
235 the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238 of the General Public License from time to time. Such new versions will
239 be similar in spirit to the present version, but may differ in detail to
240 address new problems or concerns.
241
242 Each version is given a distinguishing version number. If the Program
243 specifies a version number of this License which applies to it and "any
244 later version", you have the option of following the terms and conditions
245 either of that version or of any later version published by the Free
246 Software Foundation. If the Program does not specify a version number of
247 this License, you may choose any version ever published by the Free Software
248 Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251 programs whose distribution conditions are different, write to the author
252 to ask for permission. For software which is copyrighted by the Free
253 Software Foundation, write to the Free Software Foundation; we sometimes
254 make exceptions for this. Our decision will be guided by the two goals
255 of preserving the free status of all derivatives of our free software and
256 of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 Appendix: How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285 possible use to the public, the best way to achieve this is to make it
286 free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289 to attach them to the start of each source file to most effectively
290 convey the exclusion of warranty; and each file should have at least
291 the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) 19yy <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
309
310 Also add information on how to contact you by electronic and paper mail.
311
312 If the program is interactive, make it output a short notice like this
313 when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) 19yy name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320 The hypothetical commands `show w' and `show c' should show the appropriate
321 parts of the General Public License. Of course, the commands you use may
322 be called something other than `show w' and `show c'; they could even be
323 mouse-clicks or menu items--whatever suits your program.
324
325 You should also get your employer (if you work as a programmer) or your
326 school, if any, to sign a "copyright disclaimer" for the program, if
327 necessary. Here is a sample; alter the names:
328
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
333 Ty Coon, President of Vice
334
335 This General Public License does not permit incorporating your program into
336 proprietary programs. If your program is a subroutine library, you may
337 consider it more useful to permit linking proprietary applications with the
338 library. If this is what you want to do, use the GNU Library General
339 Public License instead of this License.
Binary diff not shown
(New empty file)
2323 not be what you're looking for or expecting for a node based plugin
2424
2525 CHANGE HISTORY:
26 axMail 2.13
27 Updated June 24, 2021
28 - Went through the code and fixed multiple compile warnings. Warnings do not
29 affect the program/binary from compiling or funcitioning BUT rather gives
30 the author(s) a warning that possible compile instructions may have changed
31 or are changing.
32
33 axMail 2.12.2
34 Updated January 18, 2021
35 - Fixed bug in mailcmd.c where sending acted funky on 64 bit systems.
36 axMail would segfault out before properly returning the user back to
37 the mailbox prompt.
38 - While at it also fixed some compiler warnings in mailcmd.c
39 - edited defines.h to fix old path from /var/ax25 to /var/lib/ax25
40 - edited defines.h to reflect this version.
41
2642 axMail 2.12.1
2743 Updated January 17, 2021
2844 - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail
1010 #include <pwd.h>
1111 #include <crypt.h>
1212 #include <error.h>
13 #include <grp.h>
1314
1415 #include "config.h"
1516 #include "axmail.h"
2021
2122 /* Parse c-style escapes (neat to have!) */
2223
24 // int setgroups(void);
25
2326 static char *parse_string(char *str)
2427 {
2528 char *cp = str;
1212 #include "mbox.h"
1313 #include "utils.h"
1414 #include "quit.h"
15
16 void getsig(char *signature);
17 void getaddy(char *forward);
1518
1619 struct cmd Mailcmds[] = {
1720 { "?", do_help },
0
10 #include <utmp.h>
21 #include "defines.h"
32
22 * defines.h - Compile-time configuration
33 */
44
5 #define VERSION "axMail-Fax v2.12.2"
5 #define VERSION "axMail-Fax v2.13"
66 #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) <hessu@hes.iki.fi>\nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) <mpetrescu@online.ro>\nOther modifications (c) 2005-2021 by Brian Rogers (N1URO) <n1uro@n1uro.net> "
77 #define PROMPT "=> "
88
0 GNU GENERAL PUBLIC LICENSE
1 Version 3, 29 June 2007
2
3 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
4 Everyone is permitted to copy and distribute verbatim copies
5 of this license document, but changing it is not allowed.
6
7 Preamble
8
9 The GNU General Public License is a free, copyleft license for
10 software and other kinds of works.
11
12 The licenses for most software and other practical works are designed
13 to take away your freedom to share and change the works. By contrast,
14 the GNU General Public License is intended to guarantee your freedom to
15 share and change all versions of a program--to make sure it remains free
16 software for all its users. We, the Free Software Foundation, use the
17 GNU General Public License for most of our software; it applies also to
18 any other work released this way by its authors. You can apply it to
19 your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22 price. Our General Public Licenses are designed to make sure that you
23 have the freedom to distribute copies of free software (and charge for
24 them if you wish), that you receive source code or can get it if you
25 want it, that you can change the software or use pieces of it in new
26 free programs, and that you know you can do these things.
27
28 To protect your rights, we need to prevent others from denying you
29 these rights or asking you to surrender the rights. Therefore, you have
30 certain responsibilities if you distribute copies of the software, or if
31 you modify it: responsibilities to respect the freedom of others.
32
33 For example, if you distribute copies of such a program, whether
34 gratis or for a fee, you must pass on to the recipients the same
35 freedoms that you received. You must make sure that they, too, receive
36 or can get the source code. And you must show them these terms so they
37 know their rights.
38
39 Developers that use the GNU GPL protect your rights with two steps:
40 (1) assert copyright on the software, and (2) offer you this License
41 giving you legal permission to copy, distribute and/or modify it.
42
43 For the developers' and authors' protection, the GPL clearly explains
44 that there is no warranty for this free software. For both users' and
45 authors' sake, the GPL requires that modified versions be marked as
46 changed, so that their problems will not be attributed erroneously to
47 authors of previous versions.
48
49 Some devices are designed to deny users access to install or run
50 modified versions of the software inside them, although the manufacturer
51 can do so. This is fundamentally incompatible with the aim of
52 protecting users' freedom to change the software. The systematic
53 pattern of such abuse occurs in the area of products for individuals to
54 use, which is precisely where it is most unacceptable. Therefore, we
55 have designed this version of the GPL to prohibit the practice for those
56 products. If such problems arise substantially in other domains, we
57 stand ready to extend this provision to those domains in future versions
58 of the GPL, as needed to protect the freedom of users.
59
60 Finally, every program is threatened constantly by software patents.
61 States should not allow patents to restrict development and use of
62 software on general-purpose computers, but in those that do, we wish to
63 avoid the special danger that patents applied to a free program could
64 make it effectively proprietary. To prevent this, the GPL assures that
65 patents cannot be used to render the program non-free.
66
67 The precise terms and conditions for copying, distribution and
68 modification follow.
69
70 TERMS AND CONDITIONS
71
72 0. Definitions.
73
74 "This License" refers to version 3 of the GNU General Public License.
75
76 "Copyright" also means copyright-like laws that apply to other kinds of
77 works, such as semiconductor masks.
78
79 "The Program" refers to any copyrightable work licensed under this
80 License. Each licensee is addressed as "you". "Licensees" and
81 "recipients" may be individuals or organizations.
82
83 To "modify" a work means to copy from or adapt all or part of the work
84 in a fashion requiring copyright permission, other than the making of an
85 exact copy. The resulting work is called a "modified version" of the
86 earlier work or a work "based on" the earlier work.
87
88 A "covered work" means either the unmodified Program or a work based
89 on the Program.
90
91 To "propagate" a work means to do anything with it that, without
92 permission, would make you directly or secondarily liable for
93 infringement under applicable copyright law, except executing it on a
94 computer or modifying a private copy. Propagation includes copying,
95 distribution (with or without modification), making available to the
96 public, and in some countries other activities as well.
97
98 To "convey" a work means any kind of propagation that enables other
99 parties to make or receive copies. Mere interaction with a user through
100 a computer network, with no transfer of a copy, is not conveying.
101
102 An interactive user interface displays "Appropriate Legal Notices"
103 to the extent that it includes a convenient and prominently visible
104 feature that (1) displays an appropriate copyright notice, and (2)
105 tells the user that there is no warranty for the work (except to the
106 extent that warranties are provided), that licensees may convey the
107 work under this License, and how to view a copy of this License. If
108 the interface presents a list of user commands or options, such as a
109 menu, a prominent item in the list meets this criterion.
110
111 1. Source Code.
112
113 The "source code" for a work means the preferred form of the work
114 for making modifications to it. "Object code" means any non-source
115 form of a work.
116
117 A "Standard Interface" means an interface that either is an official
118 standard defined by a recognized standards body, or, in the case of
119 interfaces specified for a particular programming language, one that
120 is widely used among developers working in that language.
121
122 The "System Libraries" of an executable work include anything, other
123 than the work as a whole, that (a) is included in the normal form of
124 packaging a Major Component, but which is not part of that Major
125 Component, and (b) serves only to enable use of the work with that
126 Major Component, or to implement a Standard Interface for which an
127 implementation is available to the public in source code form. A
128 "Major Component", in this context, means a major essential component
129 (kernel, window system, and so on) of the specific operating system
130 (if any) on which the executable work runs, or a compiler used to
131 produce the work, or an object code interpreter used to run it.
132
133 The "Corresponding Source" for a work in object code form means all
134 the source code needed to generate, install, and (for an executable
135 work) run the object code and to modify the work, including scripts to
136 control those activities. However, it does not include the work's
137 System Libraries, or general-purpose tools or generally available free
138 programs which are used unmodified in performing those activities but
139 which are not part of the work. For example, Corresponding Source
140 includes interface definition files associated with source files for
141 the work, and the source code for shared libraries and dynamically
142 linked subprograms that the work is specifically designed to require,
143 such as by intimate data communication or control flow between those
144 subprograms and other parts of the work.
145
146 The Corresponding Source need not include anything that users
147 can regenerate automatically from other parts of the Corresponding
148 Source.
149
150 The Corresponding Source for a work in source code form is that
151 same work.
152
153 2. Basic Permissions.
154
155 All rights granted under this License are granted for the term of
156 copyright on the Program, and are irrevocable provided the stated
157 conditions are met. This License explicitly affirms your unlimited
158 permission to run the unmodified Program. The output from running a
159 covered work is covered by this License only if the output, given its
160 content, constitutes a covered work. This License acknowledges your
161 rights of fair use or other equivalent, as provided by copyright law.
162
163 You may make, run and propagate covered works that you do not
164 convey, without conditions so long as your license otherwise remains
165 in force. You may convey covered works to others for the sole purpose
166 of having them make modifications exclusively for you, or provide you
167 with facilities for running those works, provided that you comply with
168 the terms of this License in conveying all material for which you do
169 not control copyright. Those thus making or running the covered works
170 for you must do so exclusively on your behalf, under your direction
171 and control, on terms that prohibit them from making any copies of
172 your copyrighted material outside their relationship with you.
173
174 Conveying under any other circumstances is permitted solely under
175 the conditions stated below. Sublicensing is not allowed; section 10
176 makes it unnecessary.
177
178 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
179
180 No covered work shall be deemed part of an effective technological
181 measure under any applicable law fulfilling obligations under article
182 11 of the WIPO copyright treaty adopted on 20 December 1996, or
183 similar laws prohibiting or restricting circumvention of such
184 measures.
185
186 When you convey a covered work, you waive any legal power to forbid
187 circumvention of technological measures to the extent such circumvention
188 is effected by exercising rights under this License with respect to
189 the covered work, and you disclaim any intention to limit operation or
190 modification of the work as a means of enforcing, against the work's
191 users, your or third parties' legal rights to forbid circumvention of
192 technological measures.
193
194 4. Conveying Verbatim Copies.
195
196 You may convey verbatim copies of the Program's source code as you
197 receive it, in any medium, provided that you conspicuously and
198 appropriately publish on each copy an appropriate copyright notice;
199 keep intact all notices stating that this License and any
200 non-permissive terms added in accord with section 7 apply to the code;
201 keep intact all notices of the absence of any warranty; and give all
202 recipients a copy of this License along with the Program.
203
204 You may charge any price or no price for each copy that you convey,
205 and you may offer support or warranty protection for a fee.
206
207 5. Conveying Modified Source Versions.
208
209 You may convey a work based on the Program, or the modifications to
210 produce it from the Program, in the form of source code under the
211 terms of section 4, provided that you also meet all of these conditions:
212
213 a) The work must carry prominent notices stating that you modified
214 it, and giving a relevant date.
215
216 b) The work must carry prominent notices stating that it is
217 released under this License and any conditions added under section
218 7. This requirement modifies the requirement in section 4 to
219 "keep intact all notices".
220
221 c) You must license the entire work, as a whole, under this
222 License to anyone who comes into possession of a copy. This
223 License will therefore apply, along with any applicable section 7
224 additional terms, to the whole of the work, and all its parts,
225 regardless of how they are packaged. This License gives no
226 permission to license the work in any other way, but it does not
227 invalidate such permission if you have separately received it.
228
229 d) If the work has interactive user interfaces, each must display
230 Appropriate Legal Notices; however, if the Program has interactive
231 interfaces that do not display Appropriate Legal Notices, your
232 work need not make them do so.
233
234 A compilation of a covered work with other separate and independent
235 works, which are not by their nature extensions of the covered work,
236 and which are not combined with it such as to form a larger program,
237 in or on a volume of a storage or distribution medium, is called an
238 "aggregate" if the compilation and its resulting copyright are not
239 used to limit the access or legal rights of the compilation's users
240 beyond what the individual works permit. Inclusion of a covered work
241 in an aggregate does not cause this License to apply to the other
242 parts of the aggregate.
243
244 6. Conveying Non-Source Forms.
245
246 You may convey a covered work in object code form under the terms
247 of sections 4 and 5, provided that you also convey the
248 machine-readable Corresponding Source under the terms of this License,
249 in one of these ways:
250
251 a) Convey the object code in, or embodied in, a physical product
252 (including a physical distribution medium), accompanied by the
253 Corresponding Source fixed on a durable physical medium
254 customarily used for software interchange.
255
256 b) Convey the object code in, or embodied in, a physical product
257 (including a physical distribution medium), accompanied by a
258 written offer, valid for at least three years and valid for as
259 long as you offer spare parts or customer support for that product
260 model, to give anyone who possesses the object code either (1) a
261 copy of the Corresponding Source for all the software in the
262 product that is covered by this License, on a durable physical
263 medium customarily used for software interchange, for a price no
264 more than your reasonable cost of physically performing this
265 conveying of source, or (2) access to copy the
266 Corresponding Source from a network server at no charge.
267
268 c) Convey individual copies of the object code with a copy of the
269 written offer to provide the Corresponding Source. This
270 alternative is allowed only occasionally and noncommercially, and
271 only if you received the object code with such an offer, in accord
272 with subsection 6b.
273
274 d) Convey the object code by offering access from a designated
275 place (gratis or for a charge), and offer equivalent access to the
276 Corresponding Source in the same way through the same place at no
277 further charge. You need not require recipients to copy the
278 Corresponding Source along with the object code. If the place to
279 copy the object code is a network server, the Corresponding Source
280 may be on a different server (operated by you or a third party)
281 that supports equivalent copying facilities, provided you maintain
282 clear directions next to the object code saying where to find the
283 Corresponding Source. Regardless of what server hosts the
284 Corresponding Source, you remain obligated to ensure that it is
285 available for as long as needed to satisfy these requirements.
286
287 e) Convey the object code using peer-to-peer transmission, provided
288 you inform other peers where the object code and Corresponding
289 Source of the work are being offered to the general public at no
290 charge under subsection 6d.
291
292 A separable portion of the object code, whose source code is excluded
293 from the Corresponding Source as a System Library, need not be
294 included in conveying the object code work.
295
296 A "User Product" is either (1) a "consumer product", which means any
297 tangible personal property which is normally used for personal, family,
298 or household purposes, or (2) anything designed or sold for incorporation
299 into a dwelling. In determining whether a product is a consumer product,
300 doubtful cases shall be resolved in favor of coverage. For a particular
301 product received by a particular user, "normally used" refers to a
302 typical or common use of that class of product, regardless of the status
303 of the particular user or of the way in which the particular user
304 actually uses, or expects or is expected to use, the product. A product
305 is a consumer product regardless of whether the product has substantial
306 commercial, industrial or non-consumer uses, unless such uses represent
307 the only significant mode of use of the product.
308
309 "Installation Information" for a User Product means any methods,
310 procedures, authorization keys, or other information required to install
311 and execute modified versions of a covered work in that User Product from
312 a modified version of its Corresponding Source. The information must
313 suffice to ensure that the continued functioning of the modified object
314 code is in no case prevented or interfered with solely because
315 modification has been made.
316
317 If you convey an object code work under this section in, or with, or
318 specifically for use in, a User Product, and the conveying occurs as
319 part of a transaction in which the right of possession and use of the
320 User Product is transferred to the recipient in perpetuity or for a
321 fixed term (regardless of how the transaction is characterized), the
322 Corresponding Source conveyed under this section must be accompanied
323 by the Installation Information. But this requirement does not apply
324 if neither you nor any third party retains the ability to install
325 modified object code on the User Product (for example, the work has
326 been installed in ROM).
327
328 The requirement to provide Installation Information does not include a
329 requirement to continue to provide support service, warranty, or updates
330 for a work that has been modified or installed by the recipient, or for
331 the User Product in which it has been modified or installed. Access to a
332 network may be denied when the modification itself materially and
333 adversely affects the operation of the network or violates the rules and
334 protocols for communication across the network.
335
336 Corresponding Source conveyed, and Installation Information provided,
337 in accord with this section must be in a format that is publicly
338 documented (and with an implementation available to the public in
339 source code form), and must require no special password or key for
340 unpacking, reading or copying.
341
342 7. Additional Terms.
343
344 "Additional permissions" are terms that supplement the terms of this
345 License by making exceptions from one or more of its conditions.
346 Additional permissions that are applicable to the entire Program shall
347 be treated as though they were included in this License, to the extent
348 that they are valid under applicable law. If additional permissions
349 apply only to part of the Program, that part may be used separately
350 under those permissions, but the entire Program remains governed by
351 this License without regard to the additional permissions.
352
353 When you convey a copy of a covered work, you may at your option
354 remove any additional permissions from that copy, or from any part of
355 it. (Additional permissions may be written to require their own
356 removal in certain cases when you modify the work.) You may place
357 additional permissions on material, added by you to a covered work,
358 for which you have or can give appropriate copyright permission.
359
360 Notwithstanding any other provision of this License, for material you
361 add to a covered work, you may (if authorized by the copyright holders of
362 that material) supplement the terms of this License with terms:
363
364 a) Disclaiming warranty or limiting liability differently from the
365 terms of sections 15 and 16 of this License; or
366
367 b) Requiring preservation of specified reasonable legal notices or
368 author attributions in that material or in the Appropriate Legal
369 Notices displayed by works containing it; or
370
371 c) Prohibiting misrepresentation of the origin of that material, or
372 requiring that modified versions of such material be marked in
373 reasonable ways as different from the original version; or
374
375 d) Limiting the use for publicity purposes of names of licensors or
376 authors of the material; or
377
378 e) Declining to grant rights under trademark law for use of some
379 trade names, trademarks, or service marks; or
380
381 f) Requiring indemnification of licensors and authors of that
382 material by anyone who conveys the material (or modified versions of
383 it) with contractual assumptions of liability to the recipient, for
384 any liability that these contractual assumptions directly impose on
385 those licensors and authors.
386
387 All other non-permissive additional terms are considered "further
388 restrictions" within the meaning of section 10. If the Program as you
389 received it, or any part of it, contains a notice stating that it is
390 governed by this License along with a term that is a further
391 restriction, you may remove that term. If a license document contains
392 a further restriction but permits relicensing or conveying under this
393 License, you may add to a covered work material governed by the terms
394 of that license document, provided that the further restriction does
395 not survive such relicensing or conveying.
396
397 If you add terms to a covered work in accord with this section, you
398 must place, in the relevant source files, a statement of the
399 additional terms that apply to those files, or a notice indicating
400 where to find the applicable terms.
401
402 Additional terms, permissive or non-permissive, may be stated in the
403 form of a separately written license, or stated as exceptions;
404 the above requirements apply either way.
405
406 8. Termination.
407
408 You may not propagate or modify a covered work except as expressly
409 provided under this License. Any attempt otherwise to propagate or
410 modify it is void, and will automatically terminate your rights under
411 this License (including any patent licenses granted under the third
412 paragraph of section 11).
413
414 However, if you cease all violation of this License, then your
415 license from a particular copyright holder is reinstated (a)
416 provisionally, unless and until the copyright holder explicitly and
417 finally terminates your license, and (b) permanently, if the copyright
418 holder fails to notify you of the violation by some reasonable means
419 prior to 60 days after the cessation.
420
421 Moreover, your license from a particular copyright holder is
422 reinstated permanently if the copyright holder notifies you of the
423 violation by some reasonable means, this is the first time you have
424 received notice of violation of this License (for any work) from that
425 copyright holder, and you cure the violation prior to 30 days after
426 your receipt of the notice.
427
428 Termination of your rights under this section does not terminate the
429 licenses of parties who have received copies or rights from you under
430 this License. If your rights have been terminated and not permanently
431 reinstated, you do not qualify to receive new licenses for the same
432 material under section 10.
433
434 9. Acceptance Not Required for Having Copies.
435
436 You are not required to accept this License in order to receive or
437 run a copy of the Program. Ancillary propagation of a covered work
438 occurring solely as a consequence of using peer-to-peer transmission
439 to receive a copy likewise does not require acceptance. However,
440 nothing other than this License grants you permission to propagate or
441 modify any covered work. These actions infringe copyright if you do
442 not accept this License. Therefore, by modifying or propagating a
443 covered work, you indicate your acceptance of this License to do so.
444
445 10. Automatic Licensing of Downstream Recipients.
446
447 Each time you convey a covered work, the recipient automatically
448 receives a license from the original licensors, to run, modify and
449 propagate that work, subject to this License. You are not responsible
450 for enforcing compliance by third parties with this License.
451
452 An "entity transaction" is a transaction transferring control of an
453 organization, or substantially all assets of one, or subdividing an
454 organization, or merging organizations. If propagation of a covered
455 work results from an entity transaction, each party to that
456 transaction who receives a copy of the work also receives whatever
457 licenses to the work the party's predecessor in interest had or could
458 give under the previous paragraph, plus a right to possession of the
459 Corresponding Source of the work from the predecessor in interest, if
460 the predecessor has it or can get it with reasonable efforts.
461
462 You may not impose any further restrictions on the exercise of the
463 rights granted or affirmed under this License. For example, you may
464 not impose a license fee, royalty, or other charge for exercise of
465 rights granted under this License, and you may not initiate litigation
466 (including a cross-claim or counterclaim in a lawsuit) alleging that
467 any patent claim is infringed by making, using, selling, offering for
468 sale, or importing the Program or any portion of it.
469
470 11. Patents.
471
472 A "contributor" is a copyright holder who authorizes use under this
473 License of the Program or a work on which the Program is based. The
474 work thus licensed is called the contributor's "contributor version".
475
476 A contributor's "essential patent claims" are all patent claims
477 owned or controlled by the contributor, whether already acquired or
478 hereafter acquired, that would be infringed by some manner, permitted
479 by this License, of making, using, or selling its contributor version,
480 but do not include claims that would be infringed only as a
481 consequence of further modification of the contributor version. For
482 purposes of this definition, "control" includes the right to grant
483 patent sublicenses in a manner consistent with the requirements of
484 this License.
485
486 Each contributor grants you a non-exclusive, worldwide, royalty-free
487 patent license under the contributor's essential patent claims, to
488 make, use, sell, offer for sale, import and otherwise run, modify and
489 propagate the contents of its contributor version.
490
491 In the following three paragraphs, a "patent license" is any express
492 agreement or commitment, however denominated, not to enforce a patent
493 (such as an express permission to practice a patent or covenant not to
494 sue for patent infringement). To "grant" such a patent license to a
495 party means to make such an agreement or commitment not to enforce a
496 patent against the party.
497
498 If you convey a covered work, knowingly relying on a patent license,
499 and the Corresponding Source of the work is not available for anyone
500 to copy, free of charge and under the terms of this License, through a
501 publicly available network server or other readily accessible means,
502 then you must either (1) cause the Corresponding Source to be so
503 available, or (2) arrange to deprive yourself of the benefit of the
504 patent license for this particular work, or (3) arrange, in a manner
505 consistent with the requirements of this License, to extend the patent
506 license to downstream recipients. "Knowingly relying" means you have
507 actual knowledge that, but for the patent license, your conveying the
508 covered work in a country, or your recipient's use of the covered work
509 in a country, would infringe one or more identifiable patents in that
510 country that you have reason to believe are valid.
511
512 If, pursuant to or in connection with a single transaction or
513 arrangement, you convey, or propagate by procuring conveyance of, a
514 covered work, and grant a patent license to some of the parties
515 receiving the covered work authorizing them to use, propagate, modify
516 or convey a specific copy of the covered work, then the patent license
517 you grant is automatically extended to all recipients of the covered
518 work and works based on it.
519
520 A patent license is "discriminatory" if it does not include within
521 the scope of its coverage, prohibits the exercise of, or is
522 conditioned on the non-exercise of one or more of the rights that are
523 specifically granted under this License. You may not convey a covered
524 work if you are a party to an arrangement with a third party that is
525 in the business of distributing software, under which you make payment
526 to the third party based on the extent of your activity of conveying
527 the work, and under which the third party grants, to any of the
528 parties who would receive the covered work from you, a discriminatory
529 patent license (a) in connection with copies of the covered work
530 conveyed by you (or copies made from those copies), or (b) primarily
531 for and in connection with specific products or compilations that
532 contain the covered work, unless you entered into that arrangement,
533 or that patent license was granted, prior to 28 March 2007.
534
535 Nothing in this License shall be construed as excluding or limiting
536 any implied license or other defenses to infringement that may
537 otherwise be available to you under applicable patent law.
538
539 12. No Surrender of Others' Freedom.
540
541 If conditions are imposed on you (whether by court order, agreement or
542 otherwise) that contradict the conditions of this License, they do not
543 excuse you from the conditions of this License. If you cannot convey a
544 covered work so as to satisfy simultaneously your obligations under this
545 License and any other pertinent obligations, then as a consequence you may
546 not convey it at all. For example, if you agree to terms that obligate you
547 to collect a royalty for further conveying from those to whom you convey
548 the Program, the only way you could satisfy both those terms and this
549 License would be to refrain entirely from conveying the Program.
550
551 13. Use with the GNU Affero General Public License.
552
553 Notwithstanding any other provision of this License, you have
554 permission to link or combine any covered work with a work licensed
555 under version 3 of the GNU Affero General Public License into a single
556 combined work, and to convey the resulting work. The terms of this
557 License will continue to apply to the part which is the covered work,
558 but the special requirements of the GNU Affero General Public License,
559 section 13, concerning interaction through a network will apply to the
560 combination as such.
561
562 14. Revised Versions of this License.
563
564 The Free Software Foundation may publish revised and/or new versions of
565 the GNU General Public License from time to time. Such new versions will
566 be similar in spirit to the present version, but may differ in detail to
567 address new problems or concerns.
568
569 Each version is given a distinguishing version number. If the
570 Program specifies that a certain numbered version of the GNU General
571 Public License "or any later version" applies to it, you have the
572 option of following the terms and conditions either of that numbered
573 version or of any later version published by the Free Software
574 Foundation. If the Program does not specify a version number of the
575 GNU General Public License, you may choose any version ever published
576 by the Free Software Foundation.
577
578 If the Program specifies that a proxy can decide which future
579 versions of the GNU General Public License can be used, that proxy's
580 public statement of acceptance of a version permanently authorizes you
581 to choose that version for the Program.
582
583 Later license versions may give you additional or different
584 permissions. However, no additional obligations are imposed on any
585 author or copyright holder as a result of your choosing to follow a
586 later version.
587
588 15. Disclaimer of Warranty.
589
590 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
591 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
592 HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
593 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
594 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
595 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
596 IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
597 ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
598
599 16. Limitation of Liability.
600
601 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
602 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
603 THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
604 GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
605 USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
606 DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
607 PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
608 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
609 SUCH DAMAGES.
610
611 17. Interpretation of Sections 15 and 16.
612
613 If the disclaimer of warranty and limitation of liability provided
614 above cannot be given local legal effect according to their terms,
615 reviewing courts shall apply local law that most closely approximates
616 an absolute waiver of all civil liability in connection with the
617 Program, unless a warranty or assumption of liability accompanies a
618 copy of the Program in return for a fee.
619
620 END OF TERMS AND CONDITIONS
621
622 How to Apply These Terms to Your New Programs
623
624 If you develop a new program, and you want it to be of the greatest
625 possible use to the public, the best way to achieve this is to make it
626 free software which everyone can redistribute and change under these terms.
627
628 To do so, attach the following notices to the program. It is safest
629 to attach them to the start of each source file to most effectively
630 state the exclusion of warranty; and each file should have at least
631 the "copyright" line and a pointer to where the full notice is found.
632
633 <one line to give the program's name and a brief idea of what it does.>
634 Copyright (C) <year> <name of author>
635
636 This program is free software: you can redistribute it and/or modify
637 it under the terms of the GNU General Public License as published by
638 the Free Software Foundation, either version 3 of the License, or
639 (at your option) any later version.
640
641 This program is distributed in the hope that it will be useful,
642 but WITHOUT ANY WARRANTY; without even the implied warranty of
643 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
644 GNU General Public License for more details.
645
646 You should have received a copy of the GNU General Public License
647 along with this program. If not, see <https://www.gnu.org/licenses/>.
648
649 Also add information on how to contact you by electronic and paper mail.
650
651 If the program does terminal interaction, make it output a short
652 notice like this when it starts in an interactive mode:
653
654 <program> Copyright (C) <year> <name of author>
655 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
656 This is free software, and you are welcome to redistribute it
657 under certain conditions; type `show c' for details.
658
659 The hypothetical commands `show w' and `show c' should show the appropriate
660 parts of the General Public License. Of course, your program's commands
661 might be different; for a GUI interface, you would use an "about box".
662
663 You should also get your employer (if you work as a programmer) or school,
664 if any, to sign a "copyright disclaimer" for the program, if necessary.
665 For more information on this, and how to apply and follow the GNU GPL, see
666 <https://www.gnu.org/licenses/>.
667
668 The GNU General Public License does not permit incorporating your program
669 into proprietary programs. If your program is a subroutine library, you
670 may consider it more useful to permit linking proprietary applications with
671 the library. If this is what you want to do, use the GNU Lesser General
672 Public License instead of this License. But first, please read
673 <https://www.gnu.org/licenses/why-not-lgpl.html>.
674