1 /*
2 ** Copyright 2002-2009 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 #if	HAVE_CONFIG_H
7 #include	"config.h"
8 #endif
9 
10 #include	"courier.h"
11 #include	"moduledel.h"
12 #include	"comqueuename.h"
13 #include	"comfax.h"
14 #include	"rfc822/rfc822.h"
15 #include	"waitlib/waitlib.h"
16 #include	"unicode/unicode.h"
17 #include	"numlib/numlib.h"
18 #include	<stdlib.h>
19 #include	<locale.h>
20 #include	<langinfo.h>
21 #include	<string.h>
22 #include	<ctype.h>
23 #include	<signal.h>
24 #include	<errno.h>
25 #if	HAVE_UNISTD_H
26 #include	<unistd.h>
27 #endif
28 #if	HAVE_FCNTL_H
29 #include	<fcntl.h>
30 #endif
31 #include	<pwd.h>
32 #include	<sys/wait.h>
33 #include	<sys/time.h>
34 #include	"comctlfile.h"
35 #include	"comqueuename.h"
36 #include	"comstrtotime.h"
37 #include	"comstrtimestamp.h"
38 #include	"comverp.h"
39 #include	<sys/stat.h>
40 #include <sys/types.h>
41 #if HAVE_SYS_WAIT_H
42 #include <sys/wait.h>
43 #endif
44 #ifndef WEXITSTATUS
45 #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
46 #endif
47 #ifndef WIFEXITED
48 #define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
49 #endif
50 #include	"faxconvert.h"
51 #include	"sendfax.h"
52 #include	"faxtmpdir.h"
53 
54 static const char rcsid[]="$Id: courierfax.c,v 1.8 2009/11/08 18:14:47 mrsam Exp $";
55 
56 static void fax(struct moduledel *);
57 
58 const struct unicode_info *default_charset;
59 
60 /*
61 **  Kill the child process.
62 */
63 
killit(int n)64 static RETSIGTYPE killit(int n)
65 {
66 	module_signal(SIGKILL);
67 	exit(0);
68 #if RETSIGTYPE != void
69 	return (0);
70 #endif
71 }
72 
73 /*
74 ** Main loop.  Receive a message to deliver.  Fork off a child process.  Yawn.
75 */
76 
main(int argc,char ** argv)77 int main(int argc, char **argv)
78 {
79 	struct moduledel *p;
80 	int waitstat;
81 	const char *cp;
82 
83 	setlocale(LC_ALL, "");
84 	default_charset=unicode_find(nl_langinfo(CODESET));
85 	setlocale(LC_ALL, "C");
86 
87 	if (!default_charset)
88 		default_charset= &unicode_ISO8859_1;
89 
90 	clog_open_syslog("courierfax");
91 	if (chdir(getenv("COURIER_HOME")))
92 		clog_msg_errno();
93 
94 	cp=getenv("MAXDELS");
95 	if (!cp || atoi(cp) != 1)
96 	{
97 		clog_msg_start_err();
98 		clog_msg_str("FATAL: courierfax module misconfiguration, MAXDELS must be 1");
99 		clog_msg_send();
100 		exit(0);
101 	}
102 
103 	cp=getenv("MAXRCPT");
104 	if (!cp || atoi(cp) != 1)
105 	{
106 		clog_msg_start_err();
107 		clog_msg_str("FATAL: courierfax module misconfiguration, MAXRCPT must be 1");
108 		clog_msg_send();
109 		exit(0);
110 	}
111 
112 	module_init(0);
113 	while ((p=module_getdel()) != NULL)
114 	{
115 		pid_t	pid;
116 		unsigned delid;
117 
118 		delid=atol(p->delid);
119 
120 		if ((pid=module_fork(delid, 0)) == -1)
121 		{
122 			clog_msg_prerrno();
123 			module_completed(delid, delid);
124 			continue;
125 		}
126 
127 		if (pid == 0)
128 		{
129 			fax(p);
130 			exit(0);
131 		}
132 	}
133 
134 	module_signal(SIGTERM);
135 	signal(SIGCHLD, SIG_DFL);
136 	signal(SIGALRM, killit);
137 	alarm(5);
138 	wait(&waitstat);
139 	alarm(0);
140 	return (0);
141 }
142 
143 /*
144 **  All righty - pick up a message to deliver.
145 */
146 
faxabort(int n)147 static RETSIGTYPE faxabort(int n)
148 {
149 	signal(SIGTERM, SIG_IGN);
150 	kill(-getpid(), SIGTERM);
151 #if RETSIGTYPE != void
152 	return (0);
153 #endif
154 }
155 
read_childerrmsg(pid_t child_proc,int errfd,int (* errhandler)(int,char *,void *),void * errhandler_arg)156 static int read_childerrmsg(pid_t child_proc,
157 			    int errfd,
158 			    int (*errhandler)(int, char *, void *),
159 			    void *errhandler_arg)
160 {
161 	char errbuf[BUFSIZ];
162 	int errptr=0;
163 	int waitstat;
164 	pid_t p;
165 
166 	for (;;)
167 	{
168 		int n, i;
169 
170 		if (errptr >= BUFSIZ/4 * 3)
171 		{
172 			/* Read errmsg too big, strip it */
173 
174 			i=BUFSIZ/2;
175 
176 			for (n=BUFSIZ/2; n<errptr; n++)
177 				if (errbuf[n] == '\n')
178 				{
179 					i= n+1;
180 					break;
181 				}
182 
183 			strcpy(errbuf, "...\n");
184 			n=4;
185 			while (i < errptr)
186 				errbuf[n++] = errbuf[i++];
187 			errptr=n;
188 		}
189 
190 		n=read(errfd, errbuf+errptr, BUFSIZ-1-errptr);
191 		if (n <= 0)
192 			break;
193 		errptr += n;
194 	}
195 	errbuf[errptr]=0;
196 	close(errfd);
197 
198 	while ((p=wait(&waitstat)) != child_proc)
199 	{
200 		if (p < 0 && errno != EINTR)
201 			break;
202 	}
203 
204 	if (p == child_proc && WIFEXITED(waitstat) &&
205 	    WEXITSTATUS(waitstat) == 0)
206 		return (0);
207 
208 	if (errptr == 0)
209 		strcpy(errbuf, "courierfax: child process crashed.");
210 
211 	return (*errhandler)(p == child_proc && WIFEXITED(waitstat)
212 			     ? WEXITSTATUS(waitstat):1,
213 			     errbuf, errhandler_arg);
214 }
215 
216 struct faxconv_err_args {
217 	struct ctlfile *ctf;
218 	unsigned nreceip;
219 
220 	struct sort_file_list *file_list;
221 	int is_locked;
222 	int n_cover_pages;
223 } ;
224 
225 
faxconvert_cleanup(int dummy,char * errmsg,void * vp)226 static int faxconvert_cleanup(int dummy, char *errmsg, void *vp)
227 {
228 	struct faxconv_err_args *args=(struct faxconv_err_args *)vp;
229 
230 	ctlfile_append_reply(args->ctf, args->nreceip,
231 			     errmsg,
232 			     COMCTLFILE_DELFAIL_NOTRACK, 0);
233 	return (-1);
234 }
235 
236 extern int faxconvert(const char *, int, int *);
237 
238 static int faxsend_cleanup(int, char *, void *);
239 
fax(struct moduledel * p)240 static void fax(struct moduledel *p)
241 {
242 	struct	ctlfile ctf;
243 	unsigned nreceipients=p->nreceipients;
244 	const char *host=p->host;
245 	const char *receipient;
246 	unsigned nrecipient=(unsigned)atol(p->receipients[0]);
247 	int pipefd[2];
248 	pid_t child_proc;
249 	int faxopts;
250 	int n_cover_pages;
251 	FILE *fp;
252 
253 	struct faxconv_err_args err_args;
254 
255 	struct sort_file_list *page_list, *pp;
256 
257 
258 #if     HAVE_SETPGRP
259 #if     SETPGRP_VOID
260         setpgrp();
261 #else
262         setpgrp(0, 0);
263 #endif
264 #else
265 #if     HAVE_SETPGID
266         setpgid(0, 0);
267 #endif
268 #endif
269 
270 	if (comgetfaxopts(host, &faxopts))
271 	{
272 		clog_msg_start_err();
273 		clog_msg_str("courierfax: FATAL: invalid host");
274 		clog_msg_send();
275 		exit(1);
276 	}
277 
278 	putenv(faxopts & FAX_LOWRES ? "FAXRES=lo":"FAXRES=hi");
279 
280 	if (nreceipients != 1)
281 	{
282 		clog_msg_start_err();
283 		clog_msg_str("courierfax: FATAL: # receipients must be 1");
284 		clog_msg_send();
285 		exit(1);
286 	}
287 
288 	receipient=p->receipients[1];
289 	nrecipient=(unsigned)atol(p->receipients[0]);
290 
291 	if (ctlfile_openi(p->inum, &ctf, 0))
292 		clog_msg_errno();
293 
294 	/* Convert message to fax format, use a child process */
295 
296 	signal(SIGTERM, faxabort);
297 
298 	if (pipe(pipefd) < 0)
299 	{
300 		clog_msg_errno();
301 	}
302 
303 	child_proc=fork();
304 	if (child_proc < 0)
305 	{
306 		clog_msg_errno();
307 		return;
308 	}
309 
310 	if (child_proc == 0)
311 	{
312 		const char *fn;
313 
314 		close(0);
315 		if (open("/dev/null", O_RDONLY) != 0)
316 			clog_msg_errno();
317 
318 		close(pipefd[0]);
319 		close(1);
320 		if (dup(pipefd[1]) != 1)
321 		{
322 			perror("dup");
323 			exit(1);
324 		}
325 		close(2);
326 		if (dup(pipefd[1]) != 2)
327 		{
328 			fprintf(stderr, "ERROR: dup failed\n");
329 			exit(1);
330 		}
331 		close(pipefd[1]);
332 
333 		libmail_changeuidgid(MAILUID, MAILGID);
334 
335 		fn=qmsgsdatname(p->inum);
336 
337 		if (faxconvert(fn, faxopts, &n_cover_pages))
338 			exit (1);
339 
340 		if ((fp=fopen(FAXTMPDIR "/.ncoverpages", "w")) == NULL ||
341 		    fprintf(fp, "%d\n", n_cover_pages) < 0 ||
342 		    fflush(fp) < 0)
343 			exit(1);
344 		fclose(fp);
345 		exit(0);
346 	}
347 
348 	close(pipefd[1]);
349 
350 	err_args.ctf= &ctf;
351 	err_args.nreceip=nrecipient;
352 
353 	if (read_childerrmsg(child_proc, pipefd[0],
354 			     &faxconvert_cleanup, &err_args))
355 	{
356 		ctlfile_close(&ctf);
357 		return;
358 	}
359 
360 	/* Hit it */
361 
362 	if ((fp=fopen(FAXTMPDIR "/.ncoverpages", "r")) == NULL ||
363 	    fscanf(fp, "%d", &n_cover_pages) != 1)
364 	{
365 		if (fp)
366 			fclose(fp);
367 
368 		ctlfile_append_reply(err_args.ctf,
369 				     err_args.nreceip,
370 				     "Internal error: cannot read number of cover pages",
371 				     COMCTLFILE_DELFAIL, 0);
372 		ctlfile_close(&ctf);
373 		exit(0);
374 	}
375 
376 	page_list=read_dir_sort_filenames(FAXTMPDIR, FAXTMPDIR "/");
377 
378 	if (!page_list)
379 	{
380 		clog_msg_start_err();
381 		clog_msg_str("courierfax: INTERNAL ERROR - no pages to xmit.");
382 		clog_msg_send();
383 		exit(1);
384 	}
385 
386 	/* Keep trying until the modem line is unlocked */
387 
388 	do
389 	{
390 		if (pipe(pipefd) < 0)
391 		{
392 			clog_msg_errno();
393 		}
394 
395 		child_proc=fork();
396 		if (child_proc < 0)
397 		{
398 			clog_msg_errno();
399 			return;
400 		}
401 
402 		if (child_proc == 0)
403 		{
404 			unsigned page_cnt=0;
405 			char **argvec;
406 
407 			close(pipefd[0]);
408 			close(0);
409 			if (open("/dev/null", O_RDONLY) != 0)
410 			{
411 				perror("/dev/null");
412 				exit(1);
413 			}
414 			close(1);
415 			if (dup(pipefd[1]) != 1)
416 			{
417 				perror("dup");
418 				exit(1);
419 			}
420 			close(2);
421 			if (dup(pipefd[1]) != 2)
422 			{
423 				fprintf(stderr, "ERROR: dup failed\n");
424 				exit(1);
425 			}
426 			close(pipefd[1]);
427 
428 			for (pp=page_list; pp; pp=pp->next)
429 				++page_cnt;
430 
431 #if 0
432 			while (page_list)
433 			{
434 				unlink(page_list->filename);
435 				page_list=page_list->next;
436 			}
437 
438 			exit(0);
439 #endif
440 
441 			argvec=(char **)courier_malloc(sizeof(char *)*
442 						       (page_cnt+10));
443 
444 			argvec[0]=SENDFAX;
445 			argvec[1]="-v";
446 			argvec[2]="-r";
447 
448 			page_cnt=3;
449 
450 			if (faxopts & FAX_LOWRES)
451 				argvec[page_cnt++]="-n";
452 
453 			argvec[page_cnt++]=(char *)receipient;
454 
455 			while (page_list)
456 			{
457 				argvec[page_cnt++]=page_list->filename;
458 				page_list=page_list->next;
459 			}
460 			argvec[page_cnt]=0;
461 			execv(SENDFAX, argvec);
462 			perror(SENDFAX);
463 			exit(1);
464 		}
465 		close(pipefd[1]);
466 
467 		err_args.ctf= &ctf;
468 		err_args.nreceip=nrecipient;
469 		err_args.file_list=page_list;
470 		err_args.is_locked=0;
471 		err_args.n_cover_pages=n_cover_pages;
472 
473 		if (read_childerrmsg(child_proc, pipefd[0],
474 				     &faxsend_cleanup, &err_args) == 0)
475 		{
476 			size_t npages=0;
477 			char fmtbuf[NUMBUFSIZE];
478 			char fmtbuf1[NUMBUFSIZE];
479 			char fmtbuf2[NUMBUFSIZE+100];
480 
481 			for (pp=page_list; pp; pp=pp->next)
482 				++npages;
483 
484 			libmail_str_size_t(npages, fmtbuf);
485 			libmail_str_size_t(n_cover_pages, fmtbuf1);
486 
487 			sprintf(fmtbuf2,
488 				"%s pages - including %s cover page(s)"
489 				" - sent by fax.", fmtbuf, fmtbuf1);
490 
491 			ctlfile_append_reply(&ctf, (unsigned)
492 					     nrecipient,
493 					     fmtbuf2,
494 					     COMCTLFILE_DELSUCCESS, " l");
495 			break;
496 		}
497 	} while (err_args.is_locked);
498 
499 	ctlfile_close(&ctf);
500 	rmdir_contents(FAXTMPDIR);
501 }
502 
faxsend_cleanup(int errcode,char * errmsg,void * vp)503 static int faxsend_cleanup(int errcode, char *errmsg, void *vp)
504 {
505 	struct faxconv_err_args *args=(struct faxconv_err_args *)vp;
506 	unsigned pages_sent=0;
507 	char *p, *q;
508 
509 	int i;
510 	time_t now_time;
511 
512 	unsigned coverpage_cnt=0;
513 	unsigned page_cnt=0;
514 
515 	/* Check how many files sendfax renamed (were succesfully sent) */
516 
517 	while (args->file_list)
518 	{
519 		if (access(args->file_list->filename, 0) == 0)
520 			break;
521 
522 		if (coverpage_cnt < args->n_cover_pages)
523 			++coverpage_cnt;
524 		else
525 			++pages_sent;
526 		args->file_list=args->file_list->next;
527 	}
528 
529 	/* Strip out any blank lines in captured output from sendfax */
530 
531 	for (p=q=errmsg; *p; p++)
532 	{
533 		if (*p == '\n' && (p[1] == '\n' || p[1] == 0))
534 			continue;
535 
536 		*q++=*p;
537 	}
538 	*q=0;
539 
540 	/* Find the last message from sendfax */
541 
542 	for (p=q=errmsg; *p; p++)
543 	{
544 		if (*p != '\n')
545 			continue;
546 
547 		*p=0;
548 
549 		/* Dump sendfax's output to the log */
550 
551 		if (*q)
552 		{
553 			clog_msg_start_info();
554 			clog_msg_str("courierfax: " SENDFAX ": ");
555 			clog_msg_str(q);
556 			clog_msg_send();
557 		}
558 		q=p+1;
559 	}
560 
561 	if (*q)	/* Last line of the error message */
562 	{
563 		clog_msg_start_info();
564 		clog_msg_str("courierfax: " SENDFAX ": ");
565 		clog_msg_str(q);
566 		clog_msg_send();
567 	}
568 	else	/* Default message */
569 	{
570 		q=SENDFAX ": completed.";
571 	}
572 
573 	/*
574 	** Ugly hack: capture the following message from sendfax:
575 	**
576 	** /usr/sbin/sendfax: cannot access fax device(s) (locked?)
577 	*/
578 
579 #if 0
580 	lockflag=0;
581 	p=strchr(q, ':');
582 	if (p)
583 	{
584 		static const char msg1[]="cannot access fax device";
585 		static const char msg2[]="locked";
586 
587 		++p;
588 		while (*p && isspace((int)(unsigned char)*p))
589 			p++;
590 
591 		if (*p && strncasecmp(p, msg1, sizeof(msg1)-1) == 0)
592 		{
593 			p += sizeof(msg1);
594 			while (*p && !isspace((int)(unsigned char)*p))
595 				++p;
596 
597 			p=strchr(p, '(');
598 
599 			if (p && strncmp(p+1, msg2, sizeof(msg2)-1) == 0)
600 			{
601 				args->is_locked=1;
602 				clog_msg_start_info();
603 				clog_msg_str("courierfax: detected locked"
604 					     " modem line, sleeping...");
605 				clog_msg_send();
606 				sleep(60);
607 				return (-1);
608 			}
609 		}
610 	}
611 #else
612 
613 	if (errcode == 2)
614 	{
615 		args->is_locked=1;
616 		clog_msg_start_info();
617 		clog_msg_str("courierfax: detected locked"
618 			     " modem line, sleeping...");
619 		clog_msg_send();
620 		sleep(60);
621 		return (-1);
622 	}
623 #endif
624 
625 	ctlfile_append_connectioninfo(args->ctf, args->nreceip,
626 				      COMCTLFILE_DELINFO_REPLY, q);
627 
628 	sprintf(errmsg, "%u cover pages, %u document pages sent.",
629 		coverpage_cnt, page_cnt);
630 
631 	i=ctlfile_searchfirst(args->ctf, COMCTLFILE_FAXEXPIRES);
632 
633 	time(&now_time);
634 	ctlfile_append_reply(args->ctf, args->nreceip,
635 			     errmsg,
636 			     (pages_sent == 0 &&
637 			      i >= 0 &&
638 			      errcode < 10 &&
639 			      now_time < strtotime(args->ctf->lines[i]+1)
640 			      ? COMCTLFILE_DELDEFERRED:
641 			      COMCTLFILE_DELFAIL_NOTRACK), 0);
642 	return (-1);
643 }
644 
645