axmail-2.12.2/0000755000175000017500000000000014001363657011750 5ustar n1uron1uroaxmail-2.12.2/mbox.c0000664000175000017500000001766613254532003013073 0ustar n1uron1uro /* * mbox.c - Read, parse and write the system mailbox * * Much taken from mailx-5.3b, which is * Copyright (c) 1980 Regents of the University of California. */ #include #include #include #include #include #include #include #include #include "mbox.h" #include "utils.h" #include "defines.h" #include "config.h" #include "head.h" FILE *mbox; /* Temporary mailbox in /tmp */ struct message *message; /* Message list */ struct message *dot; /* Current message pointer */ int messages = 0; /* Amount of messages in list */ int current = 0; /* Current message index */ int newm = 0; /* New messages */ long sysboxlen = 0; /* Length of the system mailbox at reading */ /* It will increase if new arrives */ /* Check if we have this message in the message list yet */ int havemessage(char *id) { int i; for (i = 0; i < messages; i++) { if (!strcmp(message[i].id, id)) return 1; } return 0; } /* Open a temp file by creating and unlinking. Return the open file descriptor. */ int opentemp(char file[]) { int f; if ((f = open(file, O_CREAT|O_EXCL|O_RDWR, 0600)) < 0) panic("opentemp: could not open file"); remove(file); return f; } /* Take the data out of the passed ghost file and toss it into a dynamically allocated message structure. */ void makemessage(FILE *f) { int size = (messages + 1) * sizeof (struct message); if (message != 0) free((char *) message); if ((message = (struct message *) malloc((unsigned) size)) == 0) panic("Insufficient memory for %d messages", messages); dot = message; size -= sizeof (struct message); fflush(f); lseek(fileno(f), (long) sizeof *message, 0); if (read(fileno(f), (char *) message, size) != size) panic("Message temporary file corrupted"); message[messages].m_size = 0; message[messages].m_lines = 0; message[messages].receipt = NULL; message[messages].from = NULL; message[messages].date = NULL; message[messages].subj = NULL; message[messages].id = NULL; fclose(f); } /* Append the passed message descriptor onto the temp file. If the write fails, return 1, else 0 */ void append(struct message *mp, FILE *f) { if (fwrite((char *) mp, sizeof *mp, 1, f) != 1) panic("append: Could not append message"); } /* Copy mailbox from ~/mail/mbox and /var/spool/mail to /tmp (yo2loj - 13 april 2003) */ int getmail(void) { struct stat stb; FILE *ibuf; FILE *mestmp; char buf[LINESIZE]; int count; long offset = 0; int inheader = 0; int maybe = 1; char *cp = NULL; char c; struct message this = { MUSED|MNEW, 0, 0, 0 }; if ((mbox = fopen(tempMail, "w")) == NULL) panic("getmail: Could not create temporary file"); if ((ibuf = fopen(userbox, "r")) == NULL) goto sysbox; if (fstat(fileno(ibuf), &stb) < 0) { printf("Ouch, could not fstat() mailbox.\n"); syslog(LOG_NOTICE, "getmail: Could not fstat()"); fclose(ibuf); goto sysbox;; } switch (stb.st_mode & S_IFMT) { case S_IFREG: /* Good, a regular file */ break; default: /* Yuck, i won't eat THAT! */ fclose(ibuf); goto sysbox; } if (stb.st_size == 0) { /* Zero-sized mailbox? */ fclose(ibuf); goto sysbox;; } /* copy old read mail */ while (fgets(buf, LINESIZE, ibuf) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, mbox); if (ferror(mbox)) panic("getmail: Could not write temporary file"); } fclose(ibuf); sysbox: if ((ibuf = fopen(mailbox, "r")) == NULL) goto rdexit; if (fstat(fileno(ibuf), &stb) < 0) { printf("Ouch, could not fstat() mailbox.\n"); syslog(LOG_NOTICE, "getmail: Could not fstat()"); fclose(ibuf); goto rdexit; } switch (stb.st_mode & S_IFMT) { case S_IFREG: /* Good, a regular file */ break; default: /* Yuck, i won't eat THAT! */ fclose(ibuf); goto rdexit; } if (stb.st_size == 0) { /* Zero-sized mailbox? */ fclose(ibuf); goto rdexit; } /* copy unread and new mail */ while (fgets(buf, LINESIZE, ibuf) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, mbox); sysboxlen += count; if (ferror(mbox)) panic("getmail: Could not write temporary file"); } fclose(ibuf); rdexit: fclose(mbox); /* all mail is now in temp file - digest it! */ if ((c = opentemp(tempMesg)) < 0) exit(1); if ((mestmp = fdopen(c, "r+")) == NULL) panic("getmail: Could not open temporary file"); if ((mbox = fopen(tempMail, "r")) == NULL) panic("getmail: Could not open temporary file"); for (;;) { if (fgets(buf, LINESIZE, mbox) == NULL) { /* End of file */ append(&this, mestmp); makemessage(mestmp); if (fclose(mbox)) panic("getmail: Could not close temporary mailbox"); return 0; } count = strlen(buf); buf[count - 1] = '\0'; if (maybe && buf[0] == 'F' && ishead(buf)) { messages++; newm++; append(&this, mestmp); this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; this.m_offset = offset; this.receipt = NULL; this.subj = NULL; this.from = NULL; this.date = NULL; this.id = NULL; inheader = 1; } else if (buf[0] == 0) { inheader = 0; } else if (inheader) { if (!strncasecmp(buf, "Status: ", 8)) { cp = &buf[8]; if (strchr(cp, 'R') != NULL) this.m_flag |= MREAD; if (strchr(cp, 'O') != NULL) { this.m_flag &= ~MNEW; newm--; } } if ((!strncasecmp(buf, "Disposition-Notification-To:", 28)) && (this.receipt == NULL)) { cp = &buf[28]; while ((*cp) && (isspace(*cp))) cp++; this.receipt = strdup(cp); } if ((!strncasecmp(buf, "Subject:", 8)) && (this.subj == NULL)) { cp = &buf[8]; while ((*cp) && (isspace(*cp))) cp++; this.subj = strdup(cp); } if ((!strncasecmp(buf, "From:", 5)) && (this.from == NULL)) { cp = &buf[5]; while ((*cp) && (isspace(*cp))) cp++; this.from = strdup(cp); } if ((!strncasecmp(buf, "Date:", 5)) && (this.date == NULL)) { cp = &buf[5]; while ((*cp) && (isspace(*cp))) cp++; this.date = strdup(cp); } if ((!strncasecmp(buf, "Message-ID:", 11)) && (this.id == NULL)) { cp = &buf[11]; while ((*cp) && (isspace(*cp))) cp++; this.id = strdup(cp); } } offset += count; this.m_size += count; this.m_lines++; maybe = buf[0] == 0; } return 0; } /* Read a message */ int readmesg(int msg, int verbose) { int i, line = 0; int inhdr = 1; char buf[LINESIZE]; if ((msg < 1) || (msg > messages)) { printf("There's no message %i.\n", msg); return -1; } if ((mbox = fopen(tempMail, "r")) == NULL) { printf("Could not open temporary mailbox.\n"); return -1; } i = msg - 1; dot = &message[i]; if (fseek(mbox, dot->m_offset, SEEK_SET)) { printf("readmesg: Could not fseek to message %i.\n", msg); return -1; } current = msg; printf("Message %i:%s%s%s\n", msg, ((dot->m_flag & (MREAD|MNEW)) == MNEW) ? " (New)" : "", ((dot->m_flag & (MREAD|MNEW)) == 0) ? " (Unread)": "", ((dot->m_flag & (MDELETED)) == MDELETED) ? " (Deleted)" : "" ); dot->m_flag |= MREAD; dot->m_flag ^= (dot->m_flag & MNEW); for (;;) { if (fgets(buf, LINESIZE, mbox) == NULL) { /* End of file */ fclose(mbox); return 0; } line++; if (inhdr) { /* Headers */ if (((verbose) && (line != 1) && (strncasecmp(buf, "Status: ", 8)) && (strncasecmp(buf, "X-Status: ", 10)) ) || (!strncasecmp(buf, "Date:", 5)) || (!strncasecmp(buf, "From:", 5)) || (!strncasecmp(buf, "To:", 3)) || (!strncasecmp(buf, "Cc:", 3)) || // (!strncasecmp(buf, "Disposition-Notification-To:", 3)) || (!strncasecmp(buf, "Subject:", 8))) printf("%s", buf); if (!strcmp("\n", buf)) { inhdr = 0; } } else { /* Data */ if (line == dot->m_lines) { fclose(mbox); return 0; } printf("%s", buf); } } return 0; } axmail-2.12.2/lock.h0000664000175000017500000000007313254532003013043 0ustar n1uron1uro extern int lock_fd(int fd); extern int unlock_fd(int fd); axmail-2.12.2/UPGRADING0000664000175000017500000000067213254532003013212 0ustar n1uron1uroIf you are upgrading axmail from ver 1.0.1, all you really need to do is copy the binary over the existing one. ** version 2.9 requires a new field to be added to axmail.conf! make upgrade will back up your old file. You can copy it back over and add "SysopMail if you wish. If you are upgrading axMail from any version equal to or earlier than 1.0.0 back up your /etc/ax25/axmail.conf file and do a full install. axmail-2.12.2/FAQ0000664000175000017500000001335113254532003012277 0ustar n1uron1uroaxMail - an SMTP mailbox for the various linux node frontends. axMail appears to work with most linux based MTAs (Mail Transport Agent) but not all, and I haven't had a chance to test it with them all either, nor do I honestly care to install every MTA available for linux to do such so if you do run an MTA *not listed* below, please feel free to email me at: and I'll add your report to this list. Consider this file a 'work in progress' as with the software itself. How to test is listed at the bottom. PostFix - tested fine Exim - tested fine Smail** - failed tests, and also causes a total loss of end user mail! Sendmail* - Qmail*** - * - In theory, the sendmail MTA should be ok since both exim and postfix have sendmail compatable binaries/symlinks/etc. ** - I don't know what it is with the smail MTA, but for some reason *all* mail gets lost during the internal transfers from the system mailbox and back to the system mailbox. Since smail has basically been abandoned in favor of exim, I don't personally foresee this as an issue. ***- I've never installed a qmail system before and honestly don't feel like doing that now hi!.. so if you run qmail and it works ok, please let me know and I'll change it's status If there's an MTA that I have missed and you've tested it and it works please inform me and I'll add your results here. How to test axmail: You can run axmail at a command prompt!.. all it requires is that you put your callsign after it. BEFORE you run this via a commandline however I strongly suggest you make a backup of your system mail spool file by typing: cp /var/spool/mail/call /var/spool/mail/call.bak this way here if there is an issue and you have mail waiting, you won't lose any mail. I'll assume your account on your box is your callsign, so in my case I would execute: n1uro@nat-client0:~$ /usr/sbin/axmail n1uro and the standard greetings should appear along with the prompt and any mail waiting should appear listed. Pending the above test worked ok and unread/undeleted mail was saved back into the system mailbox, try it from the node as a user who doesn't have an account on the box. Hopefully when you exit, it'll tell you that you have new mail waiting! Go back in and you should see the welcome.txt file from /etc/ax25 listed as a greeting email message. Other quick FAQs: axMail works by comparing the user's system mail spool file, and as well as any existing axMail saved mail and merges them together 'offline' for lack of a better word to use. It then takes this mail and allows the user to read/reply/delete/save/etc. axMail has *always* supported file attachments, after all a file attachment is just an encoded file appended to the body of the email message... its just that most every client now-a-day automatically encodes/decodes them for you and you assume that a file attachment is a seperate entity. All you need to do to send and receive attachments via a packet terminal is the following (examples taken from a linux terminal); Sending: First encode the file by using uuencode. To do this run uuencode filename filename or if you want to make a file of it run: uuencode file file > file1 then copy and paste that encoded text in it's full into the body of the mail message and send it. Receiving: copy and paste the output of your message into a temporary file and then run "uudecode -o filename tempfile". You will now have a pdf/doc/text/jpg file sent to you by someone. axMail now supports sending of fax transmissions! To configure axMail to be able to do such, configure an account with an online fax service such as eFax where you can email faxes and put the email address you'd use to send faxes to in a _new line_ called "FaxGate" inside /etc/ax25/axmail.conf. When users attempt to send a fax, your account will be hidden from them and all they'll see is that they're sending to "a" fax gateway system. People have asked about why new incoming mail isn't seen until after the user logs out of axMail. If axMail read directly off of the system mailspool file, then it'd lock out any new incoming mail from being posted to the user's mailbox as it'd have a lock on the spool file, and the message numbers could also possibly change while the user goes to select a message number to read. This would be very confusing to the end user. If you wish to allow users to use the internet or packet TCP/IP to pop3 their mail from your system, they may do so... however keep in mind, any mail they read or list manually within axMail will have it's status changed from "new". As we all know about the pop3 protocol, mail not flagged as "new" isn't popped but it's considered as if the client is using a software package such as eudora or outlook (to name a couple... notice which I listed first? hi!) and they have their options set to leave a copy of their mail on the server. The user will have to log into your node and retrieve their mail from there. After all, isn't part of running packet node services is to encourage hams to actually use their radios to get to such things? :) All you as sysop/root on the box need to do is ensure that a pop3 daemon is installed and running, and that you configure axMail.conf to give the end user proper permissions in their shell to be able to use your pop3 daemon. I've gone to many days worth of studying how most boxes are configured I've taken it upon myself to try and get axMail as 'bullet proof' and as simple a process as it can possibly be. Unfortunately the program can not read your mind so you'll have to do *some* config work to it... but otherwise it should be a nice low-ram low-resource system for you and your users to enjoy. Comments and questions are always welcomed! 73 de Brian N1URO axmail-2.12.2/INSTALL0000664000175000017500000000677513624060770013022 0ustar n1uron1uroaxMail - an SMTP mailbox for the various linux node frontends and outbound FAX engine. Current author: Brian Rogers (N1URO) Past author: Marius Petrescu (YO2LOJ) Creator: Heikki Hannikainen (OH7LZB) Additional Submissions: Stefano (IW3IJQ) As with any of the softwares I tweek n geek, *use at your own risk*! With that said, and the fact that this is GPL software if you find something that's borked... don't just submit a bug report. Fix it if you can. Rerelease it under your own callsign if you wish, or feel free to send me your code and I'll import it in. This is probably one of the simplest packages to install and configure! After you run tar zxvf axmail-###.tgz cd axmail-#### (which is where you should be now if you're reading this :) ) and run: make; make install Note: If you have clamsmtp and your clamsmtpd.conf is in /usr/local/etc, symlink it to /etc. (on newer gcc/libs I do know that there's a warning after it makes but it doesn't prevent the binary from compiling and so far it seems to test ok. I'll fix that if and when I get the chance but don't hold your breath on it hi!) cd /usr/local/etc/ax25 and using your favorite editor (vi, joe, pico, etc) and edit axmail.conf. In here you can specify how you wish the mailbox to handle accounting for end users. On *most* linux systems, the default should be "ok" but if you wish to have users contact you first, or if you wish to have the system auto-create a standard shell login, or popmail account for the users, etc... you may do so in the file. Double check your settings (it *is* possible you can configure axmail.conf so that everyone has root-group access... but why would you wish to do that? You've been *warned* so double check your config settings for auto-creation of accounts before saving!) The file is well commented to assist you. When you're finished and have become an expert, if you wish to you can delete the comment lines. You may also customize the file "welcome.txt" in /usr/local/etc/ax25/ if you wish to also. I suggest leaving the first line as-is as this is the so called "new user" welcome greeting email. I've supplied a basic and short greeting email message that users will get once they've created their mailbox. If you would rather new users email your mail account directly instead of root, you may wish to change that line. For the software itself... believe it or not, you're *DONE*! That's all! However... now we need to get it hooked into which ever node frontend you run so that users have a way of accessing it. axMail runs as an external process (ExtCmd) to the node. I've tested it with URONode (obviously) and with LinuxNode by Tomi. To do this cd /usr/local/etc/ax25 and using your favorite editor open node.conf and add the following line to your ExtCmds: ExtCmd MAil 1 root /usr/local/sbin/axmail axmail %u (note: MA in the word MAil is in CAPS) Save uronode.conf and telnet in to test! It should work just fine. Since you would have an existing account on your server, it's unlikely that you'll get the welcome message, but since you can edit it, you'll know what it says :) **ERROR 1** *** Note: If you're installing axMail-FAX via source, but your MTA (aka: postfix) was installed from repository packaging, you may need to create a symlink to your users mail file directory... typically: /var/spool/mail/ -> /usr/local/var/spool/mail/ If you don't do this, users will NOT see their incoming mail. *** Happy mailing! axmail-2.12.2/axmail.h0000664000175000017500000000014713254532003013370 0ustar n1uron1uro extern int parse_args(char *argv[],char *cmd); extern int cmdparse(struct cmd *cmds, char *cmdline); axmail-2.12.2/Makefile0000664000175000017500000000324514001130535013401 0ustar n1uron1uroall: axmail MAN_DIR = /usr/local/share/man CC = gcc LD = gcc CFLAGS = -O2 -Wstrict-prototypes -g -I../lib LIBS = -lcrypt MODULES = utils.o config.o adduser.o command.o mailcmd.o mbox.o head.o lock.o axmail.o quit.o .c.o: $(CC) $(CFLAGS) -c $< upgrade: installbin installhelp installman install: installbin installconf installhelp installman installbin: all install -m 0755 -s -o root -g root axmail /usr/local/sbin installconf: install -m 755 -o root -g root -d /usr/local/etc/ax25 install -b -m 644 -o root -g root etc/axmail.conf /usr/local/etc/ax25 install -m 644 -o root -g root etc/welcome.txt /usr/local/etc/ax25 installhelp: install -m 755 -o root -g root -d /usr/local/var/lib/ax25/axmail/help install -m 644 -o root -g root etc/help/*.hlp /usr/local/var/lib/ax25/axmail/help installman: install -m 644 -p man/axmail.8 $(MAN_DIR)/man8 install -m 644 -p man/axmail.conf.5 $(MAN_DIR)/man5 back: rm -f ../mail.tar.gz tar cvf ../mail.tar * gzip ../mail.tar clean: rm -f axmail *.o *~ *.bak core etc/*~ etc/help/*~ distclean: clean rm -f axmail axmail: $(MODULES) $(LD) -o axmail $(MODULES) $(LIBS) $(LDFLAGS) utils.o: utils.h utils.c mbox.h config.o: config.h config.c defines.h axmail.h utils.h adduser.o: adduser.h adduser.c utils.h config.h defines.h command.o: command.h command.c config.h mailcmd.h mbox.h utils.h quit.h mailcmd.o: mailcmd.h mailcmd.c defines.h utils.h mbox.h config.h mbox.o: mbox.h mbox.c utils.h defines.h config.h head.h head.o: head.h head.c defines.h utils.o: utils.h utils.c lock.o: lock.h lock.c utils.h quit.o: quit.h quit.c config.h lock.h axmail.o: axmail.h axmail.c config.h adduser.h utils.h quit.h mbox.h axmail-2.12.2/README0000664000175000017500000006140214001140711012615 0ustar n1uron1uroaxMail - an SMTP mailbox for the various linux node frontends. PREFACE: First off, sincere thanks to those who have written to tell me that they use axMail, like what I've done to axMail, and for the enthusiasm shown via words and/or code contributions for the program in hopes of keeping packet radio networks around the world alive! INTRO: Greetings and thanks for taking a look at the program. Below I've posted a kind of history of the program to the best of my knowledge taking text from existing files. Rather than trying to reinvent the wheel and after seeing this program before on Labrat's radio.linux.org.au site, I decided to try and give some life into it... partially with the assistance of Phil N1XTB nudging me pretty consistantly for many months in helping him get an SMTP agent in his linux based packet node server without having to install an xNOS overhead node ontop it. :) Please do take a moment and read the text based files included with this package so you're a bit familiar with what it does so that you don't get a false perception as to what it can and/or can not do. axMail just might not be what you're looking for or expecting for a node based plugin CHANGE HISTORY: axMail 2.12.1 Updated January 17, 2021 - Maintenance release moving /var/ax25/axmail to /var/lib/ax25/axmail to honor linux file system rules. - Changed defines.h to reflect this version. axMail 2.12 Updated August 17, 2020 by Brian Rogers (N1URO) - After fussing with an updated ClamSMTP system that appears to have some issues at least in regards to the Debian repositories I have come to learn that the MTA used (postfix) beginning with version 2.3 now may use milter (mail filter) systems. Details on how to configure the newer ClamAV-Milter system are at https://uronode.n1uro.com/linux/ under the ClamSMTP link at the bottom of the page. This is quite a major enhancement to axMail-Fax! Since now it will scan for either clamsmtp OR clamav-milter the outputs on mails show only that the mail has been scanned by ClamAV. axMail 2.11.1 Updated February 21, 2020 by Brian Rogers (N1URO) - removed the #ifdef CLAMSMTP routine from config.h - fixed my routine for checking for /etc/clamsmtpd.conf so that it no longer needs to be previously defined in config.h and auto senses now in mailcmd.c. It dawned on me that the reason it was segfaulting if there was no .conf file that trying to fclose() a file that did not exist was the reason that it was causing axmail to segfault. - made this version 2.11.1 in defines.h. - updated INSTALL and README to reflect history and instructions. - updated Makefile so make upgrade does not replace config files since it's not required if you're simply upgrading from axmail-2.9 or greater. axmail 2.11 Updated February 18, 2020 by Brian Rogers (N1URO) - Figured out how to add ClamSMTP to the mail system's MTA. Details are posted on https://uronode.n1uro.com/linux/axclamsmtp.shtml This will scan for viri both IN and OUT bound mails! Very handy! - Added a define routine in config.h now. You must #define or #undef CLAMSMTP based on whether or not you're running clamsmtp and have /etc/clamsmtpd.conf in existance. If it's elsewhere on your system create a symlink to it and you'll be fine. - added the fact when #defined where mails are tagged with the fact that your mail is being scanned by CLAMSMTP. This was done in mailcmd.c - upped the version to 2.11 in defines.h - added notes in INSTALL in regards to the new #define in config.h axmail 2.10 Updated April, 2019 by Brian Rogers (N1URO) - added online help for the "Delivery Receipt" command. This keeps it in line with all the other online helps. - modified defines.h with this version number and also increased the year that I'm still working on modifications to the project. axmail 2.9 Updated March, 2018 by Brian Rogers (N1URO) - Removed asking for password upon new user login, instead added a new field to axmail.conf for "SysopMail". Now the sysop has to put in their email address as to inform the end user to request their desired password into the system, especially if the sysop is running pop/imap features on their system. This will prevent users from entering in plain text passwords via unencrypted RF paths unlike other systems such as WL2K. I feel this is a major security fix for axMail-FAX. - added some line feeds in quit.c per suggestion of Tomasz SP2L so if another program changed the user's mail spool file the warning displays clearer. - changed version number to 2.9 in defines.h and changed the end year of maintenance from 2017 to 2018. axmail 2.8 Updated November, 2017 by Brian Rogers (N1URO) Changes: - added SPers as a command per the suggestion of VE1JOT. This was done in command.c and was actually quite simple to impliment. The logic behind it is to match the mail send command sets with those of standard PBBS messaging commands. * Note: The station who mainly requested this feature via VE1JOT, KB9PVH urged that flags, cc, and bcc options be supressed to make it more user friendly on HF at 300 baud. While I'm really NOT a fanatic about this, I do have compassion for those on HF. Steve gave me a different idea than what I was going to do but I did impliment it into mailcmd.c, mailcmd.h and command.c. If one needs a read receipt or to send cc/bcc copies of their message then S still is an option. - added a "spers" .hlp file to the archive. - changed defines.h to reflect version 2.8. - updated welcome.txt to be more generic rather than be version specific. - modified mailcmd.c to now prompt for a "carbon copy" address when sending mail. This allows for a duplicate of the message to be sent to the second person one wishes to copy on the mail. - edited this file. - while I was at it, I decided to add a "blind carbon copy" feature. This will send a copy of a message to the user specified HOWEVER, they will NOT be listed in the recipient listings. For those using raw terminals, it's possible to NOT enter a 'cc' but still enter a 'bcc' address. - edited help files: send.hlp and spersonal.hlp to help guide users on how to best send mail. - created a bypass method so that if users did not wish to use cc or bcc mail, they can bypass them instead of being prompted for them - suggested by VE1JOT. - added online help for send/sp|cc|bcc mail. - added a new signature file function to the system in both command.c and in mailcmd.c. If no signature file exists, it will instruct the user on this fact and also inform them how to make one using the new SIgnature command. Note: If no ~/.signature file exists mail will still be sent, just without a 1 line siguature (max: 79 characters). - bullet proofed both the autoforward and signature file routines in command.c by insuring that a null string not only halts execution of both but also removes both ~/.forward and ~/.signature files respectively. - cleaned up the send signature a bit and added my little spam ad even if there is no signature file present. This was done in mailcmd.c. - added a string in the signature prompt which informs users how to clear their signature if they desire such. This was done in utils.c - Added special critical instructions to INSTALL. I didn't know if I had these in there or not but SP2L informs me I did not. Thanks to Tomasz. - Fixed a bug that when the mailbox file(s) weren't found for the system MTA (aka: postfix) axMail would segfault. Now not only does it not segfault but also instructs the user to inform the sysop of this error. This bug existed since version 0.0.1. I've been wanting to do something about this for IONs but didn't get to it until now. This was done in quit.c - Fixed a couple of typos in README. I have a very difficult keyboard! - Per the suggestion of G4APL (who gives us many great ideas - and why do I refer to myself in plural? I need a DIET!) I did two things: 1 - when listing mail there's no message date stamp within the listing. added in mailcmd.c 2 - reordered the mail listing fields where I felt they'd make the most sense. Message subject, then message date, then message size are the last 3 fields listed. They should also be kept in a column justified manner of sorts. 3 - added a (St)atus header so the user has a better definition of the status of a specific message. axmail 2.7 Updated 18 May, 2017 by Brian Rogers (N1URO) Changes: - Thanks to Van W1WCG, a bug was spotted in the SR command where if the user entered a parameter such as a message number for example, it wouldn't properly function. This has been fixed. Thanks Van! - Forgot to take the "beta" tag out for 2.6. Oops. Fixed. - I know in the past I had a 'cc' command for sending mail, and it's been suck in my craw to readd it since. axmail 2.6 Updated 22 September, 2016 by Brian Rogers (N1URO) Changes: - changed version number in defines.h - fixed error message when a pop client has deleted mail from the main mail spool file. - removed excessive receipt warning spotted by a gent who identifies himself as rigor. This was in mailcmd.c in do_readmsg() - while looking at the end of that routine, it just gave me an itch that said "if you can look for a warning about a requested receipt, then numbnutz you can offer the reader a chance to just generate a receipt without having to do "SR" as previously stated at the end of the mail. So, with that said and to get feeling back in my genitals, I wrote a routine that asks the reader if they wish to send a receipt, and it also echos where it's destined and confirmation it was sent. - added an "--- end of message #* ---" tag at the end of mail when it as finished displaying. This was done in mailcmd.c - fixed an existing bug in the message routines where for each message it wasn't resetting the receipt pointer! This bug existed since I introduced the receipt "finder" in the messages. I'm shocked that it wasn't reported to me by someone earlier. Now *only* if a message has requested a receipt will it show that a receipt has been asked for... whew! - So many missing online help files! Again I'm surprised no one brought this to my attention. How did we get along with them? "Oh my!" - Sulu - Updated this README file. axmail v2.5.1 Updated 28 September, 2015 by Brian Rogers (N1URO) Changes: - added axmail.8 man page as per spec of Debian downstream. - modified Makefile to include axmail.8 manpage installation for both new and upgrade options. - modified defines.h and this document to reflect maintenance release. axmail v2.5 Updated 30 May, 2015 by Brian Rogers (N1URO) Changes: - added new delivery receipt function to the send routine. This compliments the read receipt function in the event of high priority mail. Typically the read receipt is an option generated by the recipient who may not decide to generate one. At least this modification ensures with an ESMTP delivery that the sender using axMail will get a reciept from "MAILER-DAEMON" which will verify the status of delivered mail. This change was done in mailcmd.c and is designed with the sendmail binary included with postfix. - updated this README file. - updated version number in defines.h axmail v2.4 Updated 25 April, 2015 by Brian Rogers (N1URO) Changes: - cleaned up mbox.c where I had originally placed the receipt checker routine in. This caused loops within the buffer that displayed the message. The true routine lives in mailcmd.c - added patch to Makefile provided by Jaroslav at Red Hat for distribution downstream compiles to make packages. - changed version in defines.h - major change in command.c, added a new Autofwd command to allow users to auto-forward mail from a remote system to their "home" axMail-FAX base system. Could also be used to forward mail to their internet accounts. - added autofwd.hlp file. - alphabetized the commandset listing, removed redundantly spelled commands. - reworked Makefile and added an "upgrade" option so new files ONLY are deployed after make. Execute using: "make upgrade" - updated this file. axmail v2.3.1 Updated 5 February, 2015 by Brian Rogers (N1URO) Changes: - added a flag in mailcmd.c where if the request for a receipt exists in a mail message, a bell and a warning sign is generated after the message has been read by the user with instructions to use SR to generate a receipt. This was a difficult routine for me to think of considering the various race conditions that can be expected and met. - updated welcome.txt with version upgrade and new feature list. - updated README. axmail v2.3 Updated 5 February, 2015 by Brian Rogers (N1URO) Changes: - Added a new "Receipt" request flag in mailcmd.c by request of Mitch AB4MW. This defaults to NO but when flagged to YES, a request will be sent to the remote client's agent. If the agent supports such, they will be prompted whether or not to honor your receipt request. This is history as NO AGENT FOR PACKET TERMINALS SUPPORTS THIS! The function of a generated read receipt is similar to how HylaFax generates confirmation of transmission receipt mails to your mailbox. Currently mail read in axMail will NOT generate a receipt back. I may work on this later, but for now it doesn't exist. * My thoughts of the receipt function is negative. The fact that I may be sending notification that I'm in my email client to a remote destination IMHO is such that a webcam may as well be turned on and watch me do email, and send the stream to "Big Brother" and I don't mean the television show. - Updated defines.h with the new version number. - Updated welcome.txt so the new version number is displayed. axmail v2.2 Updated 25 December, 2014 by Brian Rogers (N1URO) Changes: - Made some maintenance changes, but forgot to log them in here. axmail v2.1.1 Updated 30 October, 2014 by Brian Rogers (N1URO) Changes: - Makefile Code provided by Bob Tenty VE3TOK to make it more compatable with newer GCC compiler requirements. - utils.c Code provided by Bob Tenty VE3TOK to fix a warning produced when compiling. - defines.h Changed version number to reflect the changes incorporated by Bob Tenty VE3TOK and committed to the subversion repository. axmail v2.1 Updated 31 July, 2014 by Brian Rogers (N1URO) Changes: - axmail.c Code provided by Jaroslov OK2JRQ fixes a potential security hole in the system privilege matching. - global axMail is now under review for considerations as standard packaging in RedHat's fedora project. It appears it's going to be added as a package. axmail v2.0 Updated 8 July, 2013 by Brian Rogers (N1URO) Changes: - defines.h Updated version number to reflect version release 2.0. Version 1.0.5 was simply a maintenance test package to try and reincorporate what I had done up to version 1.0.6 which I believe was one of my last releases up to 2009. Since I've done all that I can recall at this point and time, I decided to match URONode's release numerics with a 2.0 release version. axmail v1.0.5 Updated 5 July, 2013 by Brian Rogers (N1URO) Changes: - defines.h Updated email listings to reflect the most current ones I could find including my own. Also added 2013 to the years worked on axMail by me. - quit.c Forced ALL mail, read or otherwise when user quits to save to the user's system mailbox. This is for reverse compatability with those who may also run a web-based email service on the internet such as NeoMail, EMUMail, etc. Prior, the system was supposed to separate any read mail (and all accompanying mail in that session) to the axmail ~/mbox file. We don't want this for the specific reason of "reverse email client" compatability. axmail v1.0.4 Updated 23 May, 2008 by Brian Rogers (N1URO) Changes: - setpwnam.c Changed the way SIGPIPE was handled. Instead of being ignored, it will now read a SIGQUIT properly if a QUIT is signaled to axmail either via a shell prompt, or a node frontend. I've been noticing especially on some timeouts that temp files don't flush as they should and the user's directory can start to fill up. axMail v1.0.3 Updated 2 December, 2007 by Brian Rogers (N1URO) Changes: - mailcmd.c Reset the way I wanted to handle the user input routine for sending faxes. Commented out some more unneeded/unused code in the do_fax routine... will clean it up in next release or so. - mailcmd.c cleaned up a bug I introduced in the never released 1.0.2 where the X-Mailer was duping itself after each line of the body of a message. - sfax.hlp Reworded the SFax help file to help show some examples of how to format the header. axMail v1.0.2 Updated 24 November, 2007 by Brian Rogers (N1URO) Changes: - mailcmd.c Cleaned up some of the code in SFax. Also made some cosmetic changes. axMail v1.0.1 Updated 31 October, 2007 by Brian Rogers (N1URO) Changes: - mailcmd.c Added a new routine to allow users to send faxes. This is defined by the command "SF" for Send Fax. The routine was taken from the "S"end function however since it's a one-way transmission, there is no reply available nor is there an option for users to fax to any fax service as some I know are pay services. - config.h added definitions for faxgate in axmail.conf - config.c added routine to allow for faxgate as a variable and be called from mailcmd.c - defines.h version upgraded from v1.0.0 (unreleased - test version) to v1.0.1 - etc/axmail.conf Added new line called "FaxGate" with an example of how to properly configure this line. - etc/help/sfax.hlp Added new file "sfax.hlp" which is an online help file for the SFax command. axMail v0.0.9 Updated 26 September, 2006 by Brian Rogers (N1URO) Changes: - mailcmd.c Added a new routine that prompts the sender whether or not the message is of an emergency/high priority mail message. If it's emergency message then the headers are appended with an X-code flagged in such a manner that Eudora and Outlook will display the received mail with a red flag of sorts. The idea of such came to me in thinking of "what can I do to help improve means of emergency communications using TCP/IP, Linux, and packet radio?" Having the ability to "red flag" an SMTP message I don't believe has yet to be available in any packet messaging system... axMail I hope is the first. If a user just hits enter, or selects "no" then the mail message is sent under normal send routines. found a minor bug in my routine where if an end user answered "yes" in wanting to send an emergency/high priority message the system ignored the request and sent it as 'normal' delivery. Made a minor change to bullet-proof the responce. Added online help text if user is unsure about sending a message flagged urgent or normal. This text is available when the user is prompted for priority selection by hitting "?" at the prompt. - defines.h Version updated from v0.0.8 to v0.0.9 axMail v0.0.8 Updated 2006 by Brian Rogers (N1URO) Changes: - mailcmd.c Rewrote and incorporated code provided by IW3IJQ how axMail inserts it's version number in the X-Mailer: string. - mailcmd.c Added an X-Origin: string to show those peeking at mail headers just how the message was possibly sent... by AMATEUR RADIO! - axmail.conf Added config option in "AllowMail" for axhome, a rewrite of code submitted by Stefano IW3IJQ. While I stripped out home directory structures similar to that of qmail or axspawn, Stefano convinced me that it may be easier to manage home directories for axMail users who don't have shell access to branch out within a preset directory. - defines.h Updated version number from 0.0.7 to 0.0.8 - axmail.c and config.c Rewrote and incorporated code to allow for the routines to use what Stefano IW3IJQ originally labled "newuhome" to use "axhome". While I was at it, I rewrote and shortened the error text pushed to a user who doesn't have permission to use such a directory. * Note: When I write error texts and menus, I try to write them for users on a multi-hop 1200 baud path thus the shorter the better as long as context isn't lost and for long distance hops where full paclen may cause retries (worse yet timeouts!) axMail v0.0.7 Updated 2005 by Brian Rogers (N1URO) Changes: - cosmetics My usual "I like seeing this this way" type cosmetics... too many to mention! - adduser.c changed the hard coding of user 'home' directories so that instead of them going into a period delimited sort, just dump em all into /home/ which seems to be "the norm" on most systems I've had to assist with. - adduser.c fixed a bug where creating a user was actually causing the program to segfault upon exit the first time a user went into the mailbox! The node frontends hid this segfault as the program still flushed itself from ram but I spotted it when running it at a command prompt. The segfault came when axMail attempted to write mail back to the user's system mailbox and it didn't exist. How I fixed this is listed next. This may just be a new bug that appeared with the upgrading of libs, this I'm unsure of and since I have no desire to go backwards I have decided to actually make a minor routine... - welcome.txt New users are now sent a "welcome" message that the sysop can easily customize to their desires. It's located at /etc/ax25/welcome.txt. I figured that since axMail was segfaulting because such a file did not exist, I might as well make use of this need by having the program send the user a greeting. - defines.h Changed paths to be more in line with the more modern type configs as a default. Paths can still be defined by the sysop prior to compiling axMail. - Makefile I changed the default of make install to include all of the subroutines within the Makefile yet leaving such things as "make installbin" available as runtime options if just a binary refresh creation is desired. - other I'm sure I missed a note or two *shrug* axMail v0.0.6 Tweeks made by Marius Petrescu (?) I know there was a ver 0.0.6 which I at one time had but lost and can't seem to find it. My (n1uro) changes may have alread been incorporated. axMail v0.0.5 True mailbox functionalities created by Marius Petrescu. Added Mailbox save routines (compatible with the command line mail agent, including ~/mbox file) axMail v0.0.4 Copyright (c) 1996 Heikki Hannikainen (OH7LZB) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Don't give this one to anyone yet... it is NOT ready for distribution! This is a simple mail user agent intended to provide the mail functions in xNOS in a Linux ax.25 environment. If required, it creates a normal user account for each new user (code mostly taken from axspawn by Joerg Reuter (DL1BKE)), so that they can receive mail on the system. axMail uses sendmail (or similar) to deliver mail, and reads mail from each user's system mailbox (/var/spool/mail/username). It does not provide any means of transferring mail between hosts. axMail provides a simple, low-overhead user interface, much similar to /bin/mail, xNOS and the packet BBS systems. It's useful for providing good SMTP mail services for "dumb" ax.25 users over slow radio channels. axMail is intended to be called from node. It takes one command line argument of the user's callsign (with or without SSID). It must be run as root, but it setuid()'s itself to the respective user's privileges as soon as possible. It might run from ax25d as well. It can also be executed from a shell with user privileges. Some code (command parser, configuration file stuff) and the internal architecture was taken from the LinuxNode frontend by Tomi Manninen (OH2BNS). Thanks! INSTALLATION: See the file: INSTALL TODO: Suggestions? -- Brian Rogers [n1uro@n1uro.#cct.ct.usa.noam] ftp://ftp.n1uro.net/pub/hamradio/packet axmail-2.12.2/setpwnam.h0000664000175000017500000000007613254532003013754 0ustar n1uron1uro #include extern int setpwnam (struct passwd *pwd); axmail-2.12.2/utils.c0000664000175000017500000000605613254532003013255 0ustar n1uron1uro /* utils.c - common utilities */ #include #include #include #include #include #include #include #include "utils.h" #include "mbox.h" #include "config.h" //extern int sys_nerr; /* Send the prompt */ void prompt(void) { printf("%s@%s\nCurrent message %i of %i\n=> ", callsign, hostname, current, messages); } /* Prompt for email forwarding */ void getaddy(char *forward) { char email[79]; 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"); strcpy(forward, email); } /* Prompt for signature */ void getsig(char *signature) { char email[79]; getstr(email, 79, "Hit enter to remove or type your signature here:\n"); strcpy(signature, email); } /* Prompt for name */ void getname(char *uname) { char nam[81]; rename: getstr(nam, 80, "Enter your name (? for help): "); if (!strcmp(nam, "?")) { printf("The name entered will be used in the From: header of the messages you send.\n"); printf("It will also be shown in finger queries and a number of other places.\n"); printf("It is usually set to your full name, but you may also use a nickname\n"); printf("your friends know.\n"); goto rename; } if (strlen(nam) > 30) { printf("The length of the name is limited to 30 characters.\n"); goto rename; } if (anyof(nam, "=<>()|:;!\\\",")) { printf("Characters = < > ( ) | : ; ! \\ \" , are not allowed.\n"); goto rename; } if (anycntrls(nam)) { printf("Control characters are not allowed.\n"); goto rename; } strcpy(uname, nam); } /* Get a string from the user, with maximum length limit */ void getstr(char *str, int len, char *prompt) { char *p; printf("%s", prompt); fflush(stdout); fgets(str, len, stdin); /* Strip CR */ p = strchr(str, '\n'); if (p != NULL) strcpy(p, ""); } /* Convert a string to upper case */ char *strupr(char *s) { char *p; if (s == NULL) return NULL; for (p = s; *p != '\0'; p++) *p = toupper(*p); return s; } /* Convert a string to lower case */ char *strlwr(char *s) { char *p; if (s == NULL) return NULL; for (p = s; *p != '\0'; p++) *p = tolower(*p); return s; } /* Check if any of the characters in the two strings match. */ int anyof(char *s1, char *s2) { while (*s1) if (index(s2, *s1++)) return 1; return 0; } /* Check if there are any control characters in there. */ int anycntrls(char *s1) { while (*s1) if (iscntrl(*s1++)) return 1; return 0; } /* Crash, log the reason */ void panic(const char *fmt, ...) { va_list args; va_start(args, fmt); vprintf(fmt, args); putchar('\n'); syslog(LOG_NOTICE, fmt, args); va_end(args); exit(1); } /* Report an error returned from a system call. */ void syserr(const char *fmt, ...) { int e = errno; va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); /* routine changed by VE3TOK */ printf("Error number: %d\n", e); perror("The following error occured: "); } axmail-2.12.2/head.c0000664000175000017500000001056713254532003013020 0ustar n1uron1uro /* head.c - parse mail headers. Grabbed from mailx 5.3b, reformatted, hacked and cleaned to compile without warnings by Heikki Hannikainen */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */ /* * Mail -- a mail program * * Routines for processing and detecting headlines. */ #include #include #include "head.h" #include "defines.h" /* * See if the passed line buffer is a mail header. * Return true if yes. Note the extreme pains to * accomodate all funny formats. */ int ishead(char linebuf[]) { char *cp; struct headline hl; char parbuf[LINESIZE]; cp = linebuf; if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' || *cp++ != ' ') return 0; parse(linebuf, &hl, parbuf); if (hl.l_from == NULL || hl.l_date == NULL) { /* No from or date field */ return 0; } if (!isdate(hl.l_date)) { /* Date field not legal date */ return 0; } /* * I guess we got it! */ return 1; } /* * Split a headline into its useful components. * Copy the line into dynamic string space, then set * pointers into the copied line in the passed headline * structure. Actually, it scans. */ void parse(char line[], struct headline *hl, char pbuf[]) { char *cp, *sp; char word[LINESIZE]; hl->l_from = NULL; hl->l_tty = NULL; hl->l_date = NULL; cp = line; sp = pbuf; /* * Skip over "From" first. */ cp = nextword(cp, word); cp = nextword(cp, word); if (*word) hl->l_from = copyin(word, &sp); if (cp != NULL && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') { cp = nextword(cp, word); hl->l_tty = copyin(word, &sp); } if (cp != NULL) hl->l_date = copyin(cp, &sp); } /* * Copy the string on the left into the string on the right * and bump the right (reference) string pointer by the length. * Thus, dynamically allocate space in the right string, copying * the left string into it. */ char *copyin(char *src, char **space) { char *cp, *top; top = cp = *space; while ((*cp++ = *src++)) ; *space = cp; return top; } #define L 1 /* A lower case char */ #define S 2 /* A space */ #define D 3 /* A digit */ #define O 4 /* An optional digit or space */ #define C 5 /* A colon */ #define N 6 /* A new line */ #define U 7 /* An upper case char */ 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 }; 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 }; /* * Match the given string (cp) against the given template (tp). * Return 1 if they match, 0 if they don't */ int cmatch(char *cp, char *tp) { while (*cp && *tp) switch (*tp++) { case L: if (!islower(*cp++)) return 0; break; case U: if (!isupper(*cp++)) return 0; break; case S: if (*cp++ != ' ') return 0; break; case D: if (!isdigit(*cp++)) return 0; break; case O: if (*cp != ' ' && !isdigit(*cp)) return 0; cp++; break; case C: if (*cp++ != ':') return 0; break; case N: if (*cp++ != '\n') return 0; break; } if (*cp || *tp) return 0; return 1; } /* * Test to see if the passed string is a ctime(3) generated * date string as documented in the manual. The template * below is used as the criterion of correctness. * Also, we check for a possible trailing time zone using * the auxtype template. */ int isdate(char date[]) { if (cmatch(date, ctypes)) return 1; return cmatch(date, tmztypes); } /* * Collect a liberal (space, tab delimited) word into the word buffer * passed. Also, return a pointer to the next word following that, * or NULL if none follow. */ char *nextword(char *wp, char *wbuf) { char c; if (wp == NULL) { *wbuf = 0; return NULL; } while ((c = *wp++) && c != ' ' && c != '\t') { *wbuf++ = c; if (c == '"') { while ((c = *wp++) && c != '"') *wbuf++ = c; if (c == '"') *wbuf++ = c; else wp--; } } *wbuf = '\0'; for (; c == ' ' || c == '\t'; c = *wp++) ; if (c == 0) return NULL; return (wp - 1); } axmail-2.12.2/head.h0000664000175000017500000000100613254532003013011 0ustar n1uron1uro /* * Structure used to return a break down of a head * line (hats off to Bill Joy!) */ struct headline { char *l_from; /* The name of the sender */ char *l_tty; /* His tty string (if any) */ char *l_date; /* The entire date string */ }; /* in head.c */ extern char *nextword(char *wp, char *wbuf); extern char *copyin(char *src, char **space); extern void parse(char line[], struct headline *hl, char pbuf[]); extern int ishead(char linebuf[]); extern int isdate(char date[]); axmail-2.12.2/mbox.h0000664000175000017500000000304013254532003013055 0ustar n1uron1uro/* * flag bits. */ #define MUSED (1<<0) /* entry is used, but this bit isn't */ #define MDELETED (1<<1) /* entry has been deleted */ #define MSAVED (1<<2) /* entry has been saved */ #define MTOUCH (1<<3) /* entry has been noticed */ #define MPRESERVE (1<<4) /* keep entry in sys mailbox */ #define MMARK (1<<5) /* message is marked! */ #define MODIFY (1<<6) /* message has been modified */ #define MNEW (1<<7) /* message has never been seen */ #define MREAD (1<<8) /* message has been read sometime. */ #define MSTATUS (1<<9) /* message status has changed */ /* * Structure used in the message list */ struct message { short m_flag; /* flags, see below */ long m_offset; /* offset of message */ long m_size; /* Bytes in the message */ short m_lines; /* Lines in the message */ char *receipt; /* Receipt request */ char *notify; /* Delivery notify */ char *from; /* From */ char *date; /* Date string */ char *subj; /* Subject line */ char *id; /* Message ID */ char *whoti; /* Who to send a fax to */ char *phone; /* Phone to fax */ char *note; /* Note for fax cover */ }; extern FILE *mbox; /* Temporary mailbox in /tmp */ extern struct message *message; /* Message list */ extern struct message *dot; /* Current message pointer */ extern int messages; /* Amount of messages in list */ extern int current; /* Current message index */ extern int newm; /* New messages */ extern long sysboxlen; /* System mailbox length at start */ extern int getmail(void); extern int readmesg(int msg, int verbose); axmail-2.12.2/mailcmd.h0000664000175000017500000000050313622747777013550 0ustar n1uron1uro /* in mailcmd.c */ extern int do_list(int argc, char **argv); extern int do_read(int argc, char **argv); extern int do_send(int argc, char **argv); extern int do_psend(int argc, char **argv); extern int do_fax(int argc, char **argv); extern int do_kill(int argc, char **argv); extern int do_unkill(int argc, char **argv); axmail-2.12.2/config.h0000664000175000017500000000257513716516511013402 0ustar n1uron1uro #include #include "defines.h" extern char callsign[20]; extern char username[20]; extern char fullname[31]; extern char forward[79]; extern char *homedir; /* User's home directory */ extern char *fwdfile; /* User's .forward file (~/.forward) */ extern char *sigfile; /* User's .signature file (~/.signature) */ extern char *maildir; /* User's mail directory (~/mail) */ extern char *mailbox; /* System mailbox (/var/spool/mail/user) */ extern char *userbox; /* User's mailbox (~/mbox) */ extern char *mailconf; /* User's own axmail configuration */ extern int local; /* Running with user privileges? */ extern char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */ extern char *tempRcpt; /* Temporary files: return receipt */ extern char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */ extern char *tempEdit; extern char *tempMesg; extern char *faxgate; /* Email of your E-Fax Gateway */ extern char *hostname; extern char *sysopmail; extern char *def_shell; /* Default settings for autoaccounts */ extern char *def_homedir; extern int mail_allowed, identification, autocreate, login_allowed; extern int first_uid, last_uid; extern gid_t user_gid; extern char mboxname[PATHSIZE]; extern long IdleTimeout; struct cmd { char *name; int (*function) (int argc, char **argv); }; extern struct cmd Mailcmds[]; extern void tinit(void); extern int read_config(void); axmail-2.12.2/etc/0000755000175000017500000000000013017321522012512 5ustar n1uron1uroaxmail-2.12.2/etc/welcome.txt0000644000175000017500000000125013254532003014705 0ustar n1uron1uroSubject: Welcome to axMail-FAX Welcome to axmail! Your email address is listed above the prompt. For further assistance, try "?" or email root. axMail is the first mail client for packet that allows it's users the ability to: send/receive emails, send outbound faxing with confirmations and receipts read receipts for their mail , server to server confirmation of delivery of mail cc and bcc fields for multiple copies of mail, priority flagging for emergency communications, and an SP shortcut for those using HF to bypass many prompting ...all by using just a dumb terminal. Some sites may offer pop3/IMAP/webmail as well. Contact your sysop to see if this is possible. 73! axmail-2.12.2/etc/axmail.conf0000644000175000017500000000303413254532003014635 0ustar n1uron1uro# /etc/ax25/axmail.conf - axMail configuration file # # Idle timeout (seconds). IdleTimeout 900 # Local hostname. HostName .ampr.org # Sysop's email address SysopMail # Who (of those who are listed in /etc/passwd) are allowed to use axmail # all : All users who have an account (or have just created one) # nologin : Those who have "+" as password (the axmail-only accounts) # passwd : Those who have a password set (NOT those with "+" as password) # axhome : Those who put all ham home dirs within one branch AllowMail all # Do we ask for a password or rely on the callsign # none : Trust the callsign given on command line # passwd : Ask for a plaintext password (brrrr...) # TODO: MDn authenthication ! Identification none # # ------ Parameters for automatically created user accounts # # Allow automatic creation of user accounts AutoCreate yes # Automatically created login accounts can login (through telnet, etc) # yes : User is prompted for password, when the account is created # no : Password is set to "+" (cannot login) (preferred, axmail-only # account) # crazy : Password is left empty (can login without password) LoginAllowed no # Group name or id for autoaccount AutoGroup ax25 # First user id to use for automatically created accounts First_uid 2000 # Maximum user id Last_uid 2999 # Where to add the home directories for the new users HomeDir /home # User shell Shell /bin/false # Fax Gateway - must be defined without quotes FaxGate "your@faxgate.com" axmail-2.12.2/etc/help/0000755000175000017500000000000013503747041013452 5ustar n1uron1uroaxmail-2.12.2/etc/help/verbose.hlp0000644000175000017500000000071113254532003015614 0ustar n1uron1uroUSAGE Verbose DESCRIPTION Like with the Read command, verbose will print out the full mail headers along with the body of the message. This command requires a parameter consisting of the message number you wish to read. Ex: V 3 will verbosely print message #3 including all mail headers. This can be quite lengthy but also can be quite handy if you're trying to find out if someone else's mail account may have been compromised or spoofed. axmail-2.12.2/etc/help/help.hlp0000644000175000017500000000036113254532003015100 0ustar n1uron1uroUSAGE help [] DESCRIPTION Gives help for the specified command or this text if no command is specified. Commands can not be abbreviated. Use the "?" command to retrieve a list of available commands. axmail-2.12.2/etc/help/unkill.hlp0000644000175000017500000000056413254532003015453 0ustar n1uron1uroUSAGE unkill DESCRIPTION The Unkill commmand allows you to reflag a killed message as valid so that it may be retrieved later if you wish to reread it. This comes in very handy in the event you accidentally kill or delete a mail message. Mail does NOT get fully killed until you exit the axMail-FAX mailbox, and your settings are changed and saved. axmail-2.12.2/etc/help/cancel.hlp0000644000175000017500000000033013254532003015371 0ustar n1uron1uroUSAGE Cancel DESCRIPTION When you choose to Cancel out of the mailbox, any changes you have done to your axMail-FAX mail file will NOT be saved and you will be logged out of the axMail-FAX system. axmail-2.12.2/etc/help/sig.hlp0000644000175000017500000000052013254532003014727 0ustar n1uron1uroUSAGE SI DESCRIPTION This creates a signature file which would get appended to your outgoing mail so you don't have to keep typing your closings when you send mail. If you don't have a signature file it will inform you of such but it will not prevent mail from being sent. This is limited to just 1 line (79 characters). axmail-2.12.2/etc/help/autofwd.hlp0000644000175000017500000000063213254532003015622 0ustar n1uron1uroUSAGE Autofwd DESCRIPTION This command will set the system to auto-forward any incoming mail to this address to a "home" axMail-FAX system you would usually use, OR you could set it to forward any mails from this system to any SMTP based system ie: xNOS, internet, etc. Just hitting the enter key will clear your mail forwarding and your incoming mail to this system will be held here for you. axmail-2.12.2/etc/help/delete.hlp0000644000175000017500000000037713254532003015421 0ustar n1uron1uroUSAGE kill [] delete [] DESCRIPTION This command removes specified message from mailbox. If no message number is entered, then command removes last viewed message. axmail-2.12.2/etc/help/info.hlp0000644000175000017500000000013513254532003015102 0ustar n1uron1uroThis is an SMTP mail agent node plug-in for packet radio systems using linuxnode or URONode. axmail-2.12.2/etc/help/spers.hlp0000644000175000017500000000113713254532003015306 0ustar n1uron1uroUSAGE spers DESCRIPTION This command sends message. If no mail recipient is specified, then you will be asked. This is a clone of the "Send" command, with initial flags, cc, and bcc prompts disabled. You will still be asked if you wish to receive a delivery receipt since the remote reader isn't given an option to ignore it. Mail will also default as highest priority since it's coming from amateur radio. You may enter multiple addresses on each line if you desire too. Separate them with a comma (,). Ex: To: n1uro@email.com, user@foo.net, noone@bar.org axmail-2.12.2/etc/help/bye.hlp0000644000175000017500000000023413254532003014726 0ustar n1uron1uroUSAGE bye | exit | quit DESCRIPTION Any of these commands will exit axMail-FAX and preserve any mail that you haven't killed or deleted. axmail-2.12.2/etc/help/sreply.hlp0000644000175000017500000000031513254532003015465 0ustar n1uron1uroUSAGE SReply (short for "send reply") DESCRIPTION This command allows you to send a reply to the message number the prompt tells you that you're on. Subject and destination will be preserved. axmail-2.12.2/etc/help/send.hlp0000644000175000017500000000076213254532003015106 0ustar n1uron1uroUSAGE send [] DESCRIPTION This command sends message. If no mail recipient is specified, then you will be asked. You will also be prompted for a cc: and also for a bcc: entry if desired. Hitting enter disables these features. You may enter multiple addresses on each line if you desire too. Separate them with a comma (,). Ex: s n1uro@email.com, user@foo.net, noone@bar.org cc: ripoff@arrl.org, commish@fcc.gov bcc: ghost@noth.ing, not@listed.info axmail-2.12.2/etc/help/sfax.hlp0000644000175000017500000000124713254532003015115 0ustar n1uron1uroUSAGE sfax DESCRIPTION This command sends a facsimile. The To: field will be preset for you. You can specify a user but you *must* specify a full phone number to fax to. Ex: n1uro@14132416644 Notes: Faxes will send only! You will get a confirmation that your fax was received into the system and another message after the fax was either sent successfully or had issues sending. Faxes will only work within the United States. Sending of faxes elsewhere is a violation of this program. IMPORTANT: you *must* include the beginning country code. For the U.S it's 1, for the U.K. it's 011. An example of a properly entered number would be: 12125551212 axmail-2.12.2/etc/help/read.hlp0000644000175000017500000000030413254532003015060 0ustar n1uron1uroUSAGE read DESCRIPTION Use this command to read your mail. This command requires a parameter of a message number to read. Ex: to read your mail message 3 you would enter: R 3. axmail-2.12.2/etc/help/status.hlp0000644000175000017500000000031213254532003015467 0ustar n1uron1uroUSAGE status DESCRIPTION The STatus command shows you a very shortened list by only informing you just how many total messages you have by a grand total number. Ex: status Messages: 4 axmail-2.12.2/etc/help/quit.hlp0000644000175000017500000000023413254532003015131 0ustar n1uron1uroUSAGE bye | exit | quit DESCRIPTION Any of these commands will exit axMail-FAX and preserve any mail that you haven't killed or deleted. axmail-2.12.2/etc/help/name.hlp0000644000175000017500000000030213254532003015063 0ustar n1uron1uroUSAGE name DESCRIPTION Use the Name command to change your "Real name" within the mail server system. It will automatically be appended to your email address when you send mail out. axmail-2.12.2/etc/help/kill.hlp0000644000175000017500000000037713254532003015112 0ustar n1uron1uroUSAGE kill [] delete [] DESCRIPTION This command removes specified message from mailbox. If no message number is entered, then command removes last viewed message. axmail-2.12.2/etc/help/list.hlp0000644000175000017500000000030113254532003015115 0ustar n1uron1uroUSAGE list DESCRIPTION Use this command to list your mail messages. Each message will be flagged as N(ew), U(nread), or blank for read. Use the "read" command to read each message. axmail-2.12.2/etc/help/exit.hlp0000644000175000017500000000023413254532003015120 0ustar n1uron1uroUSAGE bye | exit | quit DESCRIPTION Any of these commands will exit axMail-FAX and preserve any mail that you haven't killed or deleted. axmail-2.12.2/lock.c0000664000175000017500000000071713254532003013043 0ustar n1uron1uro /* lock.c - file locking services */ #include #include #include #include #include #include "lock.h" #include "utils.h" /* Lock a file descriptor. */ int lock_fd(int fd) { if (flock(fd, LOCK_EX)) { syserr("Can't lock fd\n"); return -1; } return 0; } /* Unlock a file descriptor. */ int unlock_fd(int fd) { if (flock(fd, LOCK_UN)) { syserr("Can't unlockfd\n"); return -1; } return 0; } axmail-2.12.2/email2fax-axmail0000755000175000017500000003717313254532003015022 0ustar n1uron1uro#!/bin/bash -x # email2fax-axmail 1.0beta # This script allows you to send faxes through your Hylafax server. # It extracts PDF,TIFF or PS attachments from an email and then passes # it to Hylafax thru "sendfax" command. # Hylafax adaptation by: # (c) Brian Rogers - NCC 2007 # (c) Raffaello Cassetta 2006 # Original work by: # (c) Tomasz Chmielewski < tch @ wpkg . org > 2005-2006 # License: GPLv2 # Variables you might want to change FAXMAIL="NCC FAX " # email from which confirmations are sent DEFSENDER="fax@n1uro.ampr.org" # If email doesn't have "From:" field, default to this for Hylafax error mails LOGFILE=/var/log/fax.log # where to log TMPDIR=/var/email2fax # dir for temp files; must be writable by the launching user MAXAGE=30 # how long to keep temp files, in minutes. # There should be no reason for keeping these files so long because # once sendfax has enqueued the document, this is stored in Hylafax # spool directory and there resides until fax transmission's completion # In a production environment, with tens or hundreds of fax submitted every # minute, you should reduce this to a value as low as possible. Anyway, leave # some grace time to tolerate delays in bash script executions (due to high # CPU load or whatelse) WHOAMI=`whoami` # User that launches script - useful for testing/debugging when invoked # by MDAs or other daemons SENDFAXOPTS=" " # Default sendfax options # You probably don't have to change anything below... DATADIR=$TMPDIR/`date +%s-%N` EMAILFILE=$DATADIR/emailfile.eml COVERFILE=$DATADIR/coverpage.txt MESSAGEFILE=$DATADIR/message.txt DATETIME=`date +"%A, %B %d %Y, at %R:%S"` # date put in email confirmations #DATETIME=`date +"%A, %B %d %Y, at %r"` # date put in email confirmations, different format VERSION="email2fax-axmail v1.0" # version PATH="/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:"$PATH ############################################################ # check how we are started, print help if pipe wasn't used # ############################################################ [ -p /dev/stdin ] [ $? -eq 1 ] && EMPTY=1 && cat <> $LOGFILE -------------------------------------------------------------- $VERSION started on $DATETIME with options: $0 $@ by user: $WHOAMI EOF ################################################# # Check the error code and make a proper action # ################################################# send_msg() { [ $1 -eq 1 -o $1 -eq 2 ] && NEWSUBJECT="Fax problem" [ $1 -eq 0 -a $NOFAX -eq 1 ] && NEWSUBJECT="Fax not sent" [ $1 -eq 0 -a $NOFAX -eq 0 ] && NEWSUBJECT="Fax confirmation" #FAXNUMBERS=`echo $NEWNUM | sed -e "s/ /, /g" -e "s/@/ /" | awk '{print $2}'` FAXNUMBERS=`cat $COVERFILE |grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' ` cat <$MESSAGEFILE From: $FAXMAIL To: $SENDER Subject: $NEWSUBJECT Dear sender, EOF case "$1" in 0) if [ $NOFAX -eq 0 ] ; then if [ $NOCONFIRM -eq 0 ] ; then cat <>$MESSAGEFILE The message was accepted for fax delivery. Fax number(s): $FAXNUMBERS Date: $DATETIME EOF [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t fi else cat <>$MESSAGEFILE Fax sending is currently disabled, please contact your administrator. Fax number(s): $FAXNUMBERS Date: $DATETIME EOF [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t fi del_temp ;; 1) echo "No e-mail message passed to email2fax-axmail, or message broken." >>$LOGFILE cat <>$MESSAGEFILE The message you sent was broken or invalid. Check if it had a proper attachment (must be one PDF or one TIFF attachment or plain text body), and if the fax number was correct, and try again. If the problem persists, contact your administrator. Fax number(s): $FAXNUMBERS Date: $DATETIME EOF [ $NOMAIL -ne 1 ] && cat $MESSAGEFILE | sendmail -t del_temp ;; 2) cat <>$MESSAGEFILE System not configured properly for sending faxes, contact your administrator. Date: $DATETIME EOF [ $NOMAIL -ne 1 ] && echo $NOMAIL && cat $MESSAGEFILE | sendmail -t del_temp esac } ####################################### # Delete temporary files if requested # ####################################### del_temp() { if [ $NODELETE -eq 0 ] ; then [ $DEBUG -eq 1 ] && echo "Removing old temporary files" >>$LOGFILE [ $DEBUG -eq 0 ] && find $TMPDIR/* -type d -mmin +$MAXAGE -exec rm -fvr {} \; &>/dev/null [ $DEBUG -eq 1 ] && find $TMPDIR/* -type d -mmin +$MAXAGE -exec rm -fvr {} \; >>$LOGFILE echo >>$LOGFILE else echo "Not removing old temporary files" >>$LOGFILE echo >>$LOGFILE fi } ##################################################### # By default, our internal "error code" should be 0 # ##################################################### ERRORCODE=0 ############################################# # Make sure temp dir exists and is writable # ############################################# mkdir -p $DATADIR if [ $? -ne 0 ] ; then echo "$DATADIR not writable, can't continue!" >>$LOGFILE ERRORCODE=2 fi ########################################### # Check if "munpack" program is installed # ########################################### if [ `which munpack &>/dev/null ; echo $?` -ne 0 ] ; then echo "munpack is not installed: can't extract attachments, can't continue!" >>$LOGFILE ERRORCODE=2 fi ############################################ # Read flags and set appropriate behaviour # ############################################ # --nomail takes precedence over --noconfirm. If --nomail is present then --noconfirm is ignored [ `echo $@ | grep -i -q '\-\-nomail' ; echo $?` -eq 0 ] && NOMAIL=1 || NOMAIL=0 if test $NOMAIL = 0; then [ `echo $@ | grep -i -q '\-\-noconfirm' ; echo $?` -eq 0 ] && NOCONFIRM=1 || NOCONFIRM=0 else NOCONFIRM=0 fi [ `echo $@ | grep -i -q '\-\-usebody' ; echo $?` -eq 0 ] && USEBODY=1 || USEBODY=0 [ `echo $@ | grep -i -q '\-\-nodelete' ; echo $?` -eq 0 ] && NODELETE=1 || NODELETE=0 [ `echo $@ | grep -i -q '\-\-nofax' ; echo $?` -eq 0 ] && NOFAX=1 || NOFAX=0 [ `echo $@ | grep -i -q '\-\-debug' ; echo $?` -eq 0 ] && DEBUG=1 || DEBUG=0 # --notify-all takes precedence over --notify. If --notify-all is present then --notify is ignored [ `echo $@ | grep -i -q '\-\-notify\-all' ; echo $?` -eq 0 ] && NOTIFYALL=1 || NOTIFYALL=0 if test $NOTIFYALL = 1; then NOTIFY="-R" else [ `echo $@ | grep -i -q '\-\-notify' ; echo $?` -eq 0 ] && NOTIFY="-D" || NOTIFY="" fi 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"` [ -z $UNKNOWN_FLAGS ] [ $? -ne 0 ] && echo "WARNING: unknown flags: $UNKNOWN_FLAGS" >>$LOGFILE if [ $DEBUG -eq 1 ] ; then cat <>$LOGFILE Variables used: FAXMAIL: $FAXMAIL LOGFILE: $LOGFILE VERSION: $VERSION TMPDIR: $TMPDIR DATADIR: $DATADIR EMAILFILE: $EMAILFILE MESSAGEFILE: $MESSAGEFILE DATETIME: $DATETIME EOF fi ############################################################ # If we can't continue, send a message with an explanation # ############################################################ [ $ERRORCODE -eq 2 ] && send_msg 2 && exit 2 ######################################### # Make a temporary file out of an email # ######################################### cat | sed 's/$//' > $EMAILFILE cp $EMAILFILE $COVERFILE ############################## # COVERPAGE VARIABLES ADDED: # ############################## COVERTO=`cat $COVERFILE |grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $1}' ` COVERCOM=`cat $COVERFILE | grep Subject:|sed -e "s/Subject: //" -e "s/@/ /" | awk '{$1=""; $2=""; sub(" ", " "); print}' ` ###################################################################### # If input file is too short (broken email etc.) send error and quit # ###################################################################### if [ `du -b $EMAILFILE | awk '{print $1}'` -lt 15 ] ; then echo "No e-mail message passed to email2fax-axmail, or message broken." >>$LOGFILE # send_msg 1 # exit 1 fi ############################################################################################# # Get the email address to send a confirmation to, and telephone number(s) to send faxes to # # Verify suitable data and take appropriate action # ############################################################################################# SUBJLINE=`grep -m 1 "Subject:" $EMAILFILE` # TOLINE=`grep -m 1 "To:" $EMAILFILE.1` SENDER=`grep -m 1 "From:" $EMAILFILE | sed -e "s/From://"` NUMBERS=`echo $SUBJLINE | awk '{print NF}'` SUBJECT=`echo $SUBJLINE | sed -e "s/Subject://" ` # If no fax numbers in the subject, send an explanation and quit [ $NUMBERS -lt 2 ] && send_msg 1 && exit 1 # If no sender in file, don't send a confirmation email if [ -z "$SENDER" ] ; then NOMAIL=1 SENDER=$DEFSENDER fi ######################################################################### # Extract everything from mail, check files and take appropriate action # ######################################################################### # extract everything from mail MOUT=`munpack -t -C "$DATADIR" "$EMAILFILE"` # I AGREE: the following "for" cycle is terrible, please make it better # ^^^^^^^^ SEQ="ODD" for P in $MOUT do if [ "$SEQ" = "ODD" ] ; then SEQ="EVEN" FORVAR=$P else FORVAR=$FORVAR" "$P if [ `echo "$FORVAR"|grep -c "text/plain"` -ne 0 ] ; then TXT=`echo $FORVAR | cut -f1 -d " "`" "$TXT # TXT=`cat $DATADIR/$EMAILFILE|formail -k -X X-Origin: -X X-Mailer >$DATADIR/part1` $FORVAR=$P elif [ `echo "$FORVAR"|grep -c -e "pdf" -e "tif" -e "postscript"` -ne 0 ] ; then ATTACH=`echo $FORVAR | cut -f1 -d " "`" "$ATTACH else mkdir $DATADIR/convdir cat $DATADIR/emailfile.eml|formail -k -X X-Origin: -X X-Mailer >$DATADIR/part1 touch $DATADIR/convdir/foo /usr/bin/text2ps -B $DATADIR/part1 > $DATADIR/convdir/part1.ps # fi fi SEQ="ODD" fi done # If no txt nor pdf nor tif nor ps parts are present, send error and exit # If only text is present, then it's only a mail if [ -z "$ATTACH" -a -z "$TXT" || -f "$CONVDIR/part1.ps" ] ; then echo "No pdf nor tif nor ps nor text body present." >>$LOGFILE send_msg 1 exit 1 elif [ -z "$ATTACH" ] ; then ISMAIL=1 else ISMAIL=0 fi ############################################################################# # Read destination numbers from subject, verify and take appropriate action # ############################################################################# # Convert fax numbers from the subject field to separate numbers SUBJLINE=`grep -m 1 "Subject:" $EMAILFILE | sed -e "s/Subject://" -e "s/[-() ]/ /g" -e "s/,/ /g"` NEWNUM="" for FAXNUM in $SUBJLINE do FAXNUM=`cat $COVERFILE | grep -m 1 "Subject:" | sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' ` [ ! -z `echo "$FAXNUM" | sed -e "s/[0-9]//g"` ] && echo "Wrong fax number: $FAXNUM" >>$LOGFILE && FAXNUM= [ -n "$FAXNUM" ] && NEWNUM="$NEWNUM $FAXNUM" done # If no numbers have been munged, send an error message and exit if test "$NEWNUM" = "" ; then echo "No destination numbers present in Subject field." >>$LOGFILE # send_msg 1 # exit 1 fi # Log who sends fax where cat <>$LOGFILE Fax from$SENDER to fax number(s): $FAXNUM Attachments: $ATTACH EOF ############################ # Send document to sendfax # ############################ if [ $NOFAX -eq 0 ] ; then # If the user wants to send the body or it's only a text message, then create text parts list. # We use faxmail to convert plain text to ps format - just to avoid strange characters that could confuse sendfax. # There should be a dedicated app for doing this, but faxmail is available here and now (default with Hylafax)- nonetheless, it works :P if [ $USEBODY -eq 1 -o $ISMAIL -eq 1 ] ; then CONVDIR="$DATADIR/convdir" # to avoid name collisions we create a dir for converted text mkdir $CONVDIR for ITEM in $TXT do cat $DATADIR/emailfile.eml | formail -k -X X-Origin: -X X-mailer: > part1 TXT2PS="$CONVDIR/$ITEM.ps" /usr/bin/text2ps -B $DATADIR/part1 > $CONVDIR/part1.ps TEXTPART=""$TXT2PS" "$TEXTPART"" done else TEXTPART="" fi # If we have to send PDF or TIF attachments then create list if [ $ISMAIL -eq 0 ] ; then for ITEM in $ATTACH do ATTACHMENT=""$DATADIR/$ITEM" "$ATTACHMENT"" done else ATTACHMENT="" fi # create destination array for "sendfax" NUM=`cat $COVERFILE | grep -m 1 "Subject:" | sed -e "s/Subject: //" -e "s/@/ /" | awk '{print $2}' ` # DEST="" # for NUM in $NEWNUM # do # DEST="-d $COVERTO@$NUM "$DEST DEST="-d $COVERTO@$NUM" # done # TEXTPART="$CONVDIR/part1.ps" ## if [ -z "$TEXTPART" ] sendfax -r "Amateur Communication" -x "axMail-Fax" -c "$COVERCOM" -f "$SENDER" $DEST $CONVDIR/part1.ps $TEXTPART $ATTACHMENT >> $LOGFILE 2>&1 & ## else ## sendfax -r "Email2Fax" -x "E-Fax at NCC" -c "$COVERCOM" -f "$SENDER" $DEST $TEXTPART $ATTACHMENT >> $LOGFILE 2>&1 & ## fi else echo "Not sending fax because --nofax was used" >>$LOGFILE fi echo >>$LOGFILE send_msg 0 axmail-2.12.2/axmail.c0000664000175000017500000001365113254532003013367 0ustar n1uron1uro/* axmail.c - The command parser and main function */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "axmail.h" #include "utils.h" #include "adduser.h" #include "quit.h" #include "mbox.h" /* Parse c-style escapes (neat to have!) */ static char *parse_string(char *str) { char *cp = str; unsigned long num; while (*str != '\0' && *str != '\"') { if (*str == '\\') { str++; switch (*str++) { case 'n': *cp++ = '\n'; break; case 't': *cp++ = '\t'; break; case 'v': *cp++ = '\v'; break; case 'b': *cp++ = '\b'; break; case 'r': *cp++ = '\r'; break; case 'f': *cp++ = '\f'; break; case 'a': *cp++ = '\007'; break; case '\\': *cp++ = '\\'; break; case '\"': *cp++ = '\"'; break; case 'x': num = strtoul(--str, &str, 16); *cp++ = (char) num; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': num = strtoul(--str, &str, 8); *cp++ = (char) num; break; case '\0': return NULL; default: *cp++ = *(str - 1); break; }; } else { *cp++ = *str++; } } if (*str == '\"') str++; /* skip final quote */ *cp = '\0'; /* terminate string */ return str; } /* Parse command line to argv, honoring quotes and such */ int parse_args(char *argv[],char *cmd) { int ct = 0; int quoted; while (ct < 31) { quoted = 0; while (*cmd && isspace(*cmd)) cmd++; if (*cmd == 0) break; if (*cmd == '"') { quoted++; cmd++; } argv[ct++] = cmd; if (quoted) { if ((cmd = parse_string(cmd)) == NULL) return 0; } else { while (*cmd && !isspace(*cmd)) cmd++; } if (*cmd) *cmd++ = 0; } argv[ct] = NULL; return ct; } /* Find the command from the command table and execute it. */ int cmdparse(struct cmd *cmds, char *cmdline) { struct cmd *cmdp; int argc; char *argv[32]; if ((argc = parse_args(argv, cmdline)) == 0 || *argv[0] == '#') return 0; strlwr(argv[0]); for (cmdp = cmds; cmdp->function != NULL; cmdp++) if (strncasecmp(cmdp->name, argv[0], strlen(argv[0])) == 0) break; if (cmdp->function == NULL) return -1; return (*cmdp->function)(argc, argv); } /* Signal handlers (which don't do all the things they SHOULD do) */ static void alarm_handler(int sig) { printf("\nTimeout! Closing...\n"); exit(1); } static void term_handler(int sig) { printf("System going down! Closing...\n"); exit(1); } /* Initialisation for the user */ int init_user(char *call) { struct passwd *pw; char pass[13], salt[3]; char *p; char axhome[64]; /* Strip SSID */ if (local) { pw = getpwuid(getuid()); } else { strcpy(callsign, call); strcpy(username, callsign); strlwr(username); p = strchr(username, '-'); if (p) *p = '\0'; pw = getpwnam(username); } if (!pw) { if (local) panic("Ouch, you don't seem to be in the password file.\n"); if (autocreate) { syslog(LOG_NOTICE, "Adding new user %s", username); if (new_user(username) < 0) { syslog(LOG_NOTICE, "Could not add new user %s", username); printf("Sorry, could not add new user.\n"); return -1; } printf("You have been added to the user list of %s.\nWelcome.\n", hostname); pw = getpwnam(username); } else { syslog(LOG_NOTICE, "New user %s not accepted", username); printf("Sorry, new users are not accepted at this time.\n"); return -1; } } else { if (local) { strcpy(username, pw->pw_name); strcpy(callsign, username); } /* Strip full name from the gecos field... */ if (strchr(pw->pw_gecos, ',') == NULL) strcpy(fullname, pw->pw_gecos); else strcpy(fullname, strtok(pw->pw_gecos, ",")); } if (!local) { if ((mail_allowed == 1) && (strcmp(pw->pw_passwd, "*"))) { printf("Sorry, you are not allowed to use axmail (you have a password set).\n"); return -1; } if ((mail_allowed == 2) && (!strcmp(pw->pw_passwd, "*"))) { printf("Sorry, you are not allowed to use axmail (locked out in password file).\n"); return -1; } if (mail_allowed == 3) { sprintf(axhome, "%s/%s", def_homedir, username); if (strcmp(pw->pw_dir, axhome)) { printf("Sorry, you are not allowed to use axmail - bad axhome.\n"); return -1; } } if (identification == 1) { getstr(pass, 12, "Password: "); strncpy(salt, pw->pw_passwd, 2); salt[2] = '\0'; if (strcmp(pw->pw_passwd, (char *)crypt(pass, salt))) { printf("Login incorrect.\n"); return -1; } } /* code supplied by Jaroslav Skarvada */ if ( (setgroups(0, NULL) == -1) || (setgid(pw->pw_gid) == -1) || (setuid(pw->pw_uid) == -1) ) panic("init_user: Argh, cannot setuid() or setgid() to %i.%i", pw->pw_uid, pw->pw_gid); } homedir = strdup(pw->pw_dir); return 0; } int main(int argc, char **argv) { char *p; signal(SIGALRM, alarm_handler); signal(SIGTERM, term_handler); openlog("axmail", LOG_PID, LOG_DAEMON); if (getuid() != 0) local = 1; /* Hey, we're being executed by a "normal" * user, with user privileges! */ if ((!local) && (argc != 2)) { printf("axmail: Callsign not found as a parameter.\n"); syslog(LOG_NOTICE, "Callsign not found as a parameter\n"); return 1; } if (read_config() == -1) /* Read axmail.conf */ return 1; printf("%s\n", VERSION); if (init_user(argv[1]) == -1) /* Get user specific data, create user account */ return 1; tinit(); /* Filenames etc */ getmail(); /* Scan mailbox */ if ((newm) || (messages)) printf("You have %i messages (%i new).\n", messages, newm); prompt(); fflush(stdout); p = malloc(1024); while (1) { fgets(p, 1023, stdin); if (p == NULL) quit(0, 0); if (cmdparse(Mailcmds, p) == -1) printf("Unknown command. Type ? for a list.\n"); prompt(); fflush(stdout); } } axmail-2.12.2/adduser.h0000664000175000017500000000004513254532003013541 0ustar n1uron1uro extern int new_user(char *newuser); axmail-2.12.2/adduser.c0000664000175000017500000000740613254532003013544 0ustar n1uron1uro /* adduser.c - create an user account (yecch) */ #include #include #include #include #include #include #include #include #include #include #include "adduser.h" #include "utils.h" #include "config.h" #include "defines.h" /* Ask for a new password, and keep it sane */ void get_passwd(char *newuser, char *passw) { printf("Please email %s with your callsign and desired password.\n", sysopmail); char passi[12]; repass: /* Get password */ getstr(passi, 10, "Enter password for the new account (6-8 characters, ? for help): "); if (!strcmp(passi, "?")) { printf("Your password must be 6 to 8 characters long, and it may not be the same as\n"); printf("your login name (in this case, your callsign).\n"); goto repass; } if ((strlen(passi) > 8) || (strlen(passi) < 6)) { printf("Password must be 6-8 characters long.\n"); goto repass; } if (!strcasecmp(passi, newuser)) { printf("Password may not be your login name (callsign).\n"); goto repass; } /* Crypt password */ strcpy(passw, crypt(passi, "ax")); /* Okay, salt _should_ be random... */ } /* add a new user to /etc/passwd and do some init */ int new_user(char *newuser) { struct passwd pw, *pwp; uid_t uid; FILE *fp; char homedir[256], userdir[256]; char buf[4096]; char subdir[4]; char passw[20]; char str[LINESIZE + 1]; int cnt = 0; unsigned char *p, *q; struct stat fst; int fd_a, fd_b, fd_l; /* Build path for home directory */ strncpy(subdir, newuser, 3); subdir[3] = '\0'; sprintf(homedir, "%s/%s", def_homedir, newuser); strcpy(userdir, homedir); getname(fullname); if (strlen(fullname) == 0) { printf("Okay, using your callsign as your name. You may change it later.\n"); strcpy(fullname, newuser); } /* Get password */ switch (login_allowed) { case 0: strcpy(passw, "*"); break; case 1: get_passwd(newuser, passw); break; case 2: strcpy(passw, ""); /* Yuck! */ break; } /* Lock */ fd_l = open(LOCK_AXMAIL_FILE, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); flock(fd_l, LOCK_EX); retry: /* Find first free UID */ cnt++; for (uid = first_uid; uid < 65535; uid++) { pwp = getpwuid(uid); if (pwp == NULL) break; } if (uid >= 65535 || uid < first_uid) return -1; /* build directories for home */ p = homedir; while (*p == '/') p++; chdir("/"); while(p) { q = strchr(p, '/'); if (q) { *q = '\0'; q++; while (*q == '/') q++; if (*q == 0) q = NULL; } if (stat(p, &fst) < 0) { if (errno == ENOENT) { mkdir(p, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); if (q == NULL) { chown(p, uid, user_gid); chmod(p, S_IRUSR|S_IWUSR|S_IXUSR); } } else return -1; } if (chdir(p) < 0) return -1; p = q; } /* Add the user now */ fp = fopen(PASSWDFILE, "a+"); if (fp == NULL) return -1; pw.pw_name = newuser; pw.pw_passwd = passw; pw.pw_uid = uid; pw.pw_gid = user_gid; pw.pw_gecos = fullname; pw.pw_dir = userdir; pw.pw_shell = def_shell; if ((getpwuid(uid) != NULL) && (cnt <= 10)) goto retry; /* oops?! */ if ((putpwent(&pw, fp) < 0) || (cnt > 10)) return -1; flock(fd_l, LOCK_UN); fclose(fp); /* Copy ax25.profile */ fd_a = open(CONF_AXMAIL_PROF_FILE, O_RDONLY); if (fd_a > 0) { fd_b = open(USERPROFILE, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IXUSR); if (fd_b < 0) return -1; while ( (cnt = read(fd_a, &buf, sizeof(buf))) > 0 ) write(fd_b, &buf, cnt); close(fd_b); close(fd_a); chown(USERPROFILE, uid, user_gid); } /* Be nice and send the new user a welcome message :) */ sprintf(str, "%s -oem %s@%s < %s", BIN_AXMAIL_SENDMAIL, newuser, hostname, WELCOME); system(str); return 0; } axmail-2.12.2/LICENSE0000664000175000017500000004307613254532003012761 0ustar n1uron1uro GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. axmail-2.12.2/utils.h0000664000175000017500000000055213254532003013255 0ustar n1uron1uro extern void prompt(void); extern void getname(char *uname); extern void getstr(char *str, int len, char *prompt); extern char *strupr(char *s); extern char *strlwr(char *s); extern int anyof(char *s1, char *s2); extern int anycntrls(char *s1); extern void panic(const char *fmt, ...); extern void syserr(const char *fmt, ...); /* n1uro */ char callsign[20]; axmail-2.12.2/quit.c0000664000175000017500000001247513254532003013101 0ustar n1uron1uro /* quit.c - clean things up on exit. */ #include #include #include #include #include #include "utils.h" #include "quit.h" #include "config.h" #include "lock.h" #include "mbox.h" /* Remove a temporary file, if it exists */ void cleartmp(char *fname) { struct stat fst; if (!stat(fname, &fst)) if (remove(fname)) printf("Ouch, couldn't remove %s.\n", fname); } /* Update system and user mailbox (yo2loj - 13 april 2003) */ int save_mbox(void) { FILE *mb; FILE *nm; FILE *ub; FILE *tmp; FILE *dest; long mblen=0; int havenew = 0; char buf[LINESIZE]; int count; int i, line; int inhdr; char *status; int hasstatus; mb = fopen(mailbox, "r"); /* Segfault protection if mailbox file doesn't exist. */ if(mb == NULL) { printf("***\nSystem error, I can't see mail files.\nPlease inform your sysop - Error 1.\n***\n"); return -1; } if (lock_fd(fileno(mb))) return -1; fseek(mb, 0, SEEK_END); mblen = ftell(mb); if (mblen < sysboxlen) { printf("Mailbox changed by another program.\nMailbox not saved.\n"); unlock_fd(fileno(mb)); fclose(mb); return -1; } if (mblen > sysboxlen) { printf("New mail has arrived.\n"); havenew = 1; /* copy new mail to a temp file, will append to system mailbox later */ if ((nm = fopen(tempNewMail, "w+")) == NULL) panic("save_mbox: Could not create temporary file"); fseek(mb, sysboxlen, SEEK_SET); while (fgets(buf, LINESIZE, mb) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, nm); if (ferror(nm)) panic("save_mbox: Could not write temporary file"); } } if ((tmp = fopen(tempMail, "r")) == NULL) panic("save_mbox: Could not open temporary mail file"); if (freopen(mailbox, "w", mb) == NULL) panic("save_mbox: Could not open system mailbox for writing"); if ((ub = fopen(userbox, "w")) == NULL) { /* error on user mailbox, dump all to the system mailbox as last resort */ while (fgets(buf, LINESIZE, tmp) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, mb); if (ferror(mb)) panic("save_mbox: Could not write to system mailbox."); } fclose(tmp); if (havenew) { fseek(nm, 0, SEEK_SET); while (fgets(buf, LINESIZE, nm) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, mb); if (ferror(mb)) panic("save_mbox: Could not write to system mailbox."); } fclose(nm); } unlock_fd(fileno(mb)); fclose(mb); printf("Could not open user mailbox, dumping to system mailbox\n"); return -1; } /* we have all processed messages in tmp and any newly arrived (if any) in nm. System mailbox is locked, empty and opened for write (mb), User Mailbox is empty and opened for writing (ub). - read message go to ~/mbox with status RO - not read go back to system mailbox with status O - deleted are purged - any arrived go to system mailbox as they are */ for (i=0; im_offset, SEEK_SET)) { printf("save_mbox: Could not find message %i.\n", i); continue; } if (dot->m_flag & MDELETED) { dest = NULL; status = NULL; } else if (dot->m_flag & MREAD) { dest = mb; status = "RO"; } else if (dot->m_flag & MNEW) { dest = mb; status = "O"; } else { dest = mb; status = NULL; } line = 0; hasstatus = 0; inhdr = 1; for (;;) { if (!dest) break; if (fgets(buf, LINESIZE, tmp) == NULL) { /* End of file */ break; } line ++; if (inhdr) { /* Header */ if (!strncasecmp(buf, "Status: ", 8)) { hasstatus = 1; if (status) sprintf(buf, "Status: %s\n", status); } else if (!strcmp("\n", buf)) { inhdr = 0; if (!hasstatus) { if (status) sprintf(buf, "Status: %s\n", status); fwrite(buf, sizeof *buf, strlen(buf), dest); } strcpy(buf, "\n"); } } else { /* Data */ if (line == dot->m_lines + 1) break; } fwrite(buf, sizeof *buf, strlen(buf), dest); } } fclose(tmp); if (havenew) { /* append the newly arrived mail */ fseek(nm, 0, SEEK_SET); freopen(mailbox, "a+", mb); while (fgets(buf, LINESIZE, nm) != NULL) { count = strlen(buf); fwrite(buf, sizeof *buf, count, mb); if (ferror(mb)) panic("save_mbox: Could not write to system mailbox."); } fclose(nm); } unlock_fd(fileno(mb)); fclose(mb); fclose(ub); return 0; } /* On quit without save: check and announce if new mail has arrived */ int chk_new_msg(void) { FILE *mb; long mblen=0; mb = fopen(mailbox, "r"); if (lock_fd(fileno(mb))) return -1; fseek(mb, 0, SEEK_END); mblen = ftell(mb); if (mblen != sysboxlen) printf("New mail has arrived.\n"); unlock_fd(fileno(mb)); fclose(mb); return 0; } /* quit. */ void quit(int save, int code) { if (save) { printf("Exiting, saving changes in mailbox.\n"); } else printf("Cancelling changes, mailbox not changed.\n"); if (save) { save_mbox(); } else chk_new_msg(); printf("Bye %s!.. from axMail@%s.\n", username, hostname); cleartmp(tempMail); cleartmp(tempNewMail); cleartmp(tempEdit); cleartmp(tempMesg); exit(code); } axmail-2.12.2/mailcmd.c0000664000175000017500000006320214001363513013516 0ustar n1uron1uro/* mailcmd.c - Mail commands */ #include #include #include #include #include #include "mailcmd.h" #include "defines.h" #include "config.h" #include "mbox.h" #include "utils.h" /* List messages */ void printhead(int i, struct message *m) { char ch = ' '; if ((m->m_flag & (MREAD|MNEW)) == MNEW) ch = 'N'; if ((m->m_flag & (MREAD|MNEW)) == 0) ch = 'U'; if ((m->m_flag & (MDELETED)) == MDELETED) ch = 'K'; printf("%c%c%4i %25.25s %-24.24s %5.16s%6li\n", (current == i+1) ? '>' : ' ', ch, i+1, m->from, m->subj, m->date ,m->m_size); } int do_list(int argc, char **argv) { int i; if (!(messages)) { printf("No messages.\n"); return 0; } printf("St Num From Subject Date Size\n"); for (i = 0; i < messages; i++) { printhead(i, &message[i]); } return 0; } /* Read a message (xNOS-stylish parameters) */ int do_read(int argc, char **argv) { char *myargv[64]; int myargc, argsmine; char *tmpbuf; int i, j, k; struct message *m; int msg, maxmsg; char line[2000]; // Automatic Receipt generator FILE *f; char str [LINESIZE + 1]; if (!(messages)) { printf("You have no messages.\n"); return 0; } if (argc > 1) { argsmine = 0; for (i = 1; i < argc; i++) myargv[i] = argv[i]; myargc = argc; } else { argsmine = 1; if (current >= messages) { printf("No more messages.\n"); return 0; } current++; myargc = 2; myargv[1] = malloc(17); sprintf(myargv[1], "echo"); sprintf(myargv[1], "%i", current); } for (i = 1; i < myargc; i++) { tmpbuf = strchr(myargv[i], '-'); msg = atoi(myargv[i]); if (tmpbuf == NULL) maxmsg = msg; else maxmsg = atoi(++tmpbuf); if (maxmsg < msg) { printf("Bad message number %i.\n", maxmsg); continue; } for (; msg <= maxmsg; msg++) { if (msg < 1 || msg > messages) { printf("There's no message number %i.\n", msg); continue; } readmesg(msg, (!strncmp(argv[0], "v", 1))); printf("--- end of message #%i --- \n", msg); if (dot->receipt != NULL) { getstr(str, LINESIZE, "\aA receipt was asked for, do we send one? (y/N): "); if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) { /* Let's try to automate the receipt generator more */ f = fopen(tempMesg, "w"); fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname); strncpy (str, dot->from, LINESIZE); printf("Receipt going to: %s\n", str); fprintf(f,"To: %s\n", str); fprintf(f,"X-Mailer: %s\n",VERSION); fprintf(f,"X-Origin: Amateur Radio Services\n"); fprintf(f,"Subject: axMail-FAX read receipt for \"%s\"\n", dot->subj); strncpy (str, dot->subj, LINESIZE); fprintf(f, "Your mail to %s <%s@%s> about \"%s\"\n", fullname, username, hostname, dot->subj); fprintf(f,"written on %s has been read.\n\n", dot->date); fprintf(f, "\n-----\nThis receipt is sent via axMail-FAX: Not your Elmer\'s Wlink!\n"); fclose(f); sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Read receipt sent.\n"); } } } } if (argsmine) for (i = 1; i < myargc; i++) free(myargv[i]); return 0; } /* Send a message (perhaps a reply) */ int do_send(int argc, char **argv) { FILE *f; FILE *g; char str[LINESIZE + 1]; char cc[LINESIZE + 1]; char bcc[LINESIZE + 1]; int i; int reply = 0; if (!strncmp(argv[0], "sr", 2)) { reply = 1; if (argc == 1) { if (current == 0) { printf("No current message to reply to.\n"); return 0; } i = current; } else i = atoi(argv[0]); i--; if ((i < 0) || (i >= messages)) { printf("Just enter SR without a parameter or number.\n"); return 0; } dot = &message[i]; } if ((f = fopen(tempMesg, "w")) == NULL) { printf("Could not create temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n"); return 0; } fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname); str[0] = '\0'; if (argc != 1) /* Recipient on command line */ for (i = 1; i < argc; i++) { if (i > 1) strcat(str, " "); strncat(str, argv[i], LINESIZE - strlen(str)); } else { if (reply) { strncpy(str, dot->from, LINESIZE); printf("To: %s\n", str); } else { mymain: getstr(str, LINESIZE, "(? = help)\nTo: "); if (!strcmp(str, "?")) { printf("Enter the email address or addresses separated by commas on this line\n"); printf("You'll be asked if you want copies to others.\n"); printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n"); goto mymain; } if (str[0] == '\0') { printf("No recipients, message cancelled.\n"); fclose(f); remove(tempMesg); return 0; } } } fprintf( f, "To: %s\n", str); /* adding a carbon copy feature */ copies: getstr(str, LINESIZE, "Send a copy or copies of this mail to others? (y/N/?): "); if (!strcmp(str, "?")) { printf("Answering \"Y\" or \"yes\" here will prompt you to enter cc or bcc mail\n"); printf("addreses. Separate them using commas. Ex: n1uro@n1uro.com, foo@bar.net\n"); goto copies; } else { if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) { goto carbon; } else { goto prio; } } carbon: getstr(cc, LINESIZE, "(? = help)\ncc: "); if (!strcmp(cc, "?")) { printf("Enter your carbon copied address(es) below. You will be prompted for\n"); printf("bcc addresses after carbon copied addresses. Enter multiple emails on\n"); printf("the same line. Ex: n1uro@n1uro.com, foo@bar.org, me@here.now\n"); goto carbon; } if (cc[0] == '\0') { goto goblind; } fprintf( f, "cc: %s\n", cc); goblind: /* adding a blind carbon copy feature */ getstr(bcc, LINESIZE, "Send a copy to a hidden user? (hit enter if there's no one.)\n(? = help)\nbcc: "); if (!strcmp(bcc, "?")) { printf("Enter your blinded copied address(es) below. These won't show in the mail sent\n"); printf("list. Enter multiple emails the same line. Ex: n1uro@n1uro.com, foo@bar.org\n"); goto goblind; } if (bcc[0] == '\0') { goto header; } fprintf( f, "bcc: %s\n", bcc); header: fprintf( f, "X-Mailer: %s\n", VERSION ); fprintf( f, "X-Origin: Amateur Radio Services\n" ); goto prio;; /* adding priority receive rule */ prio: getstr(str, LINESIZE, "Is this message emergency or urgent? (y/N/?): "); /* try to bullet-proof end-user responces a bit... */ if (!strcmp(str, "?")) { printf("\nAnswering \"Y\" or \"yes\" here will flag the message as of being highest\n"); printf("priority in nature and with most mail client software will present\n"); printf("your message as an urgent read communication. By entering \"N\" or \"no\" or\n"); printf("by hitting the enter key will send your mail message via normal delivery.\n\n"); goto prio; } if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) { fprintf( f, "X-Priority: 1 (Highest)\n" ); } else { fprintf( f,"X-Priority: 3 (Normal)\n" ); } receipt: getstr(str, LINESIZE, "Read receipt requested? (y/N/?): "); if (!strcmp(str, "?")) { printf("\nAnswering \"Y\" or \"yes\" here will request a confirmation of \n"); printf("your message being opened by the remote user. By entering \"N\" or \"no\" or\n"); printf("by hitting the enter key will not request a confirmation receipt.\n\n"); goto receipt; } if (!strcasecmp(str, "Y") || !strcasecmp (str, "YES") || !strcasecmp (str, "YE")) { fprintf( f, "Disposition-Notification-To: %s <%s@%s>\n", fullname, username, hostname); } else { fprintf( f,"" ); } if (reply) { if (strncasecmp(dot->subj, "Re: ", 3)) snprintf(str, LINESIZE, "Re: %s", dot->subj); else snprintf(str, LINESIZE, "%s", dot->subj); printf("Subject: %s\n", str); } else getstr(str, LINESIZE, "Subject: "); fprintf(f, "Subject: %s\n", str); if (reply) fprintf(f, "In-Reply-To: %s\n", dot->id); printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); cont: do { fgets(str, LINESIZE, stdin); if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f); } while (strcmp(str, ".\n") && strcmp(str, "/ex\n")); retry: getstr(str, LINESIZE, "Deliver (Y/n/c/?): "); if (!strcmp(str, "?")) { printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n"); printf("let you continue writing the message. Answering anything else will\n"); printf("proceed with delivering the message to the recipient.\n"); goto retry; } if (!strcasecmp(str, "c")) { printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); goto cont; } /* append a signature file signature to the mail message */ FILE *stream; FILE *streamm; FILE *streammm; char *line = NULL; char *sig = NULL; char buffer[79 + 1]; char bufferr[50 + 1]; char bufferrr[50 + 1]; size_t len = 0; ssize_t read; sprintf(buffer,"%s/.signature", homedir); sprintf(bufferr,"/etc/clamsmtpd.conf"); sprintf(bufferrr,"/etc/clamav/clamav-milter.conf"); stream = fopen(buffer, "r"); streamm = fopen(bufferr, "r"); streammm = fopen(bufferrr, "r"); if (stream == NULL) { printf("No signature file found, use the SIG command to make one.\n"); fprintf(f, "\n---\nsent via axMail-FAX by N1URO."); if (streamm == NULL) { } else if (streammm == NULL) { } else { fprintf(f, "\n---\nMail scanned for viri by ClamAV."); fclose(streamm); fclose(streammm); } goto mailmsg; } else { while ((read = getline(&line, &len, stream)) != -1) { fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line); if (streamm == NULL) { } else if (streammm == NULL) { } else { fprintf(f, "\n---\nMail scanned for viri by ClamAV."); fclose(streamm); } } free(line); fclose(stream); } mailmsg: if (fclose(f)) { printf("Ouch, could not close temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n"); return 0; } delrcpt: if (strcasecmp(str, "n")) { getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): "); if (!strcasecmp(str, "?")) { printf("Requesting a delivery receipt sends the remote mail server a command that tells\n"); printf("it that you desire notification that your mail message not only was received but\n"); printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n"); printf("if you need to log the fact that you sent a communication to a specific person\n"); printf("especially for emergency communication purposes and they do NOT send you a read\n"); printf("receipt even though you asked for one, this covers you and is your log of proof that\n"); printf("you infact did send a communication and the remote person did in fact received it.\n"); printf("This feature can ONLY be found in axMail-FAX.\n"); goto delrcpt; } if (!strcasecmp(str, "y")) { sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Message sent, delivery notification activated.\n"); } else { sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Message sent.\n"); } } else printf("Message canceled.\n"); if (remove(tempMesg)) { printf("Ouch, could not remove temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n"); return 0; } return 0; } /* Send a personal message with no flags or copy prompts */ int do_psend(int argc, char **argv) { FILE *f; FILE *g; char str[LINESIZE + 1]; int i; int reply = 0; if (!strncmp(argv[0], "sr", 2)) { reply = 1; if (argc == 1) { if (current == 0) { printf("No current message to reply to.\n"); return 0; } i = current; } else i = atoi(argv[0]); i--; if ((i < 0) || (i >= messages)) { printf("Just enter SR without a parameter or number.\n"); return 0; } dot = &message[i]; } if ((f = fopen(tempMesg, "w")) == NULL) { printf("Could not create temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n"); return 0; } fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname); str[0] = '\0'; if (argc != 1) /* Recipient on command line */ for (i = 1; i < argc; i++) { if (i > 1) strcat(str, " "); strncat(str, argv[i], LINESIZE - strlen(str)); } else { if (reply) { strncpy(str, dot->from, LINESIZE); printf("To: %s\n", str); } else { mypmain: getstr(str, LINESIZE, "(? = help)\nTo: "); if (!strcmp(str, "?")) { printf("Enter the email address or addresses separated by commas on this line\n"); printf("Ex: n1uro@n1uro.com, foo@bar.net - all on one line.\n"); goto mypmain; } if (str[0] == '\0') { printf("No recipients, message cancelled.\n"); fclose(f); remove(tempMesg); return 0; } } } fprintf( f, "To: %s\n", str); fprintf( f, "X-Mailer: %s\n", VERSION ); fprintf( f, "X-Origin: Amateur Radio Services\n" ); fprintf( f, "X-Priority: 1 (Highest)\n" ); if (reply) { if (strncasecmp(dot->subj, "Re: ", 3)) snprintf(str, LINESIZE, "Re: %s", dot->subj); else snprintf(str, LINESIZE, "%s", dot->subj); printf("Subject: %s\n", str); } else getstr(str, LINESIZE, "Subject: "); fprintf(f, "Subject: %s\n", str); printf("Enter message text (end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); pcont: do { fgets(str, LINESIZE, stdin); if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f); } while (strcmp(str, ".\n") && strcmp(str, "/ex\n")); pretry: getstr(str, LINESIZE, "Deliver (Y/n/c/?): "); if (!strcmp(str, "?")) { printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n"); printf("let you continue writing the message. Answering anything else will\n"); printf("proceed with delivering the message to the recipient.\n"); goto pretry; } if (!strcasecmp(str, "c")) { printf("Continue entering message text\n(end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); goto pcont; } /* append a signature file signature to the mail message */ FILE *stream; FILE *streamm; FILE *streammm; char *line = NULL; char *sig = NULL; char buffer[79 + 1]; char bufferr[50 + 1]; char bufferrr[50 + 1]; size_t len = 0; ssize_t read; sprintf(buffer,"%s/.signature", homedir); sprintf(bufferr,"/etc/clamsmtpd.conf"); sprintf(bufferrr,"/etc/clamav/clamav-milter.conf"); stream = fopen(buffer, "r"); streamm = fopen(bufferr, "r"); streammm= fopen(bufferrr, "r"); if (stream == NULL) { printf("No signature file found, use the SIG command to make one.\n"); fprintf(f, "\n---\nsent via axMail-FAX by N1URO."); } else if (streamm == NULL) { } else if (streammm == NULL) { } else { fprintf(f, "\n---\nMail scanned for viri by ClamAV."); fclose(streamm); } goto pmailmsg; if (stream) { while ((read = getline(&line, &len, stream)) != -1) { fprintf(f, "\n---\n%s\nsent via axMail-FAX by N1URO.", line); if (streamm == NULL) { } if (streammm == NULL) { } else { fprintf(f, "\n---\nMail scanned for viri by ClamAV."); fclose(streamm); fclose(streammm); } } free(line); fclose(stream); } pmailmsg: if (fclose(f)) { printf("Ouch, could not close temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n"); return 0; } if (strcasecmp(str, "n")) { pdelrcpt: getstr(str, LINESIZE, "Request a delivery receipt? (y/N/?): "); if (!strcasecmp(str, "?")) { printf("Requesting a delivery receipt sends the remote mail server a command that tells\n"); printf("it that you desire notification that your mail message not only was received but\n"); printf("also that it was actually delivered to the user's mailbox. This comes in very handy\n"); printf("if you need to log the fact that you sent a communication to a specific person\n"); printf("especially for emergency communication purposes and they do NOT send you a read\n"); printf("receipt even though you asked for one, this covers you and is your log of proof that\n"); printf("you infact did send a communication and the remote person did in fact received it.\n"); printf("This feature can ONLY be found in axMail-FAX.\n"); goto pdelrcpt; } if (!strcasecmp(str, "y")) { sprintf(str, "%s -N success,delay,failure -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Message sent, delivery notification activated.\n"); } else { sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Message sent.\n"); } } else printf("Message canceled.\n"); if (remove(tempMesg)) { printf("Ouch, could not remove temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n"); return 0; } return 0; } /* Kill a message */ int do_kill(int argc, char **argv) { int i, msg = 0, cnt = 0; char *myargv[64]; int myargc, argsmine; if (!(messages)) { printf("You have no messages.\n"); return 0; } if (argc > 1) { argsmine = 0; for (i = 1; i < argc; i++) myargv[i] = argv[i]; myargc = argc; } else { if (current == 0) { printf("No current message to kill.\n"); return 0; } argsmine = 1; myargc = 2; myargv[1] = malloc(17); sprintf(myargv[1], "%i", current); } for (i = 1; i < myargc; i++) { msg = atoi(myargv[i]) - 1; if ((msg < 0) || (msg >= messages)) { printf("There's no message %s.\n", myargv[i]); continue; } dot = &message[msg]; if ((dot->m_flag & MDELETED) == MDELETED) { printf("Message %i is already dead.\n", msg + 1); continue; } dot->m_flag |= MDELETED; cnt++; } if (cnt == 1) /* GCC warns here, but what the heck! 8-) */ printf("Message %i killed.\n", msg + 1); else if (cnt > 1) printf("%i messages killed.\n", cnt); if (argsmine) for (i = 1; i < myargc; i++) free(myargv[i]); return 0; } /* Unkill a message */ int do_unkill(int argc, char **argv) { int i, msg = 0, cnt = 0; char *myargv[64]; int myargc, argsmine; if (!(messages)) { printf("You have no messages.\n"); return 0; } if (argc > 1) { argsmine = 0; for (i = 1; i < argc; i++) myargv[i] = argv[i]; myargc = argc; } else { if (current == 0) { printf("No current message to unkill.\n"); return 0; } argsmine = 1; myargc = 2; myargv[1] = malloc(17); sprintf(myargv[1], "%i", current); } for (i = 1; i < myargc; i++) { msg = atoi(myargv[i]) - 1; if ((msg < 0) || (msg >= messages)) { printf("There's no message %s.\n", myargv[i]); continue; } dot = &message[msg]; if ((dot->m_flag & MDELETED) != MDELETED) { printf("Message %i is not dead.\n", msg + 1); continue; } dot->m_flag ^= (dot->m_flag & MDELETED); cnt++; } if (cnt == 1) /* GCC warns here, but what the heck! 8-) */ printf("Message %i unkilled.\n", msg + 1); else if (cnt > 1) printf("%i messages unkilled.\n", cnt); if (argsmine) for (i = 1; i < myargc; i++) free(myargv[i]); return 0; } /* Send a Fax */ int do_fax(int argc, char **argv) { FILE *f; char str[LINESIZE + 1]; int i; int reply = 0; if (!strncmp(argv[0], "sr", 2)) { reply = 1; if (argc == 1) { if (current == 0) { printf("No current message to reply to.\n"); return 0; } i = current; } else i = atoi(argv[1]); i--; if ((i < 0) || (i >= messages)) { printf("There's no message %s.\n", argv[1]); return 0; } dot = &message[i]; } if ((f = fopen(tempMesg, "w")) == NULL) { printf("Could not create temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not create temporary file.\n"); return 0; } fprintf(f, "From: %s <%s@%s>\n", fullname, username, hostname); str[0] = '\0'; if (argc != 1) /* Recipient on command line */ for (i = 1; i < argc; i++) { if (i > 1) strcat(str, " "); strncat(str, argv[i], LINESIZE - strlen(str)); } else { } printf("To: Fax Gateway\n"); fprintf( f, "To: %s\n", faxgate ); fprintf( f, "X-Mailer: %s\n", VERSION ); fprintf( f, "X-Origin: Amateur Radio Services\n" ); goto prio;; /* adding priority receive rule */ prio: /* if (reply) { if (strncasecmp(dot->subj, "Re: ", 3)) snprintf(str, LINESIZE, "Re: %s", dot->subj); else snprintf(str, LINESIZE, "%s", dot->subj); printf("Subject: %s\n", str); } else */ getstr(str, LINESIZE, "Enter a header \nEx: john@16195551212 Hi From Packet\nHeader: "); fprintf(f, "Subject: %s\n", str); if (reply) fprintf(f, "In-Reply-To: %s\n", dot->id); printf("Enter fax message (end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); cont: do { /* fprintf( f, "X-Mailer: %s\n", VERSION ); fprintf( f, "X-Origin: Amateur Radio Services\n" ); */ fgets(str, LINESIZE, stdin); if ( strcmp( str, ".\n") && strcmp( str, "/ex\n")) fputs(str, f); } while (strcmp(str, ".\n") && strcmp(str, "/ex\n")); retry: getstr(str, LINESIZE, "Deliver (Y/n/c/?): "); if (!strcmp(str, "?")) { printf("Answering \"N\" here will cancel the message. Answering \"C\" will\n"); printf("let you continue writing the facsimile. Answering anything else will\n"); printf("proceed with delivering the facsimile to the recipient.\n"); goto retry; } if (!strcasecmp(str, "c")) { printf("Continue entering facsimile text\n(end with \"/ex\" or \".\" on a line by itself):\n"); fflush(stdout); goto cont; } if (fclose(f)) { printf("Ouch, could not close temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not close temporary file.\n"); return 0; } if (strcasecmp(str, "n")) { sprintf(str, "%s -oem -t < %s", BIN_AXMAIL_SENDMAIL, tempMesg); system(str); printf("Facsimile sent.\n"); } else printf("Facsimile canceled.\n"); if (remove(tempMesg)) { printf("Ouch, could not remove temporary file.\n"); syslog(LOG_NOTICE, "do_send: Could not remove temporary file.\n"); return 0; } return 0; } axmail-2.12.2/defines.h0000664000175000017500000000251114001355562013533 0ustar n1uron1uro /* * defines.h - Compile-time configuration */ #define VERSION "axMail-Fax v2.12.2" #define COPYRIGHT "(c) 1996-1998 Heikki Hannikainen (OH7LZB) \nMailbox save support (c) 2003 Marius Petrescu (YO2LOJ) \nOther modifications (c) 2005-2021 by Brian Rogers (N1URO) " #define PROMPT "=> " #define CONF_AXMAIL_FILE "/usr/local/etc/ax25/axmail.conf" #define CONF_AXMAIL_PROF_FILE "/usr/local/etc/ax25/ax25.profile" // #define CONF_AXMAIL_USER_FILE ".axmailrc" #define DATA_AXMAIL_HELP_DIR "/usr/local/var/lib/ax25/axmail/help/" #define DATA_AXMAIL_MAIL_DIR "/usr/local/var/spool/mail/" #define LOCK_AXMAIL_FILE "/var/lock/axmail" #define BIN_AXMAIL_SENDMAIL "/usr/sbin/sendmail" #define FORWARDFILE ".forward" #define SIGNATUREFILE ".signature" #define USERPROFILE ".profile" #define PASSWDFILE "/etc/passwd" #define WELCOME "/usr/local/etc/ax25/welcome.txt" #define PATHSIZE 1024 #define LINESIZE 1024 /* Maximum length of a line in a message */ #define TRUE 1 #define FALSE 0 #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" axmail-2.12.2/setpwnam.c0000664000175000017500000001177113254532003013753 0ustar n1uron1uro/* setpwnam.c edit an entry in a password database. */ /* because I use getpwent(), putpwent(), etc... */ #define _SVID_SOURCE #include #include #include #include #include #include #include #include #include #ifdef BSD43 #include #endif #include #include "setpwnam.h" extern int errno; typedef int boolean; #define false 0 #define true 1 #define PASSWD_FILE _PATH_PASSWD #define PTMP_FILE _PATH_PTMP #define PTMPTMP_FILE _PATH_PTMPTMP static int copy_pwd (struct passwd *src, struct passwd *dest); static char *xstrdup (char *str); static void pw_init(void); /* * setpwnam () -- * takes a struct passwd in which every field is filled in and valid. * If the given username exists in the passwd file, his entry is * replaced with the given entry. */ int setpwnam (struct passwd *pwd) { FILE *fp; int x, save_errno, fd, ret; struct passwd *entry; boolean found; struct passwd spwd; int oldumask; /* getpwent() returns a pointer to a static buffer. * "pwd" might have some from getpwent(), so we have to copy it to * some other buffer before calling getpwent(). */ if (copy_pwd (pwd, &spwd) < 0) return (-1); oldumask = umask(0); /* Create with exact permissions */ pw_init(); /* sanity check */ for (x = 0; x < 3; x++) { if (x > 0) sleep (1); fd = open (PTMPTMP_FILE, O_WRONLY|O_CREAT, 0644); if(fd == -1) { perror(PTMPTMP_FILE); umask(oldumask); return (-1); } ret = link(PTMPTMP_FILE, PTMP_FILE); unlink(PTMPTMP_FILE); if(ret == -1) close(fd); else break; } umask(oldumask); if (ret == -1) return (-1); /* ptmp should be owned by root.root or root.wheel */ if (chown (PTMP_FILE, (uid_t) 0, (gid_t) 0) < 0) perror ("chown"); /* open ptmp for writing and passwd for reading */ fp = fdopen (fd, "w"); if (! fp) goto fail; setpwent (); /* parse the passwd file */ found = false; while ((entry = getpwent ()) != NULL) { if (! strcmp (spwd.pw_name, entry->pw_name)) { entry = &spwd; found = true; } if (putpwent (entry, fp) < 0) goto fail; } if (fclose (fp) < 0) goto fail; close (fd); endpwent (); if (! found) { errno = ENOENT; /* give me something better */ goto fail; } /* we don't care if we can't remove the backup file */ unlink (PASSWD_FILE".OLD"); /* we don't care if we can't create the backup file */ link (PASSWD_FILE, PASSWD_FILE".OLD"); /* we DO care if we can't rename to the passwd file */ if (rename (PTMP_FILE, PASSWD_FILE) < 0) goto fail; /* finally: success */ return 0; fail: save_errno = errno; if (fp) fclose (fp); if (fd >= 0) close (fd); endpwent (); unlink (PTMP_FILE); errno = save_errno; return (-1); } #define memzero(ptr, size) memset((char *) ptr, 0, size) static int failed; static int copy_pwd (struct passwd *src, struct passwd *dest) { /* this routine destroys abstraction barriers. it's not portable * across systems, or even across different versions of the C library * on a given system. it's dangerous and evil and wrong and I dispise * getpwent() for forcing me to write this. */ failed = 0; memzero (dest, sizeof (struct passwd)); dest->pw_name = xstrdup (src->pw_name); dest->pw_passwd = xstrdup (src->pw_passwd); dest->pw_uid = src->pw_uid; dest->pw_gid = src->pw_gid; dest->pw_gecos = xstrdup (src->pw_gecos); dest->pw_dir = xstrdup (src->pw_dir); dest->pw_shell = xstrdup (src->pw_shell); return (failed); } static char *xstrdup (char *str) { char *dup; if (! str) return NULL; dup = (char *) malloc (strlen (str) + 1); if (! dup) { failed = -1; return NULL; } strcpy (dup, str); return dup; } #ifdef NO_PUTPWENT int putpwent (const struct passwd *p, FILE *stream) { if (p == NULL || stream == NULL) { errno = EINVAL; return (-1); } if (fprintf (stream, "%s:%s:%u:%u:%s:%s:%s\n", p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell) < 0) return (-1); return(0); } #endif static void pw_init() { struct rlimit rlim; /* Unlimited resource limits. */ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &rlim); (void)setrlimit(RLIMIT_FSIZE, &rlim); (void)setrlimit(RLIMIT_STACK, &rlim); (void)setrlimit(RLIMIT_DATA, &rlim); (void)setrlimit(RLIMIT_RSS, &rlim); /* Don't drop core (not really necessary, but GP's). */ rlim.rlim_cur = rlim.rlim_max = 0; (void)setrlimit(RLIMIT_CORE, &rlim); /* Turn off signals. */ (void)signal(SIGALRM, SIG_IGN); (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGPIPE, SIGQUIT); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, SIG_IGN); (void)signal(SIGTSTP, SIG_IGN); (void)signal(SIGTTOU, SIG_IGN); /* Create with exact permissions. */ (void)umask(0); } axmail-2.12.2/quit.h0000664000175000017500000000004713254532003013076 0ustar n1uron1uro extern void quit(int save, int code); axmail-2.12.2/copying0000664000175000017500000004307713254532003013350 0ustar n1uron1uro GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. axmail-2.12.2/config.c0000664000175000017500000001404013254532003013352 0ustar n1uron1uro /* config.c - read configuration */ #include #include #include #include #include #include #include #include #include #include "config.h" #include "defines.h" #include "axmail.h" #include "utils.h" char callsign[20]; char username[20]; char fullname[31]; char *homedir; /* User's home directory */ char *maildir; /* User's mail directory (~/mail) */ char *mailbox; /* System mailbox (/var/spool/mail/user) */ char *userbox; /* User's mailbox (~/mbox) */ char *sysopmail; /* Sysop's email address */ char *mailconf; /* User's own axmail configuration */ int local = 0; /* Running with user privileges? */ char *tempMail; /* Temporary files: ~/mail/ax?(-pid-) */ char *tempNewMail; /* Temporary files: ~/mail/axnew?(-pid-) */ char *tempEdit; char *tempMesg; char *tempRcpt; char *hostname = NULL; char *def_shell = NULL; char *def_homedir = NULL; char *faxgate = NULL; int mail_allowed = 0; int identification = 0; int autocreate = FALSE; int login_allowed = FALSE; int first_uid = 400; int last_uid = 65535; gid_t user_gid = 0; long IdleTimeout = 900L; /* default to 15 mins */ static int do_allowmail(int, char **); static int do_autocreate(int, char **); static int do_autogroup(int, char **); static int do_first_uid(int, char **); static int do_homedir(int, char **); static int do_faxgate(int, char **); static int do_hostname(int, char **); static int do_sysopmail(int, char **); static int do_identification(int, char **); static int do_idletimeout(int, char **); static int do_loginallowed(int, char **); static int do_last_uid(int, char **); static int do_shell(int, char **); static struct cmd cfg_cmds[] = { { "allowmail", do_allowmail }, { "autocreate", do_autocreate }, { "autogroup", do_autogroup }, { "faxgate", do_faxgate }, { "first_uid", do_first_uid }, { "homedir", do_homedir }, { "hostname", do_hostname }, { "identification", do_identification }, { "idletimeout", do_idletimeout }, { "loginallowed", do_loginallowed }, { "last_uid", do_last_uid }, { "shell", do_shell }, { "sysopmail", do_sysopmail }, { NULL, NULL } }; /* ***************************************************************** */ static int do_allowmail(int argc, char **argv) { if (argc < 2) return -1; if (!strcasecmp(argv[1], "all")) mail_allowed = 0; else if (!strcasecmp(argv[1], "nologin")) mail_allowed = 1; else if (!strcasecmp(argv[1], "passwd")) mail_allowed = 2; else if (!strcasecmp(argv[1], "axhome")) mail_allowed = 3; else return -1; return 0; } static int do_autocreate(int argc, char **argv) { if (argc < 2) return -1; if (!strcasecmp(argv[1], "yes")) autocreate = 1; else autocreate = 0; return 0; } static int do_autogroup(int argc, char **argv) { if (argc < 2) return -1; user_gid = atoi(argv[1]); if (user_gid == 0) { struct group * gp = getgrnam(argv[1]); if (gp != NULL) user_gid = gp->gr_gid; else { printf("Group %s not found.\n", argv[1]); return -1; } endgrent(); } if (user_gid == 0) { printf("Default GID for new users must be set and non-zero.\n"); return -1; } return 0; } static int do_faxgate(int argc, char **argv) { if (argc < 2) return -1; faxgate = strdup(argv[1]); return 0; } static int do_first_uid(int argc, char **argv) { if (argc < 2) return -1; first_uid = atoi(argv[1]); return 0; } static int do_last_uid(int argc, char **argv) { if (argc < 2) return -1; last_uid = atol(argv[1]); return 0; } static int do_idletimeout(int argc, char **argv) { if (argc < 2) return -1; IdleTimeout = atol(argv[1]); return 0; } static int do_homedir(int argc, char **argv) { if (argc < 2) return -1; def_homedir = strdup(argv[1]); return 0; } static int do_hostname(int argc, char **argv) { if (argc < 2) return -1; hostname = strdup(argv[1]); return 0; } static int do_sysopmail(int argc, char **argv) { if (argc < 2) return -1; sysopmail = strdup(argv[1]); return 0; } static int do_identification(int argc, char **argv) { if (argc < 2) return -1; if (!strcasecmp(argv[1], "none")) identification = 0; else if (!strcasecmp(argv[1], "passwd")) identification = 1; else return -1; return 0; } static int do_loginallowed(int argc, char **argv) { if (argc < 2) return -1; if (!strcasecmp(argv[1], "yes")) login_allowed = 1; else if (!strcasecmp(argv[1], "crazy")) login_allowed = 2; else login_allowed = 0; return 0; } static int do_shell(int argc, char **argv) { if (argc < 2) return -1; def_shell = strdup(argv[1]); return 0; } /* ***************************************************************** */ /* Set the temporary file names, paths and such, and make sure they're available for us to use... */ void tinit(void) { int pid; char pat[PATHSIZE]; struct stat fst; umask(077); pid = getpid(); sprintf(pat, "%s/mail", homedir); maildir = strdup(pat); sprintf(pat, "%s/axM%05d", maildir, pid); tempMail = strdup(pat); sprintf(pat, "%s/axnewM%05d", maildir, pid); tempNewMail = strdup(pat); sprintf(pat, "%s/axE%05d", maildir, pid); tempEdit = strdup(pat); sprintf(pat, "%s/axT%05d", maildir, pid); tempMesg = strdup(pat); sprintf(pat, "%s/mbox", homedir); userbox = strdup(pat); sprintf(pat, "%s%s", DATA_AXMAIL_MAIL_DIR, username); mailbox = strdup(pat); // sprintf(pat, "%s%s", homedir, CONF_AXMAIL_USER_FILE); // mailconf = strdup(pat); if (stat(maildir, &fst) < 0) { printf("Creating directory %s...\n", maildir); if (mkdir(maildir, S_IRUSR|S_IWUSR|S_IXUSR)) panic("tinit: Cannot create mail directory"); } } /* Read configuration */ int read_config(void) { FILE *fp; char line[256]; int ret, n = 0; if ((fp = fopen(CONF_AXMAIL_FILE, "r")) == NULL) { printf("Cannot read axmail.conf\n"); return -1; } while (fgets(line, 256, fp) != NULL) { n++; ret = cmdparse(cfg_cmds, line); if (ret == -1) printf("Syntax error in config file at line %d: %s\n", n, line); if (ret < 0) { fclose(fp); return -1; } } fclose(fp); return 0; } axmail-2.12.2/command.h0000664000175000017500000000055713254532003013540 0ustar n1uron1uro /* in command.c */ extern int do_status(int argc, char **argv); extern int do_name(int argc, char **argv); extern int do_help(int argc, char **argv); extern int do_quit(int argc, char **argv); extern int do_exit(int argc, char **argv); extern int do_forward(int argc, char **argv); extern int do_signature(int argc, char **argv); /* extern int do_forward(void); */ axmail-2.12.2/command.c0000664000175000017500000000704713254532003013534 0ustar n1uron1uro/* command.c - Commands which have nothing to do with mail... */ #include #include #include #include #include #include "defines.h" #include "command.h" #include "config.h" #include "mailcmd.h" #include "mbox.h" #include "utils.h" #include "quit.h" struct cmd Mailcmds[] = { { "?", do_help }, { "Autofwd", do_forward }, { "Bye", do_exit }, { "Cancel", do_quit }, { "Delete", do_kill }, { "Exit", do_exit }, { "Help", do_help }, { "Info", do_help }, { "Kill", do_kill }, { "List", do_list }, { "Name", do_name }, { "Quit", do_exit }, { "Read", do_read }, { "Send", do_send }, { "SFax", do_fax }, { "SIg", do_signature }, { "SPers", do_psend }, { "SReply", do_send }, { "STatus", do_status }, { "Unkill", do_unkill }, { "Verbose", do_read }, { NULL, NULL } }; int do_status(int argc, char **argv) { printf("Messages: %i\n", messages); return 0; } int do_name(int argc, char **argv) { char name[32]; getname(name); if (strlen(name) == 0) printf("Name not changed. "); else { /* Okay, save it */ strcpy(fullname, name); } printf("You're now known as %s.\n", fullname); return 0; } /* int do_forward(int argc, char **argv) */ int do_forward(int argc, char **argv) { char *email; char *fwdfile; char fwd[79]; char forward[79]; getaddy(fwd); FILE *fptr; sprintf(forward, "%s/.forward", homedir); fwdfile = strdup(forward); fptr = fopen(fwdfile, "w+"); fprintf(fptr, "%s", fwd); while (! *fwd) { fclose(fptr); remove(fwdfile); printf("Forwarding halted, forward file removed.\n"); return 0; } printf("You're mail will be sent to:\n%s\nThank you.\n", fwd); fclose(fptr); return 0; } /* int do_signature(int argc, char **argv) */ int do_signature(int argc, char **argv) { char *sigfile; char sig[79]; char signature[79]; getsig(sig); FILE *fptr; sprintf(signature, "%s/.signature", homedir); sigfile = strdup(signature); fptr = fopen(sigfile, "w+"); fprintf(fptr, "%s\n", sig); while (! *sig) { fclose(fptr); remove(sigfile); printf("Signature file deleted.\n"); return 0; } printf("You're signature is set to:\n%s\nThank you.\n", sig); fclose(fptr); return 0; } int do_help(int argc, char **argv) { FILE *fp; char fname[80], line[256]; struct cmd *cmdp; int i = 0; if (*argv[0] == '?') { /* "?" */ printf("Commands:\n"); for (cmdp = Mailcmds; cmdp->name != NULL; cmdp++) { printf("%s%s", i ? ", " : "", cmdp->name); if (++i == 10) { printf("\n"); i = 0; } } if (i) printf("\n"); return 0; } strcpy(fname, DATA_AXMAIL_HELP_DIR); if (*argv[0] == 'i') { /* "info" */ strcat(fname, "info.hlp"); printf("%s - %s\n", VERSION, COPYRIGHT); printf("%s", LICENSE); } else if (argc == 1) { /* "help" */ strcat(fname, "help.hlp"); } else { /* "help " */ if (strchr(argv[1], '/') == NULL) { strlwr(argv[1]); strcat(fname, argv[1]); strcat(fname, ".hlp"); } } if ((fp = fopen(fname, "r")) == NULL) { if (*argv[0] != 'i') printf("No help for command %s.\n", argv[1] ? argv[1] : "help"); return 0; } if (*argv[0] != 'i') printf("Help for command %s:\n", argv[1] ? argv[1] : "help"); while (fgets(line, 256, fp) != NULL) { printf("%s", line); } fclose(fp); return 0; } int do_quit(int argc, char **argv) { quit(0, 0); return 0; } int do_exit(int argc, char **argv) { quit(1, 0); return 0; } axmail-2.12.2/man/0000755000175000017500000000000013017321522012512 5ustar n1uron1uroaxmail-2.12.2/man/axmail.80000644000175000017500000000422113254532003014056 0ustar n1uron1uro.TH AXMAIL8 "28 September 2015" Linux "Linux System Managers Manual" .SH NAME axMail \- A powerful but simple SMTP plugin for URONode. .SH SYNOPSIS .B axmail %u .SH DESCRIPTION .LP .B axMail\-FAX is a simple but powerful SMTP mail plugin for URONode. This package allows an end user to read and send SMTP based mail via RF, with many options available. .SH COMMANDS The following commands are supported for users of .B axMail\-FAX: .TP 14 .BI ? Give short list of available commands. .TP 14 .BI "Autofwd \- allows the end user for forward their mail to this location to any valid SMTP mailbox." .TP 14 .BI "Bye \- Disconnect user from their mailbox." .TP 14 .BI "Cancel \- Exit mailbox, discard any kills." .TP 14 .BI "Delete (number) -\ Delete message number #. Multiple numbers can be space delimited." .TP 14 .BI "Exit \- Quit the mailbox, save changes." .TP 14 .BI "Help (command) -\ Display help for specific command." .TP 14 .BI "Info \- Online information about this application." .TP 14 .BI "Kill \- see Delete. Msg numbers can be space delimited for multi kills." .TP 14 .BI "List \- List your mailbox messages for reading." .TP 14 .BI "Name \- Enter or change your name in your outgoing mail. This does not change your email address." .TP 14 .BI "Quit \- Quit the application, kill messages flagged for deletion." .TP 14 .BI "Read (number) \- Read message number #. You may reply to it after reading it by using the Send Reply (SReply) command." .TP 14 .BI "Send \- Send a message. axMail will prompt you through everything step by step and also will ask you for two layers of receipt generations. .TP 14 .BI "STatus \- Quick listing of your mailbox status." .TP 14 .BI "Unkill \- Undelete or unkill a message flagged for deletion." .TP 14 .BI "Verbose \- Read your mail with full message headers for debugging." .SH FILES .LP .TP 5 .B /usr/local/etc/ax25/axmail.conf axMail configuration file. .br .TP 5 .B /etc/postfix/main.cf postfix configuration file. .br .SH AUTHORS Brian Rogers (N1URO) .br .SH OTHERS Marius Petrescu (YO2LOJ) .br Bob Tenty (VE3TOK) .br Heikki Hannikainen (OH7LZB) axmail-2.12.2/man/axmail.conf.50000644000175000017500000000511013254532003014775 0ustar n1uron1uro.TH AXMAIL.CONF5 "28 September 2015" Linux "Linux System Managers Manual" .SH NAME axMail \- A powerful but simple SMTP plugin for URONode. .SH SYNOPSIS .B axmail.conf .SH DESCRIPTION .LP .B axmail.conf This file configures the operations of axMail\-FAX. You have to insure that you add the proper group using addgroup. The common one to use is "ax25". .SH COMMANDS The following opions are supported for .B axmail.conf: .TP 14 .BI "IdleTimeout" This should not be longer than the same command in uronode.conf. .TP 14 .BI "HostName" This is the fully qualified hostname of your mail system. Typically this would be an amprnet domnain such as n1uro.ampr.org. .TP 14 .BI "AllowMail" This command controls who has access to use mail on your system. The default is all. .TP 14 .BI "Identification" This shows how users can authenticate into the application. The default is none as the password used over RF may also be used for popping/imap if the local sysop chooses to do this. Disconnect user from their mailbox." .TP 14 .BI "AutoCreate" This allows creation of the user accounts. Since you can also configure dovecot or a pop3 daemon and pop-before-smtp to allow mail on smartphones as well, this should be set to yes which is default. .TP 14 .BI "LoginAllowed" This grants or denies permissions for other functions such as ssh on the box. This also controls access to imap/pop. Default is yes. .TP 14 .BI "AutoGroup" I suggest using ax25. You'll have to set this using addgroup ax25. .TP 14 .BI "First_uid" This is the first user id numeric to be used when axmail creates accounts. I suggest 2000 as this keeps mail clients 1000 UID away from actual local clients so it'll somewhat separate them this way. .TP 14 .BI "Last_uid" This sets just how many users may create and use mailboxes using axmail. .TP 14 .BI "HomeDir" This sets the base of the users home directory. I suggest using the standard home directory for all users. .TP 14 .BI "Shell" This is the shell the users are granted. I suggest if you wish not to allow ssh or telnet access into your server to use /bin/false. .TP 14 .BI "FaxGate" This is the efax gateway to send your faxes through to. The SFax command will preformat your mail to use this gateway. Remove the quotes. .SH FILES .LP .TP 5 .B /usr/local/etc/ax25/welcome.txt Greeting file for new users to welcome them to the mail system. .br .TP 5 .B /etc/postfix/main.cf postfix configuration file. .br .SH AUTHORS Brian Rogers (N1URO) .br .SH OTHERS Marius Petrescu (YO2LOJ) .br Bob Tenty (VE3TOK) .br Heikki Hannikainen (OH7LZB)