home *** CD-ROM | disk | FTP | other *** search
- //=========================================================
- //
- // utils.c
- //
- // This file contains a number of utilities that other
- // routines use.
- //
- //=========================================================
-
- // $Id: utils.c,v 1.5 1994/02/23 17:42:44 gbj Exp user $
-
- /*
- $Log: utils.c,v $
- * Revision 1.5 1994/02/23 17:42:44 gbj
- * Removed check for user@host in replace_alias()
- *
- * Revision 1.4 1994/02/20 19:14:04 gbj
- * Added mail aliasing.
- *
- * Revision 1.3 1994/02/20 19:12:24 gbj
- * Added mail aliasing in setpost().
- *
- * Revision 1.2 1994/02/08 23:33:54 gbj
- * First public release.
- *
- * Revision 1.1 1994/02/08 03:16:14 gbj
- * Initial revision
- *
- */
-
- #include <time.h>
- #include "mailer.h"
- #include "utils.h"
-
- static void replace_alias(char *to, char *real_to);
-
- static char buf[4096], xbuf[4096], *bp;
-
- //=========================================================
- // int get_sequence(void)
- //
- // Open the sequence file ...\spool\mqueue\sequence.seq
- // Read the sequence number, increment it, add 1 to it and
- // rewrite the sequence file
- // Close the sequence file and return the new sequence number.
- //
- //=========================================================
- int get_sequence(void)
- {
- int res, seq;
-
- xfd=fopen(sequence, "rb+"); // Open for read and write
- if (xfd == NULL)
- {
- perror("get_sequence");
- fprintf(stderr, "Can't open %s\n", sequence);
- return -1;
- }
- res=fscanf(xfd, "%d", &seq);
- if (res != 1)
- {
- fprintf(stderr, "%s is corrupt\n", sequence);
- fclose(xfd);
- return -1;
- }
- seq++;
- res=fseek(xfd, 0, SEEK_SET);
- if (res == -1)
- {
- perror("get_sequence");
- fprintf(stderr, "Can't set %s to beginning of file\n");
- fclose(xfd);
- return -1;
- }
- fprintf(xfd, "%d\n", seq);
- fclose(xfd);
- return seq;
- }
-
- //=========================================================
- // void set_paths(int seq)
- //
- // Setup the relevant file names using the specified
- // sequnce number.
- //
- //=========================================================
- void set_paths(int seq)
- {
- char cmd[128];
-
- strcpy(wrk, mqueuepath);
- strcat(wrk, "\\"); // ../mqueue/
- sprintf(cmd, "%d", seq); // nnn
- strcat(wrk, cmd); // ../mqueue/nnn
- strcpy(txt, wrk); // ../mqueue/nnn
- strcat(wrk, ".wrk"); // ../mqueue/nnn.wrk
- strcat(txt, ".txt"); // ../mqueue/nnn.txt
- return;
- }
-
- //=========================================================
- // int set_wrk(char *to)
- //
- // Setup the .wrk file contents, given the recipient.
- //
- // recipient host [myhost if no host given]
- // sender
- // recipient
- //
- //=========================================================
- int set_wrk(char *to)
- {
- char xto[128];
- char *u, *h;
-
- wfd=fopen(wrk, "wb");
- if (wfd == NULL)
- {
- perror("set_wrk");
- fprintf(stderr, "Can't open %s\n", wrk);
- return 1;
- }
-
- scaneol(to);
- strcpy(xto, to);
- u=strtok(xto, "@");
- h=strtok(NULL, " ");
- if (u == NULL)
- {
- fprintf(stderr, "Bad recipient %s\n", to);
- fclose(wfd);
- return 1;
- }
- if (*u == '\0')
- {
- fprintf(stderr, "Bad recipient %s\n", to);
- fclose(wfd);
- return 1;
- }
- // write host [note, if no host, write myhost]
- if (h == NULL)
- fprintf(wfd, "%s\n", host);
- else if (*h == '\0')
- fprintf(wfd, "%s\n", host);
- else
- fprintf(wfd, "%s\n", h);
- // write sender
- fprintf(wfd, "%s@%s\n", user, host);
- // write recipient
- fprintf(wfd, "%s\n", to);
- fclose(wfd);
- return 0;
- }
-
- //=========================================================
- // int set_txt(char *to, char *subject, int seq, char *xfile)
- //
- // Setup the .txt file.
- // The recipient, subject, sequence number and file to
- // copy in are supplied.
- //
- // The message headers are set up:
- // Date:
- // Message-Id:
- // From:
- // Reply-To:
- // To:
- // X-Mailer:
- // Subject:
- // <cr>
- //
- // Then, if xfile != NULL, its contents are copied in.
- // After this, any signature is coped in.
- //
- //=========================================================
- int set_txt(char *to, char *subject, int seq, char *xfile)
- {
- char d[26];
- char *ddd, *mmm, *dd, *hhmmss,*yyyy, *bp;
- struct tm *ptr;
- time_t t;
-
- time(&t);
- ptr=gmtime(&t);
- strcpy(d, asctime(ptr));
- ddd=strtok(d, " \r\n");
- mmm=strtok(NULL, " \r\n");
- dd=strtok(NULL, " \r\n");
- hhmmss=strtok(NULL, " \r\n");
- yyyy=strtok(NULL, "\r\n");
-
- tfd=fopen(txt, "wb");
- if (tfd == NULL)
- {
- perror("setpost");
- fprintf(stderr, "setpost: Cannot open %s\n", txt);
- return 1;
- }
- fprintf(tfd, "Date: %-3.3s, %-2.2s %-3.3s %-2.2s %-8.8s GMT\n",
- ddd, dd, mmm, &(yyyy[2]), hhmmss);
- fprintf(tfd, "Message-Id: <%d@%s>\n", seq, host);
- fprintf(tfd, "From: %s@%s (%s)\n", user, host, name);
- fprintf(tfd, "Reply-To: %s@%s\n", user, host);
- fprintf(tfd, "To: %s\n", to);
- fprintf(tfd, "X-Mailer: %s\n",VERSION);
- fprintf(tfd, "Subject: %s\n\n", subject);
-
- // Copy any specified file
- if (xfile != NULL)
- if (*xfile != '\0')
- {
- xfd=fopen(xfile, "r");
- if (xfd != NULL) {
- bp=fgets(buf, 4095, xfd);
- while (bp != NULL) {
- scaneol(buf);
- strcat(buf, "\n");
- fputs(buf, tfd);
- bp=fgets(buf, 4095, xfd);
- }
- fclose(xfd);
- }
- }
-
- fprintf(tfd, "\n");
- fprintf(tfd, "-- \n"); // RFC says signature is two dashes+space
- // Copy in any signature file
- xfd=fopen(sig, "rb");
- if (xfd != NULL) {
- scaneol(buf);
- strcat(buf, "\n");
- bp=fgets(buf, 4095, xfd);
- while (bp != NULL) {
- fputs(buf, tfd);
- bp=fgets(buf, 4095, xfd);
- }
- fclose(xfd);
- }
- fclose(tfd);
- return 0;
- }
-
- //=========================================================
- // int call_editor(void)
- //
- // Call the user's favourite editor.
- //
- // NOTE: the editor and file to edit are specified in the
- // global char* variabled 'edit' and 'txt'. These should
- // really be passed as parameters.
- //
- //=========================================================
- int call_editor(void)
- {
- char cmd[128];
- int res;
-
- sprintf(cmd, "%s %s", edit, txt);
- res=system(cmd);
- if (res == -1)
- {
- perror("call_editor");
- fprintf(stderr,
- "Couldn't run editor, command line is:\n");
- fprintf(stderr, "%s\n", cmd);
- return 1;
- }
- else
- return 0;
- }
-
- //=========================================================
- // int tmp_msg(int msg, char *xfile, int quote, int copy_msg)
- //
- // This routine is doing too many things!
- //
- // Anyway, you are supplied with:
- //
- // msg the number of the message to copy
- // xfile the name of the file to copy this into
- // quote TRUE=quote each copied line (prepend >)
- // copy_msg TRUE=copy the message, FALSE=don't copy
- //
- //=========================================================
- int tmp_msg(int msg, char *xfile, int quote, int copy_msg)
- {
- FILE *mfd, *xfd;
- char *bp;
- char dbuf[80];
-
- if (msg < 0 || msg > maxmsgno)
- {
- fprintf(stderr, "tmp_msg: Message %d does not exist\n", msg);
- return 1;
- }
-
- if (xfile == NULL)
- {
- fprintf(stderr, "tmp_msg: No filename given\n");
- return 1;
- }
- if (*xfile == '\0')
- {
- fprintf(stderr, "tmp_msg: No filename given\n");
- return 1;
- }
-
- mfd=fopen(mbox, "rb");
- if (mfd == NULL)
- {
- perror("tmp_msg");
- fprintf(stderr, "tmp_msg: Can't open mailbox %s\n", mbox);
- return 1;
- }
-
- if (fseek(mfd, mailix[msg].fpos, SEEK_SET) == -1)
- {
- perror("tmp_msg");
- fclose(mfd);
- fprintf(stderr,
- "tmp_msg: Can't set file to start of message [%ld]",
- mailix[msg].fpos);
- return 1;
- }
-
- xfd=fopen(xfile, "wb");
- if (xfd == NULL)
- {
- perror("tmp_msg");
- fclose(mfd);
- fprintf(stderr, "tmp_msg: Can't open %s\n", xfile);
- return 1;
- }
-
- // Skip the From .... line
- bp=fgets(buf, 4095, mfd);
- bp=fgets(buf, 4095, mfd);
- if (copy_msg)
- {
- while (bp != NULL)
- {
- scaneol(buf);
- strcat(buf, "\n");
-
- strncpy(dbuf, buf, 78);
- dbuf[79]='\0';
-
- if (quote)
- {
- strcpy(xbuf, ">");
- strcat(xbuf, buf);
- }
- else
- strcpy(xbuf, buf);
- if (strncmp(buf, "From ", 5) == 0 && strchr(buf, '@'))
- break;
- else
- {
- // Not a From ... line, so put it out
- fputs(xbuf, xfd);
- }
- bp=fgets(buf, 4095, mfd);
- }
- }
- fclose(mfd);
- fclose(xfd);
- return 0;
- }
-
- //=========================================================
- // int fcopy(char *from, char *to, int header)
- //
- // Copy from file 'from' to file 'to', retain message
- // headers if header=TRUE.
- // If 'to' exists, you are asked if you want to Overwrite
- // it, Append to it, or Quit (abandon) the copy.
- //
- //=========================================================
- int fcopy(char *from, char *to, int header)
- {
- FILE *ifd, *ofd;
- int header_skipped, res, done, append, c;
-
- header_skipped=FALSE;
- append=FALSE;
- res=access(to, 0);
- if (res == 0)
- {
- done=FALSE;
- while (!done)
- {
- printf("\n%s Exists, (O)verwrite, (A)ppend or (Q)uit? ", to);
- c=toupper(getche());
- putchar('\r');
- putchar('\n');
- if (c == 'O')
- {
- done=TRUE;
- append=FALSE;
- }
- else if (c == 'A')
- {
- done=TRUE;
- append=TRUE;
- }
- else if (c == 'Q')
- return -1;
- else
- done=FALSE;
- }
- }
-
- ifd=fopen(from, "rb");
- if (ifd == NULL)
- {
- perror("fcopy");
- fprintf(stderr, "fcopy: Can't open %s\n", from);
- return 1;
- }
-
- if (append)
- ofd=fopen(to, "ab");
- else
- ofd=fopen(to, "wb");
- if(ofd == NULL)
- {
- perror("fcopy");
- fprintf(stderr, "fcopy: Can't open %s\n", to);
- fclose(ifd);
- return 1;
- }
-
- bp=fgets(buf, 4095, ifd);
- while(bp != NULL)
- {
- scaneol(buf);
- strcat(buf, "\n");
- if (header)
- fputs(buf, ofd);
- else
- if (header_skipped)
- fputs(buf, ofd);
- else
- if (*buf == '\n' || *buf == '\r' || *buf == '\0')
- header_skipped=TRUE;
-
- bp=fgets(buf, 4095, ifd);
- }
-
- fclose(ifd);
- fclose(ofd);
- return 0;
- }
-
- //=========================================================
- // void scaneol(char *buf)
- //
- // Scan buf for \r and \n and replace with \0.
- //
- //
- //=========================================================
- void scaneol(char *buf)
- {
- char *bp;
-
- bp=strchr(buf, '\n');
- if (bp)
- *bp='\0';
- bp=strchr(buf, '\r');
- if (bp)
- *bp='\0';
- }
-
- //=========================================================
- // int setpost(char *to, char *subject, char *xfile)
- //
- // Bump the sequence number in sequence.seq and save that
- // number for this item.
- // Translate any potential alias.
- // open nnn.wrk and setup the control data, then close it.
- // open nnn.txt and setup the default mail data, if xfile is
- // not null, include this file in nnn.txt as well, then close it.
- // Finally, call the user's editor.
- //
- // Return 1 if an error has occurred, otherwise return 0.
- //
- //=========================================================
-
- int setpost(char *to, char *subject, char *xfile)
- {
- int res, seq;
- char real_to[128];
-
- replace_alias(to, real_to);
-
- seq=get_sequence();
- if (seq == -1)
- return 1;
-
- // Setup paths to files
- set_paths(seq);
-
- // Now set up the .wrk file
- res=set_wrk(real_to);
- if (res)
- return 1;
-
- // Now setup the .txt file
- res=set_txt(real_to, subject, seq, xfile);
- if (res)
- return 1;
-
- // All done with the .txt file and call the editor
- res=call_editor();
- if (res)
- return 1;
-
- // Bye-bye
- return 0;
-
- }
-
- //=========================================================
- // void replace_alias(char *to, char *real_to)
- //
- // Scan the alias file and replace 'to' with any alias
- // in 'real_to'.
- // If the 'alias' file is not specified, or 'to' is not found,
- // just copy 'to' to 'real_to'.
- //
- // alias file format is:
- //
- // potential_alias real_address
- //
- //=========================================================
- static void replace_alias(char *to, char *real_to)
- {
- FILE *fd;
-
- char buf[81], *f1, *f2;
-
- strcpy(real_to, to); // Copy 'to' first
-
- if (*alias == '\0') // No alias file
- return;
-
- fd=fopen(alias, "r");
- if (fd == NULL) // Can't open alias file
- return;
-
- while (fgets(buf, 80, fd)) // Get a line
- {
- f1=NULL;
- f2=NULL;
- f1=strtok(buf, " \t\n"); // Get first token
- if (f1) // potential_alias?
- {
- f2=strtok(NULL, " \t\n"); // real_address?
- if (f2)
- {
- if (strcmp(to, f1) == 0)
- {
- strcpy(real_to, f2);
- break;
- }
- }
- }
- }
- fclose(fd);
- }
-