📄 qfaxutil.c
字号:
/* qfaxutil.c - Library of shared functions for Renaissoft QFax 1.3 Copyright 1994-1996 Robert LeBlanc and Renaissoft*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <pwd.h>#include <grp.h>#include "qfax.h"void dispatch(Fax *f){/* Looks up the fax sender's username in /etc/group to determine whether he's one of the privileged few who can send faxes immediately, rather than having his fax stored in the queue for later processing. If so, qrun is invoked with special instructions to send only faxes belonging to that user.*/ struct group *grp; int i = 0; int found = 0; char cmd[LONGLEN]; if ((grp = getgrnam(FAXGROUP)) != NULL) { while (!found && grp->gr_mem[i]) found = (strcmp(f->fperson.username, grp->gr_mem[i++]) == 0); if (found) { sprintf(cmd, "qrun %s", f->fperson.username); system(cmd); } }}char *get_user(void){/* Tries to determine the user's userid, first using cuserid(), then getlogin(), then "whoami", and finally we check the environment variables $USER and $LOGNAME.*/ static char user[ALIASLEN]; FILE *ifp; strcpy(user, ""); cuserid(user); if (!user) { strcpy(user, getlogin()); if (!user) { if ((ifp = popen("whoami", "r")) != NULL) { fscanf(ifp, "%s", user); pclose(ifp); } else { strcpy(user, getenv("USER")); if (!user) strcpy(user, getenv("LOGNAME")); else strcpy(user, "nobody"); } } } return(user);}char *get_home(char *user){/* Returns the user's home directory from getpwent(), otherwise we try to read /etc/passwd directly, and lastly we try "/home/user".*/ char cmd[LINELEN]; static char home[LONGLEN]; FILE *ifp; struct passwd *pw; strcpy(home, ""); pw = getpwnam(user); strcpy(home, pw->pw_dir); if (!home) { sprintf(cmd, "grep \"%s:\" /etc/passwd | cut -d: -f6", user); strcpy(home, ""); if ((ifp = popen(cmd, "r")) != NULL) { fscanf(ifp, "%s", home); pclose(ifp); if (!home) sprintf(home, "/home/%s", user); } else { sprintf(home, "/home/%s", user); } } return(home);}char *getsline(FILE *p){/* Gets a newline terminated line from a file, strips the newline and returns the remaining string.*/ static char line[LINELEN]; fgets(line, LINELEN, p); line[strlen(line)-1] = '\0'; return(line);}char *getline(FILE *p){/* Returns the next non-comment/non-blank line from a file.*/ static char line[LINELEN]; char test[LINELEN]; int good = 0; while (!good) { strcpy(line, getsline(p)); strcpy(test, ""); sscanf(line, "%s", test); if ((test[0] != '#') && (test[0] != '\0')) good = 1; } return(line);}char *getfield(char *line){/* Skips the first non-whitespace token in a string and any trailing whitespace until the next non-whitespace character, then returns the remainder of the line. Useful for reading multi-word data fields from a string.*/ static char field[LINELEN]; int i = 0; int j = 0; strcpy(field, ""); while((line[i] != ' ') && (line[i] != '\t')) i++; while((line[i] == ' ') || (line[i] == '\t')) i++; for (j=i-1; j < strlen(line); j++) field[j-(i-1)] = line[j+1]; field[j-1] = '\0'; return(field);}void mail_user(char *user, char *subject, char *message){/* Sends a brief message to a (local) user by e-mail.*/ char tmp[LINELEN]; sprintf(tmp, "echo \"%s\" | mail -s \"%s\" %s", message, subject, user); system(tmp);}char *psfix(char *str){/* As '(' and ')' have to be escaped in PostScript, make sure we modify a string as necessary to return a "PostScript-safe" equivalent.*/ int i = 0; int j = 0; static char tmp[LONGLEN]; while (i < strlen(str)) { if (str[i] == '(') { tmp[j++] = '\\'; tmp[j++] = '('; } else if (str[i] == ')') { tmp[j++] = '\\'; tmp[j++] = ')'; } else { tmp[j++] = str[i]; } i++; } tmp[j] = '\0'; return (tmp);}void read_config(Fax *f){/* Reads the Qfax configuration file (fax.rc) to determine some initial settings for such things as page size, fonts to use for the cover page, label text, and information about your company.*/ FILE *cf; char tmp[LINELEN]; if ((cf = fopen(CONFIG, "r")) == NULL) { mail_user(f->fperson.username, "Qfax Error Message", "Can't read fax config file!"); exit(EXIT_FAILURE); } /* company info */ strcpy(f->fcompany.logoname, getline(cf)); strcpy(f->fcompany.fullname, getline(cf)); strcpy(f->fcompany.street, getline(cf)); strcpy(f->fcompany.city, getline(cf)); strcpy(f->fcompany.postcode, getline(cf)); strcpy(f->fcompany.phone, getline(cf)); strcpy(f->fcompany.fax, getline(cf)); strcpy(f->fcompany.domain, getline(cf)); /* e-mail info */ strcpy(f->labels.headerstart, getline(cf)); strcpy(f->labels.headerend, getline(cf)); /* page size info */ strcpy(tmp, getline(cf)); sscanf(tmp, "%d%d", &(f->pwidth), &(f->pheight)); /* font info */ strcpy(tmp, getline(cf)); sscanf(tmp, "%s%d", f->fonts.logo.name, &(f->fonts.logo.size)); strcpy(tmp, getline(cf)); sscanf(tmp, "%s%d", f->fonts.address.name, &(f->fonts.address.size)); strcpy(tmp, getline(cf)); sscanf(tmp, "%s%d", f->fonts.title.name, &(f->fonts.title.size)); strcpy(tmp, getline(cf)); sscanf(tmp, "%s%d", f->fonts.main.name, &(f->fonts.main.size)); strcpy(tmp, getline(cf)); sscanf(tmp, "%s%d", f->fonts.label.name, &(f->fonts.label.size)); /* label info */ strcpy(f->labels.title, getline(cf)); strcpy(f->labels.tocompany, getline(cf)); strcpy(f->labels.to, getline(cf)); strcpy(f->labels.tovoice, getline(cf)); strcpy(f->labels.tofax, getline(cf)); strcpy(f->labels.from, getline(cf)); strcpy(f->labels.email, getline(cf)); strcpy(f->labels.date, getline(cf)); strcpy(f->labels.pages, getline(cf)); strcpy(f->labels.regarding, getline(cf)); strcpy(f->labels.comments, getline(cf)); fclose(cf);}int read_db(Fax *f, char *dbfile){/* Scans the given fax database file (~/.fax or fax.db) to try to find a match for the recipient and his/her company. As an example, mail to "joe@megacorp.fax" would first cause the program to look up the alias "megacorp" in its database. If found, the program then checks the list of known users at megacorp, looking specifically for the alias "joe". If it finds a match in the database, it knows then that "joe" is "Joseph P. Smith", "megacorp" is "MegaCorp International", and voice and fax numbers are read. If no match is found, the routine returns an error code, which just means the recipient wasn't found in THIS database file.*/ FILE *db; char tmp[LINELEN]; char header[LINELEN]; int done = 0; if ((db = fopen(dbfile, "r")) == NULL) { return(1); } strcpy(tmp, getsline(db)); while (!done && !feof(db)) { sscanf(tmp, "%s", header); if (strcasecmp(header, f->tcompany.alias) == 0) { strcpy(f->tcompany.fullname, getfield(tmp)); strcpy(f->tcompany.phone, getsline(db)); strcpy(f->tcompany.fax, getsline(db)); strcpy(tmp, getsline(db)); while (!done && !feof(db)) { sscanf(tmp, "%s", header); if (strcasecmp(header, f->tperson.alias) == 0) { strcpy(f->tperson.fullname, getfield(tmp)); done = 1; } else if (tmp[0] == '+') { return(1); } if (!done) strcpy(tmp, getsline(db)); } } else { while (strcasecmp(getsline(db), "+") != 0) ; } if (!done) strcpy(tmp, getsline(db)); } fclose(db); if (!done) { return(1); } return(0);}void make_cover(Fax *f){/* The template cover page (cover-template.ps) has a number of variables hardwired into it, but these values are uninitialized. This routine makes a copy of the template page, inserting the necessary values into the copy so that it can be made into a proper PostScript program, for easy conversion to G3 format by Efax. The output filename for the copy of the cover page is of the form: FAXQUEUE/faxcover.user.timestamp.ps e.g. /usr/spool/fax/sendq/faxcover.tom.26Aug230715.ps The timestamp information is identical to the value used to stamp the associated fax file. The resulting *.ps file is Adobe PS 2.0 compatible, and can be used for any conceivable purpose, but its main purpose is to serve as a fax cover page for one specific fax message. "fax make" is called again to convert this PostScript file into a G3 fax.*/ FILE *ifp; FILE *of; char tmp[LINELEN]; char t1[LINELEN], t2[LINELEN], t3[LINELEN]; ifp = fopen(TEMPLATE, "r"); sprintf(tmp, "%s/faxcover.%s.%s.ps", FAXQUEUE, f->fperson.username, f->tstamp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -