⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qrun.c

📁 使用efax的fax工具程序
💻 C
字号:
/* * qrun.c - Fax spool processor for Renaissoft Qfax 1.3 * Copyright 1994-1996 Robert LeBlanc and Renaissoft */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include "qfax.h"/* Non-exported function prototypes */void kill_daemon(void);void start_daemon(void);int send_fax(char *dialstring, char *filelist);char *error_message(int errcode);void notify_sender(int errcode, char *prefix, char *recipient, char *subject);int ok_to_call(char *dialstring);char *make_pagelist(char *prefix);void store_fax(char *prefix);char *make_pagelist(char *prefix){/*   Scans the FAXQUEUE directory for all pages with the same prefix, in   order to assemble a whitespace-separated list of files to be sent.*/  static char list[COMMENTLEN];  char cmd[LINELEN];  char tmp[LINELEN];  FILE *ls;  sprintf(cmd, "%s -1 %s.[0-9][0-9][0-9]", LS, prefix);  strcpy(list, "");  ls = popen(cmd, "r");  while (fscanf(ls, "%s", tmp) != EOF) {    strcat(list, " ");    strcat(list, tmp);  }  pclose(ls);  return(list);}void store_fax(char *prefix){/*   Move all files relating to a given fax to STOREDIR, where they can sit   indefinitely until the owner decides what to do with them.  By moving   them out of the spool directory, we prevent Qrun from trying to send   them out again the next time it's invoked.  Presumably this is done   only once the maximum number of attempts has been made without success.*/  char cmd[LINELEN];  sprintf(cmd, "rm -f %s.try", prefix);  system(cmd);  sprintf(cmd, "mv %s.* %s", prefix, STOREDIR);  system(cmd);}int ok_to_call(char *dialstring){/*   Returns true if it's ok to place the call at this time.  The idea is to   make sure that long-distance faxes only get sent out between their   designated hours.*/  int result;  int hstart, hend, mstart, mend, hnow, mnow;  int vstart, vend;  char *ptr;  char timerange[10];  char tstart[10];  char tstop[10];  struct tm  *tp;  time_t now;  if ((dialstring[0] == '1') || (dialstring[0] == '0')) {    strcpy(timerange, LDPERIOD);    ptr = strchr(timerange, '-');    *ptr = '\0';    strcpy(tstart, timerange);    strcpy(tstop, (++ptr));    if (strcasecmp(tstart, tstop) == 0) {      result = 1;    } else {      now = time(NULL);      tp = localtime(&now);      hnow = tp->tm_hour;      mnow = tp->tm_min;      vstart = atoi(tstart);      vend = atoi(tstop);      hstart = (vstart / 100);      if (hstart == 24)	hstart = 0;      mstart = (vstart % 100);      hend = (vend / 100);      if (hend == 24)	hend = 0;      mend = (vend % 100);      if (hend < hstart) {	if ((hnow > hstart) || (hnow < hend)) {	  result = 1;	} else if ((hnow == hstart) && (mnow >= mstart)) {	  result = 1;	} else {	  result = 0;	}      } else if (hend > hstart) {	if ((hnow > hstart) && (hnow < hend)) {	  result = 1;	} else if ((hnow == hstart) && (mnow >= mstart)) {	  result = 1;	} else {	  result = 0;	}      } else {	if ((mnow >= mstart) && (mnow < mend))	  result = 1;	else	  result = 0;      }    }  } else {    result = 1;  }  return (result);}void kill_daemon(void){/*   Kills the most recent active fax answer process and writes a .stop   file to prevent init() from respawning another one until further   notice.  This is useful to avoid interruptions from incoming calls   while we're trying to dial out.*/  char cmd[LINELEN];  sprintf(cmd, "%s stop > /dev/null", FAXSCRIPT);  system(cmd);  sleep(2);}void start_daemon(void){/*   Removes any .stop files that might be preventing init() from spawning   a new fax answer process.  We use this once we're done sending out   faxes, so that we can continue to receive incoming calls.   NOTE: You MUST have an entry in your inittab file running "fax answer",   since this routine does NOT actually restart Efax.*/  char cmd[LINELEN];  sprintf(cmd, "%s start", FAXSCRIPT);  system(cmd);}int send_fax(char *dialstring, char *pagelist){/*   Calls "send fax" with the given phone number and page list to   send.  Since Efax does its own error-trapping, we need to modify   the FAX script to write the resulting error code to a file called   RESULT just before it terminates, so that we can read and return   this value for our purposes.*/  char cmd[LINELEN];  int errcode;  FILE *ifp;  sprintf(cmd, "%s send %s %s > /dev/null", FAXSCRIPT, dialstring, pagelist);  system(cmd);  ifp = fopen(RESULT, "r");  fscanf(ifp, "%d", &errcode);  fclose(ifp);  return (errcode);}char *error_message(int errcode){/*   Returns an error message based on an Efax error code.  These messages   and codes come from the man page for Efax, and are subject to change.*/  static char message[255];  switch(errcode) {  case 0:    strcpy(message, "Fax was successfully transmitted.");    break;  case 1:    strcpy(message, "Modem was busy (device in use), retrying later.");    break;  case 2:    strcpy(message, "General error occurred (file not found, disk full, etc.).");    break;  case 3:    strcpy(message, "Modem protocol error occurred.");    break;  case 4:    strcpy(message, "Modem was not responding.");    break;  case 5:    strcpy(message, "Efax was terminated by a signal.");    break;  default:    strcpy(message, "An unknown error has occurred.  Please send in a bug report.");  }  return(message);}void notify_sender(int errcode, char *prefix, char *recipient, char *subject){/*   Sends the (local) sender of the fax an e-mail message notifying him that   an attempt to send the fax was made, and the results of this attempt.   The time in the e-mail header should serve as a timestamp record of when   the fax was last attempted, and the recipient's name and the subject of   the fax are quoted for reference.*/  char cmd[LINELEN];  char tmp[LINELEN];  char sender[ALIASLEN];  char letter[COMMENTLEN];  char timestr[SHORTLEN];  char *ptr;  FILE *ifp;  int code;  strcpy(tmp, prefix);  ptr = strrchr(tmp, '.');  *ptr = '\0';  ptr = strrchr(tmp, '.');  strcpy(sender, (++ptr));  strcpy(letter, "An attempt to send your fax\n\n");  sprintf(tmp, ">>>      To: %s\n", recipient);  strcat(letter, tmp);  sprintf(tmp, ">>> Subject: %s\n\n", subject);  strcat(letter, tmp);  strcat(letter, "was made, with the following results:\n\n");  sprintf(tmp, "%s.try", prefix);  if ((ifp = fopen(tmp, "r")) != NULL) {    while (fscanf(ifp, "%d\n", &code) != EOF) {      strcpy(timestr, getsline(ifp));      sprintf(tmp, "%s: [%d] %s\n", timestr, code, error_message(code));      strcat(letter, tmp);    }    fclose(ifp);  }  strcpy(timestr, timestring());  sprintf(tmp, "%s: [%d] %s\n", timestr, errcode, error_message(errcode));  strcat(letter, tmp);  if (errcode > 0) {    strcpy(cmd, prefix);    ptr = strrchr(cmd, '/');    strcpy(cmd, (++ptr));    sprintf(tmp, "\nYour fax, %s.*,has been moved to %s.\n",	    cmd, STOREDIR);    strcat(letter, tmp);    sprintf(tmp, "To send it again, move these files back to %s.\n", FAXQUEUE);    strcat(letter, tmp);  }  sprintf(cmd, "echo \"%s\" | mail -s \"Fax Transmission Notification\" %s",	  letter, sender);  system(cmd);}void main(int argc, char *argv[]){  int i, faxes, errcode, code, tries;  char cmdlist[MAXFAXES][LINELEN];  char dialstring[PHONELEN];  char recipient[LONGLEN];  char subject[LINELEN];  char prefix[LINELEN];  char timestr[SHORTLEN];  char tmp[LINELEN];  char username[SHORTLEN];  FILE *ifp, *ofp;  /*     Assemble a list of the faxes waiting in FAXQUEUE to go out.  */  faxes = make_cmdlist(cmdlist);  if (!faxes)  /*     No faxes waiting to be sent, so we have nothing to do.   */    exit(EXIT_SUCCESS);#ifdef USE_DAEMON  /*     Kill any existing fax answer daemon, just to be sure that we aren't     interrupted before we seize the line.   */  kill_daemon();#endif  if (argc > 1)    strcpy(username, argv[1]);  else    username[0] = '\0';  for (i=0; i < faxes; i++) {    get_cmdinfo(cmdlist[i], dialstring, recipient, subject);    if (ok_to_call(dialstring)) {      strcpy(prefix, make_prefix(cmdlist[i]));      if ((argc == 1) || (strstr(prefix, username) != NULL)) {        errcode = send_fax(dialstring, make_pagelist(prefix));        if (!errcode) {          /* No errors, delete the fax and notify the sender */          notify_sender(errcode, prefix, recipient, subject);          delete_fax(prefix);        } else {          /* 	     An error occurred, so let's see whether we should	     try again or give up.           */          sprintf(tmp, "%s.try", prefix);          if ((ifp = fopen(tmp, "r")) != NULL) {	    /* We've tried to send this fax before */	    tries = 0;	    while (!feof(ifp)) {	      fscanf(ifp, "%d\n", &code);	      fgets(timestr, SHORTLEN, ifp);	      tries++;            }	    fclose(ifp);	    if (tries >= MAXTRIES) {	      /*	         We've reached our limit; give up, store the fax and	         notify the sender.	       */	      notify_sender(errcode, prefix, recipient, subject);	      store_fax(prefix);	    } else {	      /*	         Try again next time Qrun is invoked, but make a note	         of the fact that we tried, writing the errorcode and	         the time/date to the *.try file.	       */	      ofp = fopen(tmp, "a");	      strcpy(timestr, timestring());	      fprintf(ofp, "%d\n%s\n", errcode, timestr);	      fclose(ofp);	    }          } else {	    /*	       We've never tried to send this fax before, so we make a	       record of the fact that we've failed once now.	     */	    ofp = fopen(tmp, "a");	    strcpy(timestr, timestring());	    fprintf(ofp, "%d\n%s\n", errcode, timestr);	    fclose(ofp);          }        }        sleep(15);      }    }  }#ifdef USE_DAEMON  /*      Restart the fax answer daemon so we can continue to receive     incoming faxes, now that we're done sending.   */  start_daemon();#endif  exit(EXIT_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -