New upstream version 2.13
Dave Hibberd
2 years ago
0 | 12 |
0 | 12 |
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 | /* 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 <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 | 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
23 | 23 | not be what you're looking for or expecting for a node based plugin |
24 | 24 | |
25 | 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 | ||
26 | 42 | axMail 2.12.1 |
27 | 43 | Updated January 17, 2021 |
28 | 44 | - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail |
10 | 10 | #include <pwd.h> |
11 | 11 | #include <crypt.h> |
12 | 12 | #include <error.h> |
13 | #include <grp.h> | |
13 | 14 | |
14 | 15 | #include "config.h" |
15 | 16 | #include "axmail.h" |
20 | 21 | |
21 | 22 | /* Parse c-style escapes (neat to have!) */ |
22 | 23 | |
24 | // int setgroups(void); | |
25 | ||
23 | 26 | static char *parse_string(char *str) |
24 | 27 | { |
25 | 28 | char *cp = str; |
12 | 12 | #include "mbox.h" |
13 | 13 | #include "utils.h" |
14 | 14 | #include "quit.h" |
15 | ||
16 | void getsig(char *signature); | |
17 | void getaddy(char *forward); | |
15 | 18 | |
16 | 19 | struct cmd Mailcmds[] = { |
17 | 20 | { "?", do_help }, |
2 | 2 | * defines.h - Compile-time configuration |
3 | 3 | */ |
4 | 4 | |
5 | #define VERSION "axMail-Fax v2.12.2" | |
5 | #define VERSION "axMail-Fax v2.13" | |
6 | 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 | 7 | #define PROMPT "=> " |
8 | 8 |
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 |