Logo Search packages:      
Sourcecode: filter version File versions  Download package

utils.c

static char rcsid[] ="@(#)$Id: utils.c,v 5.4 1993/08/03 19:28:39 syd Exp $";

/******************************************************************************
 *  The Elm Mail System  -  $Revision: 5.4 $   $State: Exp $
 *
 *                Copyright (c) 1988-1992 USENET Community Trust
 *                Copyright (c) 1986,1987 Dave Taylor
 ******************************************************************************
 * Bug reports, patches, comments, suggestions should be sent to:
 *
 *    Philip Brown    filter@bolthole.com
 *
 ******************************************************************************
 * $Log: utils.c,v $
 *
 *  2000/10/20: added make_tempfile(), remove_tempfile() -- phil
 *
 *  1998/07/18: added "printlist" -- phil
 *
 * Revision 5.4  1993/08/03  19:28:39  syd
 * Elm tries to replace the system toupper() and tolower() on current
 * BSD systems, which is unnecessary.  Even worse, the replacements
 * collide during linking with routines in isctype.o.  This patch adds
 * a Configure test to determine whether replacements are really needed
 * (BROKE_CTYPE definition).  The <ctype.h> header file is now included
 * globally through hdrs/defs.h and the BROKE_CTYPE patchup is handled
 * there.  Inclusion of <ctype.h> was removed from *all* the individual
 * files, and the toupper() and tolower() routines in lib/opt_utils.c
 * were dropped.
 * From: chip@chinacat.unicom.com (Chip Rosenthal)
 *
 * Revision 5.3  1993/01/27  19:40:01  syd
 * I implemented a change to filter's default verbose message format
 * including %x %X style date and time along with username
 * From: mark@drd.com (Mark Lawrence)
 *
 * Revision 5.2  1992/11/15  01:40:43  syd
 * Add regexp processing to filter.
 * Add execc operator
 * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
 *
 * Revision 5.1  1992/10/03  22:18:09  syd
 * Initial checkin as of 2.4 Release at PL0
 *
 *
 *****************************************************************************/

/** Utility routines for the filter program...

**/

#include <stdio.h>
#include <pwd.h>
#include <fcntl.h>

#include "defs.h"
#include "filter.h"
#include "s_filter.h"

extern char *date_n_user();
extern char *datestring();

void leave(reason)
char *reason;
{
      if (outfptr != NULL)
      {
            fprintf(outfptr,"filter (%s): LEAVE %s\n", date_n_user(),
                  reason);
            fclose(outfptr);
      }
      
      exit(1);
}


/* we have a simple linked-list struct now. We sometimes want to print
 * it out. so print out contents, on a single line.
  * (Currently, will be used for "To:" list)
  */

void printlist(fptr, listing)
FILE *fptr;
LIST *listing;
{
      while(listing != NULL)
      {
            fprintf(fptr,"%s ", listing->str);
            listing=listing->next;
      }
}

