1 /* EMAILPKT: Husky e-mailer
2 *
3 * (C) Copyleft Stas Degteff 2:5080/102@FIDOnet, g@grumbler.org
4 * (c) Copyleft Husky developers team http://husky.sorceforge.net/team.html
5 *
6 * $Id$
7 * Send FTN via email
8 *
9 * For latest version see http://husky.sorceforge.net/emailpkt
10 *
11 * This file is part of EMAILPKT, module of The HUSKY Fidonet Software.
12 *
13 * EMAILPKT is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
17 *
18 * EMAILPKT is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public
24 * License along with this library; see file COPYING. If not, write to the Free
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 * See also http://www.gnu.org, license may be found here.
28 *****************************************************************************
29 */
30
31 /* libc */
32 #include <string.h>
33 #include <stdio.h> /*FILE operations*/
34 #include <time.h>
35 #include <stdlib.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <ctype.h>
39 #include <limits.h>
40
41 #include <smapi/compiler.h>
42
43 #ifdef HAS_UNISTD_H
44 # include <unistd.h>
45 #endif
46 #ifdef HAS_DIRENT_H
47 # include <dirent.h>
48 #endif
49
50 /* husky */
51 #include <fidoconf/log.h>
52 #include <fidoconf/temp.h>
53 #include <fidoconf/xstr.h>
54
55 /* ./ */
56 #include "ecommon.h"
57 #include "version.h"
58
59 #if defined(__MINGW32__) || defined(_MSC_VER)
60 # define random() rand()
61 #endif
62
63 #ifndef nfree
64 # define nfree(a) ({ if (a != NULL) { fprintf(stderr,"hesend.c:%d nfree()\n",__LINE__); free(a); a = NULL; } })
65 #endif
66
67 #define PROGRAMNAME "hesend"
68 #define TEMPEXT "emo" /* "e-mail outgoing" */
69 #define TEMPFLOEXT "flo"
70
71 s_fidoconfig *config=NULL;
72 static int sent = 0, allsent=0; /* sent files count */
73
74 int SAVEFLAG=0; /* Save processed e-mail messages (for debugging) */
75 int debugflag=0; /* Execute in debug mode (not call sendmail, not remove files) */
76
77 /* Write e-mail messsage with attached file (bundle)
78 * Return filename or NULL
79 */
writeMessage(const char * fullFileName,s_link link)80 char *writeMessage(const char *fullFileName, s_link link)
81 { char adr[ADRS_MAX];
82 char basefilename[NAME_MAX];
83 char *tempfilename=NULL, timebuf[32], *msgidbuf=NULL;
84 FILE *infd=NULL, *tempfd=NULL;
85 char *cp=NULL;
86 time_t t=0;
87 struct tm *tm=NULL;
88 int i;
89
90 w_log(LL_FUNC,"writeMessage()");
91
92 snprintaddr(adr, sizeof(adr), link.hisAka);
93
94 w_log(LL_FILENAME, "Full file name: '%s'", fullFileName);
95 /* input file name */
96 if ((infd = fopen(fullFileName, "r")) == NULL) {
97 w_log( LL_ERR, "Can't open '%s': %s", fullFileName, strerror(errno));
98 return NULL;
99 }
100
101 tempfd = createTempFileIn(config->tempOutbound, TEMPEXT, 'b', &tempfilename);
102 if( !tempfd ) {
103 fclose(infd);
104 w_log( LL_ERR, "Can't create temp file in '%s': %s",
105 config->tempOutbound, strerror(errno));
106 return NULL;
107 } /*else w_log(LL_FILENAME, "tempfilename=%s", tempfilename);*/
108
109 /* for netmail (.?ut) change ext to pkt */
110 i = sstrlen(fullFileName);
111 if( tolower(fullFileName[i-2]) == 'u' && tolower(fullFileName[i-1]) == 't' )
112 { if( (cp = makeUniqueDosFileName( "", "pkt", config)) )
113 { strncpy(basefilename, cp, sizeof(basefilename));
114 nfree( cp );
115 }else w_log(LL_CRIT, "Can't generate unique dos file name: memory too low" );
116 }else
117 {
118 sstrncpy( basefilename, (char*)basename(fullFileName), sizeof(basefilename) );
119 w_log(LL_FILENAME, "Base file name: '%s'", basefilename);
120 }
121
122 /* print some headers */
123 if( link.emailFrom == NULL )
124 {
125 fprintf(tempfd, "From: \"%s\" <%s>\n", DEFAULT_FROMNAME, DEFAULT_FPOMADDR);
126 w_log(LL_WARN, "Undefined emailFrom for %s, use default: %s",
127 adr, DEFAULT_FPOMADDR );
128 }
129 else
130 fprintf(tempfd, "From: \"%s\" <%s>\n", DEFAULT_FROMNAME, link.emailFrom );
131
132 fprintf(tempfd, "To: %s\n", link.email );
133
134 if( link.emailSubj == NULL )
135 {
136 fprintf(tempfd, "Subject: %s\n", DEFAULT_SUBJECT );
137 w_log(LL_WARN, "Undefined emailSubj for %s, use default: %s",
138 link.emailSubj, DEFAULT_SUBJECT );
139 }
140 else fprintf(tempfd, "Subject: %s\n", link.emailSubj );
141
142
143 time (&t);
144 tm = localtime (&t);
145
146 strftime(timebuf, sizeof (timebuf), "%a, %d %b %Y %H:%M:%S %z", tm);
147 fprintf(tempfd, "Date: %s\n", timebuf);
148
149 strftime(timebuf, sizeof (timebuf), "%s", tm);
150
151 /*
152 xscatprintf( &msgidbuf, "%s %ul", timebuf, (unsigned long)random());
153 */
154 if( link.emailFrom )
155 xscatprintf( &msgidbuf, "%s.%lu.%s", timebuf, (unsigned long)random(), link.emailFrom );
156 else if( link.ourAka[0].point )
157 xscatprintf( &msgidbuf,
158 "%s.%lu@p%u.f%u.n%u.z%u.%s.org\n", timebuf,
159 (unsigned long)random(), link.ourAka[0].point, link.ourAka[0].node,
160 link.ourAka[0].net, link.ourAka[0].zone,
161 link.ourAka[0].domain ? link.ourAka[0].domain : "fidonet" );
162 else
163 xscatprintf( &msgidbuf,
164 "%s.%lu@f%u.n%u.z%u.%s.org\n", timebuf,
165 (unsigned long)random(), link.ourAka[0].node,
166 link.ourAka[0].net, link.ourAka[0].zone,
167 link.ourAka[0].domain ? link.ourAka[0].domain : "fidonet" );
168
169 fprintf( tempfd, "Message-ID: <%s>\n", msgidbuf );
170 fprintf( tempfd, "X-Mailer: %s\n", program_name);
171
172 switch( link.emailEncoding ){
173
174 case eeUUE: /* uuencode file */
175
176 w_log(LL_ENCODE, "Encode method for %s: UUE", adr );
177
178 if( strlen(DEFAULTBODY)>0 )
179 {
180 fprintf(tempfd, "\n\n%s\n", DEFAULTBODY);
181 }
182
183 uuencodeFile(infd, tempfd, basefilename, 0, 0);
184 break;
185
186 /* SEAT internal "protocol" - MIME/base64 encoding */
187 /*
188 case eeIREX:
189
190 fprintf(tempfd, "Mime-Version: 1.0\n");
191 fprintf(tempfd, "Content-Type: multipart/mixed; boundary=\"%s\"\n",MIMEBOUNDARY);
192
193 fprintf(tempfd, "Ftn-File-ID: %s\n", msgidbuf );
194 fprintf(tempfd, "Ftn-Crc32: %X\n", crc32 );
195 fprintf(tempfd, "Ftn-Seg: %u-%u\n", segno, seg );
196 fprintf(tempfd, "Ftn-Seg-Crc32: %X\n", crc32seg );
197 fprintf(tempfd, "Ftn-Seg-ID: %u.%s", segno, msgidbuf );
198
199 if( strlen(DEFAULTBODY)>0 )
200 {
201 fprintf(tempfd, "\n\n%s\n", DEFAULTBODY);
202 }
203
204 //This is a MIME encoded message generated by Internet Rex.
205 //If your mailer doesn't support this type of coding,
206 //you can decode the file attached using a program like
207 //'munpack'. 'munpack' is available for anonymous FTP
208 //from ftp://ftp.andrew.cmu.edu/pub/mpack
209
210 */
211 case eeSEAT: /* SEAT "protocol" - MIME/base64 encoding */
212 w_log(LL_ENCODE, "Encode method for %s: SEAT (MIME)", adr );
213 case eeMIME: /* MIME/base64 */
214 w_log(LL_ENCODE, "Encode method for %s: MIME", adr );
215 default:
216 w_log(LL_ENCODE, "Encode method for %s: MIME (default)", adr );
217
218 /* Main section */
219 fprintf(tempfd, "Mime-Version: 1.0\n");
220 fprintf(tempfd, "Content-Type: multipart/mixed; boundary=\"%s\"\n",MIMEBOUNDARY);
221
222 fprintf(tempfd, "\n--%s\n",MIMEBOUNDARY);
223 fprintf(tempfd, "Content-Type: text/plain");
224 if( strlen(DEFAULTBODY)>0 )
225 {
226 fprintf(tempfd, "\n\n%s\n", DEFAULTBODY);
227 }
228
229 /* Attachment section */
230 fprintf(tempfd, "\n--%s\n",MIMEBOUNDARY);
231 fprintf(tempfd, "Content-Type: application/octet-stream; name=\"%s\"\n", basefilename);
232 fprintf(tempfd, "Content-Transfer-Encoding: base64\n");
233 fprintf(tempfd, "Content-Disposition: attachment; filename=\"%s\"\n\n", basefilename);
234
235 base64encodeFile(infd, tempfd);
236
237 fprintf(tempfd, "\n\n--%s--\n",MIMEBOUNDARY);
238 break;
239
240
241 } /* switch */
242
243 fclose(infd);
244 fclose(tempfd);
245
246 nfree(msgidbuf);
247 /* nfree(cp); not malloc'ed */
248 /* nfree(basefilename); not malloc'ed */
249 w_log(LL_FILENAME, "Return file name: '%s'", tempfilename );
250 w_log(LL_FUNC,"writeMessage() OK");
251 return sstrdup(tempfilename);
252 }
253
254 /* Send written message
255 */
sendFile(const char * filename,s_link link)256 int sendFile(const char *filename, s_link link)
257 { char *buf=NULL, *cmd=NULL, *p=NULL;
258 int rc;
259
260 w_log(LL_FUNC,"sendFile()");
261
262 /* Contruct sendmail command
263 If $a and $f not present use 'sendmailcmd address < file'
264 */
265 cmd = sstrdup( config->sendmailcmd );
266 w_log(LL_DEBUGS,"%s::sendFile():%u Command construct: '%s'", __FILE__, __LINE__, cmd);
267 p=strstr(cmd, "$a");
268 if( p ){
269 *p++ = '%'; *p='s';
270 xscatprintf( &buf, cmd, link.email);
271 }
272 else
273 xscatprintf( &buf, "%s %s", config->sendmailcmd, link.email);
274 nfree(cmd);
275
276 w_log(LL_DEBUGS,"%s::sendFile():%u Command construct: '%s'", __FILE__, __LINE__, cmd);
277
278 p=strstr(buf, "$f");
279 if( p ){
280 *p++ = '%'; *p='s';
281 xscatprintf( &cmd, buf, filename);
282 }
283 else
284 xscatprintf( &cmd, "%s < %s", buf, filename);
285 nfree(buf);
286
287 w_log(LL_EXEC,"Execute '%s'",cmd);
288 if( debugflag>1 ){
289 w_log(LL_ERR, "(debug) Cmd line: '%s'", cmd);
290 }else
291 if( (rc = system(cmd)) != 0)
292 {
293 w_log(LL_ERR, "Calling error (rc=%d)", rc );
294 w_log(LL_ERR, "(cmd line: '%s')", cmd);
295 nfree(cmd);
296 w_log(LL_FUNC,"sendFile() failed");
297 return rc;
298 }
299
300 w_log(LL_FILESENT, "Sent '%s' to %s (%s)", filename, link.email,
301 snprintaddr(cmd, sstrlen(cmd), link.hisAka)
302 );
303
304 /* todo: save to confirmation */
305 if( debugflag && !SAVEFLAG )
306 w_log(LL_DEL, "(debug) Remove '%s'",filename);
307 else if (!SAVEFLAG)
308 delete(filename);
309 else
310 w_log(LL_DEL, "(Save flag is set) Keep '%s'",filename);
311
312 nfree(cmd);
313 w_log(LL_FUNC,"sendFile() OK");
314 return 0;
315 }
316
317
318 /* Process outbound netmail for link (.?ut): scan BSO & send ?ut for this link
319 */
processNet(s_link link)320 int processNet(s_link link)
321 { char adr[ADRS_MAX], *messagefile=NULL;
322 int lenvar=0, rc=0, RC=0, ch=0;
323 char flavorCharsUse[] = "ocid"; /* flavores for send netmail (hold not sent) */
324
325 w_log(LL_FUNC,"processNet()");
326 adr[0]=0;
327
328 if( (lenvar = strlen(link.pktFile)-3) <0 )
329 { w_log(LL_ERR, "Illegal pktFile for link %s (%s)",
330 snprintaddr(adr, sizeof(adr), link.hisAka), link.pktFile );
331 return 1;
332 }
333
334 for( ch=strlen(flavorCharsUse)-1; ch >=0; ch--)
335 {
336 link.pktFile[lenvar]=flavorCharsUse[ch];
337
338 if ( testfile(link.pktFile) )
339 continue;
340 w_log(LL_FILENAME, "pktFile '%s'", link.pktFile);
341
342 if( (messagefile=writeMessage(link.pktFile, link)) == NULL)
343 { w_log(LL_ERR, "Skip on compose error: '%s'", link.pktFile );
344 RC++;
345 continue;
346 }
347 if( (rc = sendFile(messagefile,link)) !=0 )
348 { w_log(LL_ERR, "Skip on send error: '%s'", link.pktFile );
349 RC++;
350 continue;
351 }
352 sent++;
353 w_log(LL_SENT, "Sent '%s' to %s (%s)\n", link.pktFile, link.email,
354 snprintaddr(messagefile, strlen(messagefile) ,link.hisAka)
355 );
356
357 if( debugflag )
358 w_log(LL_ERR, "(debug) Remove '%s'",link.floFile);
359 else if( (rc=delete(link.pktFile)) )
360 { w_log(LL_ERR, "File '%s' not removed: %s", link.pktFile, strerror(rc));
361 RC++;
362 }
363 else
364 w_log(LL_DEL, "Removed '%s'", link.pktFile);
365
366 }
367 w_log(LL_FUNC,"processNet() OK");
368 return rc;
369 }
370
371 /* Process outbound echomail for link (.?lo): scan outbound for ?lo, read its
372 * and send files listed in.
373 */
processFlo(s_link link)374 int processFlo(s_link link)
375 { FILE *flofd=NULL, *tempflofd=NULL;
376 char buf[PATH_MAX], filetosend[PATH_MAX], *messagefile=NULL;
377 char *tempfloname=NULL;
378 int ch=0, replacefloflag=0, delflag = 0, truncflag = 0, lenvar = 0, rc=0;
379 char flavorCharsUse[] = "fcid"; /* flavores for send echomail */
380
381 w_log(LL_FUNC,"processFlo()");
382
383 if( (lenvar = strlen(link.floFile)-3) <0 )
384 { w_log(LL_ERR, "Illegal floFile for link %s (%s)",
385 snprintaddr(buf, sizeof(buf), link.hisAka), link.floFile );
386 return 1;
387 }
388
389 /* scan directory for ?lo files */
390 for( ch=strlen(flavorCharsUse)-1; ch >=0; ch--)
391 {
392 link.floFile[lenvar]=flavorCharsUse[ch];
393
394 if( testfile(link.floFile) )
395 continue;
396
397 if( (flofd = fopen(link.floFile, "rt")) == NULL)
398 { w_log(LL_ERR, "Cannot open '%s': %s", link.floFile, strerror(errno));
399 continue;
400 }
401
402 if( NULL==(tempflofd = createTempFileIn(config->tempOutbound, TEMPFLOEXT, 't', &tempfloname)) )
403 { w_log(LL_ERR, "Can't create temporary .FLO file");
404 return 1;
405 }
406 w_log(LL_FILE,"Process '%s'",link.floFile);
407 replacefloflag=0;
408 /* read lines from flo file */
409 while (fgets(buf, sizeof(buf), flofd) != NULL)
410 { delflag = 0;
411 truncflag = 0;
412 if (buf[0] == '^')
413 {
414 delflag = 1;
415 strncpy(filetosend, buf+1, sizeof(filetosend));
416 if( strlen(filetosend)!=strlen(buf+1) )
417 { w_log(LL_ERR,"processFlo(): Too long filename '%s' in '%s', can't send", buf+1, link.floFile);
418 replacefloflag=1;
419 fprintf(tempflofd, "%s\r\n", buf);
420 continue;
421 }
422 }else if (buf[0] == '#')
423 {
424 truncflag = 1;
425 strncpy(filetosend, buf+1, sizeof(filetosend));
426 if( strlen(filetosend)!=strlen(buf+1) )
427 { w_log(LL_ERR,"processFlo(): Too long filename '%s' in '%s', can't send", buf+1, link.floFile);
428 replacefloflag=1;
429 fprintf(tempflofd, "%s\r\n", buf);
430 continue;
431 }
432 }else
433 { strncpy(filetosend, buf, sizeof(filetosend));
434 if( strlen(filetosend)!=strlen(buf) )
435 { w_log(LL_ERR,"processFlo(): Too long filename '%s' in '%s', can't send", buf, link.floFile);
436 replacefloflag=1;
437 fprintf(tempflofd, "%s\r\n", buf);
438 continue;
439 }
440 }
441
442 /* stripLeadingChars(filetosend,"\r\n");*/ /* remove the trailing \r & \n */
443 stripCRLF(filetosend);
444 if(strlen(filetosend)==0)
445 continue;
446
447 /* Next block: don't remove file from .flo if file not exist */
448 if( testfile(filetosend) )
449 { w_log(LL_FLO, "File not exist! '%s'",filetosend);
450 replacefloflag=1;
451 if(delflag) fprintf(tempflofd, "^");
452 else if(truncflag) fprintf(tempflofd, "#");
453 fprintf( tempflofd, "%s\r\n", filetosend );
454 continue;
455 }
456 w_log(LL_FILE, "Bundle '%s'", filetosend);
457
458 nfree(messagefile);
459 if( (messagefile=writeMessage(filetosend, link)) == NULL)
460 { w_log(LL_ERR, "Skip on compose error: '%s'", buf );
461 replacefloflag=1;
462 if(delflag) fprintf(tempflofd, "^");
463 else if(truncflag) fprintf(tempflofd, "#");
464 fprintf( tempflofd, "%s\r\n", filetosend );
465 continue;
466 }
467 if( (rc = sendFile(messagefile,link)) !=0 )
468 { w_log(LL_ERR, "Skip on send error: '%s'", buf );
469 nfree(messagefile);
470 replacefloflag=1;
471 if(delflag) fprintf(tempflofd, "^");
472 else if(truncflag) fprintf(tempflofd, "#");
473 fprintf( tempflofd, "%s\r\n", filetosend );
474 continue;
475 }
476 sent++;
477 w_log(LL_SENT, "Sent '%s' to %s (%s)\n", filetosend, link.email,
478 snprintaddr(messagefile, strlen(messagefile) ,link.hisAka)
479 );
480
481 if( debugflag && delflag )
482 w_log(LL_ERR, "(debug) Delete file: '%s'", filetosend);
483 else if( delflag )
484 {
485 if( (rc=delete(filetosend)) )
486 w_log(LL_ERR, "Can't remove file '%s': %s", filetosend, strerror(rc));
487 else
488 w_log(LL_DEL, "Removed '%s'", filetosend);
489 }
490 else if( debugflag && truncflag )
491 w_log(LL_ERR, "(debug) Truncate file: '%s'", filetosend);
492 else if( truncflag )
493 {
494 if( (rc=truncat(filetosend)) )
495 w_log(LL_ERR, "Can't truncate file '%s': %s", filetosend, strerror(errno));
496 else
497 w_log(LL_TRUNC, "Truncated '%s'", filetosend);
498 }
499
500 nfree(messagefile);
501 } /* while */
502 fclose(flofd);
503 fclose(tempflofd);
504 tempflofd=flofd=NULL;
505
506 if( debugflag ){
507 if( replacefloflag )
508 w_log(LL_DEL, "Replace '%s'",link.floFile);
509 else w_log(LL_ERR, "(debug) Remove '%s'",link.floFile);
510 }
511 else
512 { delete(link.floFile);
513 if(replacefloflag)
514 { w_log(LL_DEL, "Replace '%s'",link.floFile);
515 if( move_file(tempfloname, link.floFile, 1) )
516 w_log(LL_FILE, "Replaced '%s' with '%s'",link.floFile, tempfloname);
517 }else
518 delete( tempfloname );
519 }
520
521 }/*for*/
522 if(tempflofd)
523 { fclose(tempflofd);
524 delete(tempfloname);
525 }
526 nfree(tempfloname);
527 w_log(LL_FUNC, "processFlo() OK");
528 return 0;
529 }
530
531
532 /* Process outbound filebox for link (.?lo): scan & send all files
533 */
processBox(s_link link)534 int processBox(s_link link)
535 { DIR *boxP;
536 struct dirent * dp;
537 char path[PATH_MAX], adr[30], *messagefile;
538 unsigned pathlen=0;
539 int rc;
540
541 w_log(LL_FUNC,"processBox()");
542 w_log(LL_FILENAME, "Filebox: %s", link.fileBox);
543 snprintaddr(adr,sizeof(adr),link.hisAka);
544 if ( link.fileBox==NULL || (pathlen=strlen( link.fileBox ))==0 )
545 { w_log(LL_BOX, "Not defined filebox for %s", adr );
546 return 0;
547 }
548
549 if ( (boxP = opendir(link.fileBox))==NULL )
550 { w_log(LL_ERR, "Can't open filebox for %s: %s", adr, link.fileBox );
551 return 1;
552 }
553 w_log(LL_LINK, "Process filebox for %s (%s)", adr, link.fileBox );
554 strncpy( path, link.fileBox, sizeof(path) );
555 while( (dp = readdir(boxP)) != NULL ){
556 path[pathlen]=0;
557 #ifdef DT_REG
558 /* struct direntry have member d_type in *NIX */
559 if( dp->d_type != DT_REG)
560 { w_log(LL_FILE, "%s is not regular file", dp->d_name );
561 continue; /* Send only regular files! */
562 }
563 #endif
564 strncat(path,dp->d_name, sizeof(path));
565 if( testfile(path) )
566 continue;
567 w_log(LL_FILE, "Sending file %s to %s", path, adr);
568
569 if( (messagefile=writeMessage(path, link)) == NULL)
570 { w_log(LL_ERR, "Composing error: '%s', skip", path );
571 continue;
572 }
573 if( (rc = sendFile(messagefile,link)) !=0 )
574 { w_log(LL_ERR, "Sending error: '%s', skip", path );
575 continue;
576 }
577 sent++;
578 w_log(LL_SENT, "Sent %s to %s (%s)\n",
579 path, link.email, adr, link.hisAka
580 );
581
582 if( debugflag ){
583 w_log(LL_ERR, "(debug) Delete file: %s", path);
584 }else
585 if( (rc=delete(path)) )
586 w_log(LL_ERR, "File %s not removed: %s", path, strerror(rc));
587 }
588 (void)closedir(boxP);
589
590 w_log(LL_FUNC,"processBox() OK");
591 return 0;
592 }
593
594 /* Do send files.
595 *
596 */
send(void)597 int send(void)
598 { FILE *bsyfd;
599 int i, rc=0;
600 char adr[30];
601
602 w_log(LL_FUNC,"send()");
603 adr[0]=0;
604
605 for (i = 0; i < config->linkCount; i++)
606 {
607 if( config->links[i].email != NULL
608 && setOutboundFilenames( &(config->links[i]), normal )==0 )
609 {
610 sent=0;
611 snprintaddr(adr,sizeof(adr),config->links[i].hisAka);
612 w_log(LL_LINK, "Process link %s", adr);
613
614 if( (bsyfd = createbsy(config->links[i]))==NULL )
615 continue;
616 if( (rc += processNet(config->links[i])) )
617 {
618 w_log(LL_ERR,"Netmail send error.\n");
619 }
620 rc *= 10;
621 if( (rc = processFlo(config->links[i])) )
622 {
623 w_log(LL_ERR,"Echomail send error.\n");
624 }
625 rc *= 10;
626 if( (rc += processBox(config->links[i])) )
627 {
628 w_log(LL_ERR,"Filebox send error.\n");
629 }
630 fclose(bsyfd);
631 if(!delete(config->links[i].bsyFile))
632 w_log(LL_DEL, "Deleted bsy for %s", adr);
633 else
634 w_log(LL_ERR, "Can't delete bsy for %s: %s", adr, strerror(errno));
635
636 if( sent )
637 {
638 allsent += sent;
639 w_log(LL_INFO, "Sent %d files to %s", sent, adr );
640 }
641 else
642 w_log(LL_INFO, "Nothing to send for %s", adr );
643
644 }/*if*/
645 }/*for*/
646
647 w_log(LL_FUNC,"send() OK");
648 return rc;
649 }
650
651
652 void
printver()653 printver()
654 { fprintf( stderr, /* ITS4: ignore */
655 "%s - send FTN over email\n(part of the EmailPkt package, The Husky FidoSoft Project module) \n\n",
656 program_name );
657 }
658
659 void
usage()660 usage()
661 { printver();
662 fprintf( stderr, /* ITS4: ignore */
663 /* "Usage: %s [-qVD] [-c configfile]\n", program_name); */
664 "Usage: hesend [-qVD] [-c configfile]\n");
665 #ifndef __UNIX__
666 fprintf( stderr, /* ITS4: ignore */
667 /* "or: %s [--help] [--version] [--debug] [--quiet] [--config=configfile]\n", program_name);*/
668 "or: hesend [--help] [--version] [--debug] [--quiet] [--config=configfile]\n");
669 #endif
670 exit(-1);
671 }
672
673 int
main(int argc,char ** argv)674 main( int argc, char **argv)
675 { int rc=0, op=0, quiet=0;
676 char *cp=NULL;
677 #include "../h/cvsdate.h"
678
679 program_name = GenVersionStr( PROGRAMNAME, VER_MAJOR, VER_MINOR, VER_PATCH, VER_BRANCH, cvs_date );
680
681 #ifdef __UNIX__
682 opterr = 0;
683 while ((op = getopt(argc, argv, "DVc:d:hq")) != EOF)
684 switch (op) {
685 case 'c': /* config file */
686 cp=sstrdup(optarg);
687 case 'D': /* debug mode */
688 debugflag++;
689 break;
690 case 'q': /* quiet mode */
691 quiet=1;
692 break;
693 case 'V': /* version */
694 printver();
695 nfree(cp); nfree(program_name);
696 return 0;
697 case 'h': /* help */
698 default :
699 usage();
700 nfree(cp); nfree(program_name);
701 return 0;
702 }
703
704 #else
705 for( op=1; op<argc; op++ ){
706 if(argv[op][0]=='-'){
707 if(argv[op][1]=='-'){
708 if(strcmp(argv[op]+2,"quiet"))
709 quiet=0;
710 if(strcmp(argv[op]+2,"debug"))
711 debugflag++;
712 if( strstr(argv[op]+2,"config=")==(argv[op]+2) ) {
713 cp = strchr(argv[op], '=');
714 if( cp ) cp = sstrdup(++cp);
715 else fprintf(stderr, "Strange error: --config=... not contents '='");
716 }
717 if(strcmp(argv[op]+2,"version")) {
718 printver();
719 nfree(cp); nfree(program_name);
720 return 0;
721 }
722 if(strcmp(argv[op]+2,"help")) {
723 usage();
724 nfree(cp); nfree(program_name);
725 return 0;
726 }
727 }else{
728 if(strchr(argv[op],'q'))
729 quiet=0;
730 if(strchr(argv[op],'D'))
731 debugflag++;
732 if(strchr(argv[op],'c')) {
733 cp = sstrdup(argv[++op]); /* config-file */
734 }
735 if(strchr(argv[op],'V')) {
736 printver();
737 nfree(cp); nfree(program_name);
738 return 0;
739 }
740 if(strchr(argv[op],'h')) {
741 usage();
742 nfree(cp); nfree(program_name);
743 return 0;
744 }
745 }
746 }else{
747 fprintf(stderr,"Illegal parameter: %s", argv[op]);
748 nfree(cp); nfree(program_name);
749 return 1;
750 }
751 }
752 #endif
753
754 set_module_vars();
755 config = readConfig(cp);
756 nfree(cp);
757 if(quiet) config->logEchoToScreen=0;
758
759 if( !openLog( LOGFILE, program_name, config) )
760 fprintf(stderr, "Can't init log()! Use stderr instead.\n");
761
762 if( sstrlen(config->sendmailcmd) )
763 {
764 if( debugflag )
765 w_log(LL_PRG,"Start %s (debug%u mode)", program_name, debugflag);
766 else w_log(LL_PRG,"Start %s", program_name);
767
768 if (debugflag == 1)
769 { SAVEFLAG++;
770 debugflag = 0;
771 }
772 rc = send();
773 w_log(LL_SUMMARY, "Summary sent %d files", allsent);
774 }
775 else
776 w_log(LL_CRIT, "sendmailcmd not defined in config! Abort.");
777
778 disposeConfig(config);
779 w_log(LL_PRG,"Stop %s", program_name);
780 nfree(program_name);
781 closeLog();
782
783 return rc;
784 }
785