Path: utzoo!news-server.csri.toronto.edu!rutgers!mcnc!decwrl!uunet!papaya.bbn.com!rsalz From: rsalz@uunet.uu.net (Rich Salz) Newsgroups: comp.sources.unix Subject: v24i040: Email fax-sending package, Part02/05 Message-ID: <3369@litchi.bbn.com> Date: 13 Mar 91 19:14:09 GMT Lines: 2233 Approved: rsalz@uunet.UU.NET X-Checksum-Snefru: 4beb9ab3 f356640f 2c0d96d7 a288ae7b Submitted-by: klaus u schallhorn Posting-number: Volume 24, Issue 40 Archive-name: faxpax/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: FaxConfig faxhost/faxfonts/diykit.c faxhost/sendfax.c # Wrapped by rsalz@litchi.bbn.com on Wed Mar 13 14:08:01 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 2 (of 5)."' if test -f 'FaxConfig' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'FaxConfig'\" else echo shar: Extracting \"'FaxConfig'\" \(25531 characters\) sed "s/^X//" >'FaxConfig' <<'END_OF_FILE' X#!/bin/sh X# X# $Header: FaxConfig, 2.2.91, ks X# basically a [very much] stripped down and ripped off version of rn/Configure X# where it says: X# Yes, you may rip this off to use in other distribution packages. X# so I did X Xn='' Xc='' Xcontains='' X Xmodemtypes='1' X Xcharset='i' Xdevice="/dev/not_that_one" Xdevlock="LCK..nosuchdevice" Xdialstr="" Xdialtype='T' Xnet='y' Xnetwide_fax="NETWIDE_FAX" Xfaxhost="faxhost" Xfaxadmin=`whoami` Xfaxadmin="$faxadmin@"`hostname` Xfaxfmode='0644' Xfaxlib='/usr/local/lib/faxlib' Xfaxspool='/usr/local/spool/fax' Xfmtype="sierra" Xlocalbin='/usr/local/bin' Xloglevel='9' Xmanshelf='/usr/share/man' Xmaxresend='3' Xmaxage='1' Xmaxtry='5' Xtopspeed='7' Xuucplocks='/var/spool/locks' X X Xecho "Beginning of configuration questions for faxpak." Xecho " " X X: some greps do not return status, grrr. Xecho "grimblepritz" >grimble Xif grep blurfldyick grimble >/dev/null 2>&1 ; then X contains=contains Xelse X if grep grimblepritz grimble >/dev/null 2>&1 ; then X contains=grep X else X contains=contains X fi Xfi X X: sanity checks XPATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc' Xexport PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$) X Xif test ! -t 0; then X echo "Type 'sh FaxConfig', not 'sh .echotmp Xif $contains c .echotmp >/dev/null 2>&1 ; then X echo "...using -n." X n='-n' X c='' Xelse X echo "...using \\\c." X n='' X c='\c' Xfi Xecho $n "Type carriage return to continue. Your cursor should be here-->$c" Xread ans Xrm .echotmp X X: now set up to do reads with possible shell escape X: if this does not work on your machine, 1,$s/. myread/read ans/ Xcat <myread Xans='!' Xwhile expr "X\$ans" : "X!" >/dev/null; do X read ans X case "\$ans" in X !) X sh X echo " " X echo $n "Your answer: $c" X ;; X !*) X set \`expr "X\$ans" : "X!\(.*\)\$"\` X sh -c "\$*" X echo " " X echo $n "Your answer: $c" X ;; X esac Xdone XEOSC X X Xcat <faxconfig.h <b)?a:b) X#endif X X X /* network stuff */ X#ifdef NETWIDE_FAX X#define FAXHOST "$faxhost" /* get host by name */ X#endif X X X /* application specific stuff */ X#define FAXADMIN "$faxadmin" /* mail errors if !user */ X#define FAXFMODE $faxfmode /* for chmod */ X#define FAXSERVER "spool.fax" /* name of spool pgm */ X#define FAXLIB "$faxlib" /* needed on faxhost only */ X#define FAXSPOOL "$faxspool" /* needed on faxhost only */ X X#define UUCPLOCKS "$uucplocks" /* again host only */ X#define LOCALBIN "$localbin" /* client && host, for fax.c */ X X#define MAX_RESEND $maxresend /* don't resend a page forever */ X#define FAXLFONT "textfaxl.font" /* lores bitmap font from diykit */ X#define FAXHFONT "textfaxh.font" /* hires bitmap font from diykit */ X#define PSFONT "Courier-Bold12" /* ghostscript font */ X X#define MAX_FAX_LINES 2400 /* is a bit generous, so what */ X X#define COARSE 1 /* 204.15 by 97.79 dpi */ X#define FINE 2 /* 204.15 by 195.58 dpi */ X#define HP 3 X X#define ASCII 0 /* use hp laser jet compat font to create pbm */ X#define PBM 1 /* use as is, sort of */ X /* these aren't done yet, see wiring.c, why */ X#define DVI 2 /* dvi2ps, NOT YET DONE */ X#define GHOSTSCRIPT 3 /* ideas [not yet] stolen from mit ai labs */ X#define HPCL 4 /* hp laser jet compat output */ X X X /* fax modem specific bits */ X#define BETA_FIRMWARE /* applies to wiring.c */ X#define SIERRA /* type of fax modem */ X X X#ifdef NEED_FAXTYPES /* needed in fax.c and spool.fax.c */ Xstruct ftypes X{ X char *typename; X int typeid; X} faxtypes[] = X{ X "ascii", ASCII, X "pbm", PBM, X "dvi", DVI, X "postscript", GHOSTSCRIPT, X "hpcl" HPCL X}; X#define MAX_FTYPE sizeof(faxtypes)/sizeof(struct ftypes) X#endif /* need fax types */ X X Xstruct FAX X{ X long spooled; X char user[80]; X#ifdef JOBID X char jobid[80]; X#endif X char dname[256]; X char xname[256]; X char **phone; X int tries, X hires, X uid, X now, X mail, X pages, X type, X phone_nos; X long tpos, X ppos; X}; XEOT X Xecho "writing fax.config" X Xcat >fax.config < 1 X# X# international ones start with 010 cty code PLUS any combination of 1 to 9 X# X# This feature can be raped to make sure faxes to specific fax numbers X# are only sent at an acceptable [for the recipient] time, as shown in the X# first "hour entry". Hard coded phone nos should come before wild card X# entries. X# X# This sample states that long distance is ok from 6 pm to 6 am, X# international ones from 8 pm to 6 am X# X#hours 0104977777777 9 - 12 # this guy can only be sent to in the morning X#hours 01049123456 8 - 10 14 16 - 19 X#hours 0[1-9][1-9]* 18 - 6 # as in 078 123 6789 X#hours 0[2-9]* 18 - 6 # as in 030 455 6748 X#hours 010[1-9]* 20 - 6 # as in 01049 30 345 6789 X# X# X# max age of files in spool dir [days], fax is supposed to be fast! X# ============================= X# Xmaxage $maxage X# X# X# max number of attempts to connect X# ================================= X# Xmaxtry $maxtry X# X# log level X# ========= X# X# 9 = everything X# 0 = errors, transmission times X# other useful levels are 3 and 5 X# Xloglevel $loglevel X# X# X# end of fax.config XEOT X X# now save fax.1 man pages X########################## X Xecho "writing faxclient/fax.1 man pages" X Xcat >faxclient/fax.1 <Makefile <faxclient/Makefile <faxhost/Makefile <faxhost/faxfonts/Makefile <'faxhost/faxfonts/diykit.c' <<'END_OF_FILE' X#include X#include X#include X#include "diykit.h" X X#include "../../faxconfig.h" X Xstatic char *PGM = "diykit"; Xchar charset[128]; Xint bm_len; Xextern int errno; X Xstruct FNT_BITMAP /* one for each char */ X{ X short *SH; X short active; X} font[256]; X X Xfont_init(name) Xchar *name; X{ X FILE *hp; X int i; X struct FNT_BITMAP *cf; X static int fst; X char tmp[4]; X X errno = 0; X if (!fst) X for (i=0; i<256; i++) /* just to be safe */ X { X cf = &font[i]; X cf->SH = (short *)NULL; X cf->active = 0; X } X else for (i=0; i<256; i++) /* just to be safe */ X { X cf = &font[i]; X if (cf->SH) X free(cf->SH); X cf->SH = (short *)NULL; X cf->active = 0; X } X X if ((hp = fopen(name, "r")) == NULL) X { X fprintf(stderr,"%s: can't open %s font, errno %d\n",PGM,name,errno); X return(ERROR); X } X X if (fread(tmp, sizeof(char), 3, hp) != 3) X { X fprintf(stderr,"%s: can't read fontfile %s, errno %d\n",PGM,name,errno); X return(ERROR); X } X if (!strncmp(tmp, "fxL", 3)) X bm_len = 16; X else if (!strncmp(tmp, "fxH", 3)) X bm_len = 32; X else X { X fprintf(stderr,"%s: %s is not a bitmap font\n",PGM,name); X return(ERROR); X } X X if (rd_diykit(hp)) X return(ERROR); X X fclose(hp); X ++fst; X return(0); X} Xrd_diykit(fp) XFILE *fp; X{ X int i, lastc; X struct FNT_BITMAP *cf; X short cur_char; X char curchar[8]; X X for (cur_char=0;;) X { X lastc = cur_char; X /* not all machines are big endian ones */ X /* diykit therefore stores cur_char as a */ X /* 4 byte ascii string. It is, however written */ X /* as a short. */ X if ((i = fread(curchar, 4, 1, fp)) != 1) X { X if (cur_char > 0x7e && (!i)) X break; X fprintf(stderr,"%s: read error %d in font\n",PGM,errno); X return(ERROR); X } X curchar[4] = '\0'; X cur_char = (short)atoi(curchar); X if (cur_char <= 0x20 || cur_char > 0xff) X { X fprintf(stderr,"%s: illegal curchar value %04x after char %3d\n", X PGM,cur_char,lastc); X return(ERROR); X } X cf = &font[cur_char]; X X if ((cf->SH = (short *)malloc(bm_len * sizeof(short))) == (short *)NULL) X { X fprintf(stderr,"%s: not enough memory for bitmap array char %d\n", X PGM,cur_char); X return(ERROR); X } X X if (fread(cf->SH, sizeof(short), bm_len, fp) != bm_len) X { X fprintf(stderr,"%s: read error %d for char bitmap %d\n", X PGM,errno,cur_char); X return(ERROR); X } X cf->active = TRUE; X } X return(0); X} Xwritekit(hp,kit) XFILE *hp, *kit; X{ X struct FNT_BITMAP *cf; X short cur_char, i, pos; X char tmp[4]; X X if (bm_len == 16) X strcpy(tmp, "fxL"); X else strcpy(tmp, "fxH"); X X if (fwrite(tmp, sizeof(char), 3, hp) != 3) X { X fprintf(stderr,"%s: write error %d on fontfile\n",PGM,errno); X return(ERROR); X } X X for (cur_char=33; cur_char<128; cur_char++) X { X cf = &font[cur_char]; X if (cf->active) X { X if (fwrite(&cur_char, sizeof(short), 1, hp) != 1) X { X fprintf(stderr,"%s: write error %d on font\n", X PGM,errno); X return(ERROR); X } X if (fwrite(cf->SH, sizeof(short), bm_len, hp) != bm_len) X { X fprintf(stderr,"%s: write error %d on font\n", X PGM,errno); X return(ERROR); X } X } X } X X while ((cur_char = getnext_char(&pos,kit)) != EOF) X { X cf = &font[cur_char]; X if (cf->active) X { X if (fwrite(&pos, sizeof(short), 1, hp) != 1) X { X fprintf(stderr,"%s: write error %d on font\n", X PGM,errno); X return(ERROR); X } X if (fwrite(cf->SH, sizeof(short), bm_len, hp) != bm_len) X { X fprintf(stderr,"%s: write error %d on font\n", X PGM,errno); X return(ERROR); X } X } X } X return(0); X} Xgetnext_char(pos,fp) Xshort *pos; XFILE *fp; X{ X char buf[128], charname[40]; X int found, Pos; X static int line; X X for (;;) X { X if (fgets(buf, 126, fp) == NULL) X return(EOF); X ++line; X if (buf[0] != '#') X { X if (sscanf(buf,"%d %s",&Pos,charname) < 2) X { X fprintf(stderr,"%s: def file looks wrong to me at line %d\n",PGM,line); X return(EOF); X } X *pos = Pos; X if ((found = find_def(charname)) == EOF) X { X fprintf(stderr,"%s: unknown char def {%s} at at line %d\n", X PGM,charname,line); X return(EOF); X } X return(found); X } X } X} Xfind_def(s) Xchar *s; X{ X int mid, cmp, hi,lo; X X lo=0; X hi = MAX_DEF-1; X for (; lo<=hi;) X { X mid = (lo+hi)/2; X if ((cmp = strcmp(s, diy[mid].charname)) < 0) X hi = mid-1; X else if (cmp > 0) X lo = mid+1; X else return(diy[mid].chardef); X } X return(EOF);; X} Xmain() X{ X FILE *out, *kitfp; X char destname[256]; X X errno = 0; X if ((kitfp = fopen("diykit.def", "r")) == NULL) X { X fprintf(stderr,"%s: can't open diykit.def, errno %d\n",errno); X exit(1); X } X X if (fgets(charset, 126, kitfp) == NULL) X { X fprintf(stderr,"%s: can't read charset info on 1st line, errno %d\n", X PGM,errno); X exit(1); X } X if (font_init("lores.data")) X exit(1); X X sprintf(destname, "%s/%s", FAXLIB, FAXLFONT); X if ((out = fopen(destname, "w")) == NULL) X { X fprintf(stderr,"%s: can't create %s, errno %d\n", X PGM,destname,errno); X exit(1); X } X writekit(out,kitfp); X fclose(out); X chmod(destname, 0644); X X errno = 0; X rewind(kitfp); X if (fgets(charset, 126, kitfp) == NULL) X { X fprintf(stderr,"%s: can't read charset info on 1st line, errno %d\n", X PGM,errno); X exit(1); X } X if (font_init("hires.data")) X exit(1); X X sprintf(destname, "%s/%s", FAXLIB, FAXHFONT); X if ((out = fopen(destname, "w")) == NULL) X { X fprintf(stderr,"%s: can't create %s, errno %d\n", X PGM,destname,errno); X exit(1); X } X writekit(out,kitfp); X fclose(out); X fclose(kitfp); X chmod(destname, 0644); X X exit(0); X} END_OF_FILE if test 5399 -ne `wc -c <'faxhost/faxfonts/diykit.c'`; then echo shar: \"'faxhost/faxfonts/diykit.c'\" unpacked with wrong size! fi # end of 'faxhost/faxfonts/diykit.c' fi if test -f 'faxhost/sendfax.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'faxhost/sendfax.c'\" else echo shar: Extracting \"'faxhost/sendfax.c'\" \(20157 characters\) sed "s/^X//" >'faxhost/sendfax.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include X#include X#include X X#include "../faxconfig.h" X X/* X sendfax.c X X called frequently by cron, X inspect spool area for jobs to do - and get on with it X the actual squirting of data through the serial ports X is done in wiring.c X this file is concerned mainly with reading config info, X collecting and parsing all available x.files and X passing them on to forked copies of sendfax to share X the load X X if you have only one faxmodem, all work is done in house X without forking off slave clones X X first released version 0.99 [desperado version] X cleaned up Jan 22nd '91, X Copyright (C) 1991, klaus schallhorn, klaus@cnix.uucp X X Permission to use, copy, modify, and distribute this software X and its documentation for any purpose and without fee is hereby X granted, provided that the above copyright notice appear in X all copies and that both that copyright notice and this permission X notice appear in supporting documentation. X X This software is provided "as is" without express or implied warranty. X*/ X X#define COME_BACK 0 X#define GO_AWAY 1 X X#define ALLOWED 1 /* individual permissions, same as cron/at */ X#define DENIED 2 /* files: fax.allow, fax.deny */ X#define ROOT 3 X#define ALL 4 X Xchar faxrun[256], /* make a note that's sendfax is running */ X tmp[1024], X io[1024]; X X Xchar **faxjobs; /* list of x.files, jobs to do */ Xchar **Denied, **Allowed; /* fax permissions, same setup as cron */ Xchar **CanNow; /* in case the boss wants to override hours */ X Xstatic int pid, /* zip 'em all out to zero */ X max_age, /* days a fax may hover in spool dir */ X max_tries, /* max no of attempts to tx a fax [job] */ X faxperms, /* checking fax.allow && fax.deny */ X a_cnt, d_cnt, /* number of allowed/denied users */ X cn_cnt, /* no of unrestricted users */ X dev_cnt, /* number of devices faxable */ X todo; /* no of fax jobs in queue */ X Xint blah; /* chattynes for logging */ X Xstruct Hours /* restrict certain area/country codes to cheap hours, */ X{ /* or local faxes only between midday and noon */ X char *dialcode; X char hours[24]; X} *hour_ptr; Xstatic int h_entries; X X Xstruct config_funcs /* to read fax.config in any order */ X{ X int (*funcptr)(); /* function address */ X char *funcname; /* name used in config file */ X}; X Xint device(), incoming(), hours(), maxage(), maxtry(), loglevel(); Xchar **Devices, /* array of device names in /dev */ X **Devlocks, /* array of lock file names */ X **Faxtypes, /* array of fax modem types */ X **Wakeup, /* array of strings to revive modems */ X *Dialtyp, /* array of T's or P's [tone/pulse] */ X *Topspeed; /* array of one byte speed indicators */ X Xstruct config_funcs config_table[] = X{ X/* address funcname */ X { device, "device" }, X { incoming, "incoming" }, X { hours, "hours" }, X { maxage, "maxage" }, X { maxtry, "maxtry" }, X { loglevel, "loglevel" } X}; X#define MAX_CONFIG sizeof(config_table)/sizeof(struct config_funcs) X Xstruct FAX fax; X Xextern int errno; XFILE *popen(); X X Xmain(ac,av) Xint ac; Xchar *av[]; X{ X char *PGM; X X errno = blah = 0; X hour_ptr = NULL; X Topspeed = Dialtyp = NULL; X Allowed = Denied = CanNow = NULL; X Devices = Devlocks = Faxtypes = Wakeup = NULL; X X pid = getpid(); X X if ((PGM = strrchr(av[0], '/')) != NULL) X PGM++; X else PGM = av[0]; X X#ifndef TESTING X if (fork()) /* errs, parent, or unwanted relatives */ X exit(0); X if (setpgrp(0,0)) X { X fax_log(ERROR, "sendfax: can't create new prgp\n"); X exit(1); X } X#endif X X if (chdir(FAXSPOOL)) /* quick one, job done */ X { X fax_log(ERROR,"sendfax: can't cd to FAXSPOOL\n"); X exit(1); X } X if (read_config()) X exit(1); X X if (!strcmp(PGM, "rcvfax")) X exit(0); /*rcvfax(); when done */ X else /* sendfax */ X { /* see if sendfax is active, if so, go away */ X sprintf(faxrun, "%s/SEND.FAX.RUN",FAXLIB); X if (mklock(faxrun, FALSE, FALSE) < 0) X { X fax_log(5, "sendfax: busy\n"); X exit(0); /* last cron job of sendfax still busy */ X } X if ((todo = chk_queue()) > 0) X { X if (!blah) X fax_log(0, "sendfax: STARTUP, %d device%c, %d jobs pending\n", X dev_cnt,(dev_cnt>1)?'s':' ',todo); X else fax_log(9, "sendfax: %d jobs pending\n",todo); X runqueue(); X } X fax_log(5, "sendfax: done\n"); X unlink(faxrun); X } X exit(0); X} X Xrunqueue() X{ X int i, j, k, brk, in_use, slot, *kid_pids; X FILE *X; X X fax.phone = NULL; X X if (dev_cnt > 1) /* do this only if more than 1 faxmodem */ X { X if ((kid_pids = (int *)malloc(dev_cnt * sizeof(int))) == NULL) X { X fax_log(ERROR,"sendfax: can't allocate memory\n"); X return; X } X for (i=0; i1)?"es":"", X fax.tries, fax.user, X (fax.tries < max_tries)?"":", CANNOT RETRY"); X X if (fax.tries >= max_tries) X { X fclose(X); X continue; X } X X if (chk_perms()) X { X fclose(X); X fax_log(ERROR,"sendfax: user %s not permitted to use fax, mailed user, unlinked files\n",fax.user); X rmjob(faxjobs[i],fax.dname,fax.pages); X sprintf(tmp,"echo 'you have no permission to fax [fax admin: %s]' | mail %s",FAXADMIN,fax.user); X system(tmp); X continue; X } X X/* X can no longer avoid the issue. X if we have just 1 faxmodem, squirt one job now, X if we're sharing the load between several devices, find X an unused one and fork a copy to do the sending. If no X faxmodems avail, wait for one to pop up. X X All this assumes uucp is not interfering, this is checked X in "wiring.c", where we just die away [or return in case X of just 1 device] if port cannot be opened X*/ X if (dev_cnt == 1) X { X sendfax(X, slot, COME_BACK); X continue; X } X X for (k=0; kd_name, "x.f", 3)) X continue; X X if ((faxjobs[entries] = malloc(1+strlen(dp->d_name))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(faxjobs[entries++], dp->d_name); X } X closedir(dirp); X i = entries; X while (i < alloced) X faxjobs[i++] = NULL; X return(entries); X} Xread_config() X{ X FILE *cfg; X char a[256]; X int i; X X sprintf(a, "%s/fax.config", FAXLIB); X if ((cfg = fopen(a, "r")) == NULL) X { X fax_log(ERROR,"sendfax: can't open %s/fax.config\n",FAXLIB); X return(ERROR); X } X X while (fgets(io, 254, cfg) != NULL) X { X if (io[0] == '#' || (sscanf(io, "%s",a) < 1)) X continue; X for (i=0; i= 5) /* alternative STARTUP log is in main with blah == 0 */ X fax_log(5, "sendfax: STARTUP, %d device%c\n",dev_cnt,(dev_cnt>1)?'s':' '); X if (get_perms()) X return(ERROR); X return(0); X} Xfstbyte(s,skip) /* find fst usable item in a config line like: */ Xchar *s; /* device /dev/copperwire */ Xint skip; X{ X s += skip; X while (*s && isspace(*s)) X { X ++skip; X ++s; X } X return(skip); X} Xnxtint(s) Xchar *s; X{ X char *o; X X o = s; X while (*s && (isdigit(*s) || *s == '-')) X ++s; X while (*s && isspace(*s)) X ++s; X return((int)(s - o)); X} Xdevice(s) Xchar *s; X{ X static int d_alloced; X char dev[80], devlck[80], faxtyp[80], dial, speed, *sptr, *eptr; X X if (sscanf(s,"%s %s %s %c %c",dev,devlck,faxtyp,&dial,&speed) < 5) X return(ERROR); X X if (!d_alloced) X { X if (((Devices = (char **)malloc(4*sizeof(char *))) == NULL) X || ((Devlocks = (char **)malloc(4*sizeof(char *))) == NULL) X || ((Faxtypes = (char **)malloc(4*sizeof(char *))) == NULL) X || ((Wakeup = (char **)malloc(4*sizeof(char *))) == NULL) X || ((Dialtyp = (char *)malloc(4)) == NULL) X || ((Topspeed = (char *)malloc(4)) == NULL)) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X d_alloced = 4; X } X else if (d_alloced == dev_cnt) X { X d_alloced += 4; X if (((Devices = (char **)realloc(Devices, X d_alloced * sizeof(char *))) == NULL) X || ((Devlocks = (char **)realloc(Devlocks, X d_alloced * sizeof(char *))) == NULL) X || ((Faxtypes = (char **)realloc(Faxtypes, X d_alloced * sizeof(char *))) == NULL) X || ((Wakeup = (char **)realloc(Wakeup, X d_alloced * sizeof(char *))) == NULL) X || ((Dialtyp = (char *)realloc(Dialtyp, X d_alloced)) == NULL) X || ((Topspeed = (char *)realloc(Topspeed, X d_alloced)) == NULL)) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X if (((Devices[dev_cnt] = malloc(1+strlen(dev))) == NULL) X || ((Devlocks[dev_cnt] = malloc(1+strlen(devlck))) == NULL) X || ((Faxtypes[dev_cnt] = malloc(1+strlen(faxtyp))) == NULL)) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(Devices[dev_cnt], dev); X strcpy(Devlocks[dev_cnt], devlck); X strcpy(Faxtypes[dev_cnt], faxtyp); X Dialtyp[dev_cnt] = dial; X Topspeed[dev_cnt] = speed; X X if (((sptr = strchr(s, '"')) != NULL) X && ((eptr = strrchr(s, '"')) != NULL) X && (eptr > sptr)) X { X *eptr = '\0'; X ++sptr; X if ((Wakeup[dev_cnt] = malloc(1+(int)(eptr-sptr))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(Wakeup[dev_cnt], sptr); X } X else Wakeup[dev_cnt] = NULL; X X ++dev_cnt; X return(0); X} Xincoming(s) Xchar *s; X{ X/* haven't had time to do this X if (sscanf(s,"%s",Incoming) < 1) X*/ X return(ERROR); X} Xmaxtry(s) Xchar *s; X{ X if (sscanf(s,"%d",&max_tries) < 1) X return(ERROR); X return(0); X} Xloglevel(s) Xchar *s; X{ X if (sscanf(s,"%d",&blah) < 1) X return(ERROR); X return(0); X} Xmaxage(s) Xchar *s; X{ X if (sscanf(s,"%d",&max_age) < 1) X return(ERROR); X return(0); X} Xhours(s) Xchar *s; X{ X static int h_alloced; X int i, lasth; X char *p; X X if (sscanf(s,"%s",tmp) < 1) /* expect dial code */ X return(ERROR); X i = strlen(tmp); X s += fstbyte(s, i); /* skip him */ X X if (!h_entries) X { X if ((hour_ptr = (struct Hours *)malloc( X (h_alloced += 8) * sizeof(struct Hours))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X else if (h_alloced == h_entries) X { X if ((hour_ptr = (struct Hours *)realloc(hour_ptr, X (h_alloced += 8) * sizeof(struct Hours))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X if ((hour_ptr[h_entries].dialcode = malloc(1+i)) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(hour_ptr[h_entries].dialcode, tmp); X X p = hour_ptr[h_entries].hours; X for (i=0; i<24; i++) X *p++ = '\0'; X X lasth = -1; X p = hour_ptr[h_entries].hours; X X while (*s && *s != '#') X { X if (isdigit(*s)) X { X if ((i = atoi(s)) < 0 || i > 23) X return(ERROR); X p[i] = '\1'; X if (lasth > -1) X { X if (lasth < i) X { X while (lasth < i) X p[lasth++] = '\1'; X } X else X { X while (lasth < 24) X p[lasth++] = '\1'; X lasth = 0; X while (lasth < i) X p[lasth++] = '\1'; X } X lasth = -1; X } X s += nxtint(s); X } X else if (*s == '-') X { X lasth = i; X s += nxtint(s); X } X } X ++h_entries; X return(0); X} X#define MATCHCMASK 0377 X#define MATCHQUOTE 0200 X#define MATCHQMASK (MATCHCMASK&~MATCHQUOTE) X#define MATCHNOT '^' X Xstatic char *cclass(); X Xmatch(s, p) Xchar *s, *p; X{ X int sc, pc; X X while ((pc = *p++ & MATCHCMASK) != '\0') X { X sc = *s++ & MATCHQMASK; X switch (pc) X { X case '[': X if ((p = cclass(p, sc)) == NULL) X return(0); X break; X case '?': X if (sc == 0) X return(0); X break; X case '*': X s--; X do X { X if (*p == '\0' || match(s, p)) X return(1); X } while (*s++ != '\0'); X return(0); X default: X if (sc != (pc & ~MATCHQUOTE)) X return(0); X } X } X return(*s == 0); X} X Xstatic char *cclass(p, sub) Xchar *p; Xint sub; X{ X int c, d, not, found; X X if ((not = *p == MATCHNOT) != 0) X p++; X found = not; X X do X { X if (*p == '\0') X return(NULL); X c = *p & MATCHCMASK; X if (p[1] == '-' && p[2] != ']') X { X d = p[2] & MATCHCMASK; X p++; X } X else d = c; X X if (c == sub || c <= sub && sub <= d) X found = !not; X } while (*++p != ']'); X X return(found ? (p+1) : NULL); X} Xget_perms() X{ X FILE *fp; X int a_alloced, d_alloced, len; X X a_alloced = d_alloced = 0; X sprintf(tmp, "%s/fax.allow", FAXLIB); X if ((fp = fopen(tmp, "r")) != NULL) X { X if ((Allowed = (char **)malloc(8*sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X a_alloced = 8; X X for (;;) X { X if (a_cnt == a_alloced) X { X if ((Allowed = (char **)realloc(Allowed, X (a_alloced += 8) * sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X X if (fgets(tmp, 128, fp) == NULL) X break; X if ((len = strlen(tmp)) == 0) X break; X X tmp[--len] = '\0'; X if (!len) X continue; X if ((Allowed[a_cnt] = malloc(1+len)) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(Allowed[a_cnt++], tmp); X } X if (a_cnt) X faxperms = ALLOWED; X fclose(fp); X } X else X { X sprintf(tmp, "%s/fax.deny", FAXLIB); X if ((fp = fopen(tmp, "r")) != NULL) X { X if ((Denied = (char **)malloc(8*sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X d_alloced = 8; X X for (;;) X { X if (d_cnt == d_alloced) X { X if ((Denied = (char **)realloc(Denied, X (d_alloced += 8) * sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X X if (fgets(tmp, 128, fp) == NULL) X break; X if ((len = strlen(tmp)) == 0) X break; X X tmp[--len] = '\0'; X if (!len) X continue; X if ((Denied[d_cnt] = malloc(1+len)) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(Denied[d_cnt++], tmp); X } X if (d_cnt) X faxperms = DENIED; X else faxperms = ALL; X fclose(fp); X } X } X if (!faxperms) X faxperms = ROOT; X return(get_boss_perms()); X} Xget_boss_perms() X{ X FILE *fp; X int cn_alloced, len; X X cn_alloced = 0; X sprintf(tmp, "%s/fax.always", FAXLIB); X if ((fp = fopen(tmp, "r")) != NULL) X { X if ((CanNow = (char **)malloc(8*sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X cn_alloced = 8; X X for (;;) X { X if (cn_cnt == cn_alloced) X { X if ((CanNow = (char **)realloc(CanNow, X (cn_alloced += 8) * sizeof(char *))) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X } X X if (fgets(tmp, 128, fp) == NULL) X break; X if ((len = strlen(tmp)) == 0) X break; X tmp[--len] = '\0'; X if (!len) X continue; X if ((CanNow[cn_cnt] = malloc(1+len)) == NULL) X return(fax_log(ERROR,"sendfax: can't allocate memory\n")); X strcpy(CanNow[cn_cnt++], tmp); X } X fclose(fp); X } X fax_log(3, "sendfax: faxperms %d, allowed %d, denied %d, always %d\n", X faxperms, a_cnt, d_cnt, cn_cnt); X return(0); X} Xread_job(fp, xn) XFILE *fp; Xchar *xn; X{ X int i; X X if (fax.phone_nos) /* has been called before, clean up */ X { X for (i=0; itm_hour]) X return(ERROR); X return(FALSE); X } X return(FALSE); /* no restrictions on this phone number */ X} Xrmjob(xname,dname,pages) Xchar *xname,*dname; Xint pages; X{ X char buf[256], *d; X int i; X X unlink(xname); X for (i=0; i