void log_msg(what)
int what;
{
      /** make an entry in the log files for the specified entry **/

      FILE *fptr;
      int subj_len;

      if (!logging)
            return;

      if (! show_only) {
        if ((fptr = fopen(filtersum, "a")) == NULL) {
          if (outfptr != NULL)
            fprintf(outfptr,catgets(elm_msg_cat,
                            FilterSet,FilterCouldntOpenLogFile,
                          "filter (%s): Couldn't open log file %s\n"), 
                  date_n_user(), filtersum);
          fptr = stdout;
        }
        fprintf(fptr, "%d\n", rule_choosen);
        fclose(fptr);
      }

      if (show_only)
        fptr = stdout;
      else if ((fptr = fopen(filterlog, "a")) == NULL) {
        if (outfptr != NULL)
          fprintf(outfptr,catgets(elm_msg_cat,
                          FilterSet,FilterCouldntOpenLogFile,
                          "filter (%s): Couldn't open log file %s\n"), 
                date_n_user(), filterlog);
        fptr = stdout;
      }
      
#ifdef _IOFBF
      setvbuf(fptr, NULL, _IOFBF, BUFSIZ);
#endif

      subj_len = strlen(subject);
      fprintf(fptr,catgets(elm_msg_cat,FilterSet,FilterMailFrom,
                      "\n%s: Mail from "), datestring());
             
      if (strlen(Hfrom) + subj_len > 60)
        fprintf(fptr, "%s\n\t", Hfrom);
      else
        fprintf(fptr, "%s ", Hfrom);

      if (subj_len > 0)
        fprintf(fptr,catgets(elm_msg_cat,FilterSet,FilterAbout,
                       "about %s"),subject);
      fprintf(fptr, "\n");

      if (rule_choosen != -1)
        if (rules[rule_choosen].condition->matchwhat == TO)
          fprintf(fptr,catgets(elm_msg_cat,FilterSet,FilterAddressedTo,
                         "\t(addressed to "));
          printlist(fptr, tolist);
          fprintf(fptr,"\n");

      switch (what) {
        case DELETE_MSG : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterDeletedMesg,
                                     "\tDELETED"));
                          break;
        case FAILED_SAVE: fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterSaveFailedMesg,
                               "\tSAVE FAILED for file \"%s\""), 
                            rules[rule_choosen].argument2);
                          break;
        case SAVE       : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterSavedMesg,
                                     "\tSAVED in file \"%s\""), 
                            rules[rule_choosen].argument2);
                          break;
        case SAVECC     : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterSavedAndPutMesg,
                        "\tSAVED in file \"%s\" AND PUT in mailbox"), 
                            rules[rule_choosen].argument2);
                          break;
        case FORWARD    : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterForwardedMesg,
                                     "\tFORWARDED to \"%s\""), 
                            rules[rule_choosen].argument2);
                          break;
        case FORWARDC    : fprintf(fptr,catgets(elm_msg_cat,
                                    FilterSet,
                                    FilterForwardedAndPutMesg,
                      "\tFORWARDED to \"%s\" AND PUT in mailbox"), 
                             rules[rule_choosen].argument2);
                           break;
        case RESEND : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterResentMesg,
                                     "\tRESENT to \"%s\""),
                                     rules[rule_choosen].argument2);
                          break;
        case BOUNCE : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterBouncedMesg,
                                     "\tBOUNCED"));
                          break;

        case EXEC       : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterExecutedMesg,
                                     "\tEXECUTED \"%s\""),
                            rules[rule_choosen].argument2);
                          break;
        case EXECC      : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterExecutedSMesg,
                        "\tEXECUTED \"%s\" AND PUT in mailbox"),
                            rules[rule_choosen].argument2);
                          break;
        case LEAVE      : fprintf(fptr,catgets(elm_msg_cat,
                                     FilterSet,FilterPutMesg,
                                     "\tPUT in mailbox"));
                        break;
      }

      if (rule_choosen != -1)
        fprintf(fptr,catgets(elm_msg_cat,FilterSet,FilterByRule,
                       " by rule #%d\n"), rule_choosen+1);
      else
        fprintf(fptr,catgets(elm_msg_cat,FilterSet,FilterTheDefaultAction,
                        ": the default action\n"));

      fflush(fptr);
      fclose(fptr);
}

/* we should use this more. But right this second, I'm not doing retrofit*/
char *safemalloc(int bsize)
{
      char *retstr=(char*)malloc(bsize);
      if(retstr==NULL)
      {
        if (outfptr != NULL)
          fprintf(outfptr,catgets(elm_msg_cat,
                          FilterSet,FilterCantAllocRules,
                  "filter (%s): Can't alloc memory!\n"),
                  date_n_user());
        if (outfptr != NULL) fclose(outfptr);
        exit(1);
      }
      return retstr;
}

int
contains(str, pat)
char *str, *pat;
{
      /** Returns TRUE iff pat occurs IN IT'S ENTIRETY in str.
          The comparison is case insensitive.   **/

      register int i = 0, j = 0;

      while (str[i] != '\0') {
        while (tolower(str[i]) == tolower(pat[j])) {
          i++; j++;
          if (pat[j] == '\0') 
            return(TRUE);
        }
        i = i - j + 1;
        j = 0;
      }
      return(FALSE);
}

/* Note: Non-thread-safe static string returned */
char *itoa(i, two_digit)
int i, two_digit;
{     
      /** return 'i' as a null-terminated string.  If two-digit use that
          size field explicitly!  **/

      static char value[10];
      
      if (two_digit)
        sprintf(value, "%02d", i);
      else
        sprintf(value, "%d", i);

      return( (char *) value);
}

void lowercase(string)
char *string;
{
      /** translate string into all lower case **/

      register int i;

      for (i= strlen(string); --i >= 0; )
        if (isupper(string[i]))
          string[i] = tolower(string[i]);
}

/* convenience function to use strncpy, and explicitly zero the
 * last byte, since strncpy does not do so.
 *  WARNING: "len" should be total length of src,
 *    or, the total length of the resulting string you want PLUS 0.
 *
 * In other words strlen(result)+1  
 */
void stringcopy(char *dest, char *src, int len)
{
      strncpy(dest, src, len);
      dest[len-1]='\0';
}

/* the following code is borrowed from elm src/file.c
 * it has been stripped down to only handle ~ expansion
 */

int expand_filename(filename)
char *filename;
{
      /** Expands ~/    to the current user's home directory

          Side effect: strips off trailing blanks

          Returns       1     upon proper expansions
                  0     upon failed expansions
       **/

      char temp_filename[SLEN], *ptr;

      ptr = filename;
      while (*ptr == ' ') ptr++;    /* leading spaces GONE! */
      stringcopy(temp_filename, ptr, SLEN);

      /** New stuff - make sure no illegal char as last **/
      ptr = temp_filename + strlen(temp_filename) - 1;
      while (*ptr == '\n' || *ptr == '\r')
        *ptr-- = '\0';
        
      /** Strip off any trailing backslashes or blanks **/
      while (*ptr == '\\' || *ptr == ' ')
            *ptr-- = '\0';

      if ((temp_filename[0] == '~') &&
          (temp_filename[1] == '/')) {
          sprintf(filename, "%s%s%s",
              home, (lastch(home) != '/' ? "/" : ""), &temp_filename[2]);

      /* any further expansion, such as = + < >
       * would require parsing the elmrc file
       */

      } else
        stringcopy(filename, temp_filename, SLEN);
        
      return(1);
}

static int tmpinuse=0;


/* create a temporary file in a SAFE manner.
 * And also save the name in tmpfilename for easier cleanup on panic-exit.
 *  [via remove_tempfile()]
 *
 * Return a FILE* to it, or NULL on error.
 */
FILE* make_tempfile(){
      FILE *returnfp;
      int fd,mypid;

      mypid=getpid();

      if(tmpinuse!=0){
            fprintf(stderr,
                  "tempfile already in use, but make_tempfile called?\n");
            return NULL;
      }
      sprintf(tmpfilename,"%s_%s.%d", filter_temp, username, mypid);
      fd=open(tmpfilename, O_RDWR|O_CREAT|O_EXCL, 0600);
      if(fd==-1){
            sprintf(tmpfilename,"%s_%s.%d.2", filter_temp, username,mypid);
            fd=open(tmpfilename, O_RDWR|O_CREAT|O_EXCL,0600);
      }
      if(fd==-1){
            return NULL;
      }

      returnfp=fdopen(fd, "w+");
      tmpinuse=1;
      return (returnfp);
}

/* remove actual file created by make_tempfile().
 */
void remove_tempfile(){
      unlink(tmpfilename);
      tmpinuse=0;
}

Generated by  Doxygen 1.6.0   Back to index