1 /*:ts=8*/
2 /*****************************************************************************
3  * FIDOGATE --- Gateway UNIX Mail/News <-> FTN NetMail/EchoMail
4  *
5  *
6  * Hatch file into file area
7  *
8  *****************************************************************************
9  * Copyright (C) 1990-2002
10  *  _____ _____
11  * |     |___  |   Martin Junius             <mj@fidogate.org>
12  * | | | |   | |   Radiumstr. 18
13  * |_|_|_|@home|   D-51069 Koeln, Germany
14  *
15  * This file is part of FIDOGATE.
16  *
17  * FIDOGATE is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 2, or (at your option) any
20  * later version.
21  *
22  * FIDOGATE is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with FIDOGATE; see the file COPYING.  If not, write to the Free
29  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30  *****************************************************************************/
31 
32 #include "fidogate.h"
33 #include "getopt.h"
34 
35 #define PROGRAM		"ftnhatch"
36 #define CONFIG		DEFAULT_CONFIG_MAIN
37 
38 #define CREATOR		"by FIDOGATE/ftnhatch"
39 
40 #define MY_AREASBBS	"FAreasBBS"
41 #ifdef TIC_PASSWORD
42 #define MY_CONTEXT	"tic"
43 #else
44 #define MY_CONTEXT	"ff"
45 #endif                          /* TIC_PASSWORD */
46 
47 /*
48  * Prototypes
49  */
50 static mode_t tick_mode = 0600;
51 static char pass_path[MAXPATH];
52 
53 int hatch(char *, char *, char *, char *);
54 void short_usage(void);
55 void usage(void);
56 
57 /*
58  * Hatch file
59  */
hatch(char * area,char * file,char * desc,char * replaces)60 int hatch(char *area, char *file, char *desc, char *replaces)
61 {
62     char file_name[MAXPATH];
63     AreasBBS *bbs;
64     struct stat st;
65     unsigned long file_size, file_crc;
66     time_t file_time, now;
67     Tick tic;
68     Node node;
69     LNode *p;
70     int ret;
71 
72     /*
73      * Lookup area
74      */
75     if ((bbs = areasbbs_lookup(area)) == NULL) {
76         /* Unknown area: log it, dump it. ;-) */
77         fglog("ERROR: unknown area %s", area);
78         return EXIT_ERROR;
79     }
80     if (bbs->zone != -1)
81         cf_set_zone(bbs->zone);
82     if (bbs->addr.zone != -1)
83         cf_set_curr(&bbs->addr);
84 #ifdef BEST_AKA
85     else if (bbs->nodes.first)
86         cf_set_best(bbs->nodes.first->node.zone, bbs->nodes.first->node.net,
87                     bbs->nodes.first->node.node);
88 #endif                          /* BEST_AKA */
89     /*
90      * Make sure that file exists
91      */
92     BUF_COPY3(file_name, bbs->dir, "/", file);
93     if (stat(file_name, &st) == ERROR) {
94         fglog("$ERROR: can't stat() file %s", file_name);
95         return EXIT_ERROR;
96     }
97     file_size = st.st_size;
98     file_time = st.st_mtime;
99     file_crc = crc32_file(file_name);
100 
101     debug(4, "file: name=%s size=%ld time=%ld crc=%08lx",
102           file_name, file_size, (long)file_time, file_crc);
103 
104     /*
105      * Build Tick struct
106      */
107     tick_init(&tic);
108 
109     now = time(NULL);
110 
111     tic.origin = cf_n_addr();
112     tic.from = cf_n_addr();
113     /* tic.to set by hatch_one() */
114     tic.area = area;
115     tic.file = file;
116     tic.replaces = replaces;
117     tl_append(&tic.desc, xlat_s(desc, NULL));
118     tic.crc = file_crc;
119     tic.created = CREATOR;
120     tic.size = file_size;
121     tl_appendf(&tic.path, "%s %ld %s",
122                znf1(cf_addr()), (long)now, date(NULL, &now));
123     lon_add(&tic.seenby, cf_addr());
124     lon_join(&tic.seenby, &bbs->nodes);
125     /* tic.pw set by hatch_one() */
126     tic.date = file_time;
127 
128     /*
129      * Send to all nodes
130      */
131     ret = EXIT_OK;
132     for (p = bbs->nodes.first; p; p = p->next) {
133         if (lon_search(&(bbs->passive), &(p->node)))
134             continue;
135         node = p->node;
136         if (cf_addr()->zone == node.zone && cf_addr()->net == node.net &&
137             cf_addr()->node == node.node && cf_addr()->point == node.point)
138             continue;
139         debug(4, "sending to %s", znfp1(&node));
140 #ifndef FECHO_PASSTHROUGHT
141         if (tick_send(&tic, &node, file_name, tick_mode) == ERROR)
142 #else
143         if (tick_send(&tic, &node, file_name, 0, tick_mode, pass_path) == ERROR)
144 #endif                          /* FECHO_PASSTHROUGHT */
145             ret = EXIT_ERROR;
146     }
147 
148     return ret;
149 }
150 
151 /*
152  * Usage messages
153  */
short_usage(void)154 void short_usage(void)
155 {
156     fprintf(stderr, "usage: %s [-options] AREA FILE \"DESCRIPTION\"\n",
157             PROGRAM);
158     fprintf(stderr, "       %s --help  for more information\n", PROGRAM);
159     exit(EX_USAGE);
160 }
161 
usage(void)162 void usage(void)
163 {
164     fprintf(stderr, "FIDOGATE %s  %s %s\n\n",
165             version_global(), PROGRAM, version_local(VERSION));
166 
167     fprintf(stderr, "usage:   %s [-options] AREA FILE \"DESCRIPTION\"\n\n",
168             PROGRAM);
169     fprintf(stderr, "\
170 options: -b --fareas-bbs NAME         use alternate FAREAS.BBS\n\
171          -r --replaces FILES          add Replaces entry\n\
172 \n\
173          -v --verbose                 more verbose\n\
174 	 -h --help                    this help\n\
175          -c --config name             read config file (\"\" = none)\n\
176 	 -a --addr Z:N/F.P            set FTN address\n\
177 	 -u --uplink-addr Z:N/F.P     set FTN uplink address\n");
178 
179     exit(0);
180 }
181 
main(int argc,char ** argv)182 int main(int argc, char **argv)
183 {
184     char *areas_bbs = NULL;
185     char *r_flag = NULL;
186     int c;
187     char *c_flag = NULL;
188     char *a_flag = NULL, *u_flag = NULL;
189     int ret;
190     char *area, *file, *desc, *p;
191     char *cs_out = NULL, *cs_in = NULL;
192 
193     int option_index;
194     static struct option long_options[] = {
195         {"fareas-bbs", 1, 0, 'b'},
196         {"replaces", 1, 0, 'r'},
197 
198         {"verbose", 0, 0, 'v'}, /* More verbose */
199         {"help", 0, 0, 'h'},    /* Help */
200         {"config", 1, 0, 'c'},  /* Config file */
201         {"addr", 1, 0, 'a'},    /* Set FIDO address */
202         {"uplink-addr", 1, 0, 'u'}, /* Set FIDO uplink address */
203         {0, 0, 0, 0}
204     };
205 
206     log_program(PROGRAM);
207 
208     /* Init configuration */
209     cf_initialize();
210 
211     while ((c = getopt_long(argc, argv, "b:r:vhc:a:u:",
212                             long_options, &option_index)) != EOF)
213         switch (c) {
214         /***** ftnhatch options *****/
215         case 'b':
216             areas_bbs = optarg;
217             break;
218         case 'r':
219             r_flag = optarg;
220             break;
221 
222         /***** Common options *****/
223         case 'v':
224             verbose++;
225             break;
226         case 'h':
227             usage();
228             exit(0);
229             break;
230         case 'c':
231             c_flag = optarg;
232             break;
233         case 'a':
234             a_flag = optarg;
235             break;
236         case 'u':
237             u_flag = optarg;
238             break;
239         default:
240             short_usage();
241             exit(EX_USAGE);
242             break;
243         }
244 
245     /*
246      * Read config file
247      */
248     cf_read_config_file(c_flag ? c_flag : CONFIG);
249 
250     /*
251      * Process config options
252      */
253     if (a_flag)
254         cf_set_addr(a_flag);
255     if (u_flag)
256         cf_set_uplink(u_flag);
257 
258     cf_debug();
259 
260     routing_init(cf_p_routing());   /* SNP:FIXME: add `-r' command-line option? */
261 
262     /*
263      * Command line parameters
264      */
265     if (argc - optind != 3)
266         short_usage();
267     area = argv[optind++];
268     file = argv[optind++];
269     desc = argv[optind++];
270 
271     /*
272      * Get name of fareas.bbs file from config file
273      */
274     if (areas_bbs == NULL)
275         areas_bbs = cf_get_string(MY_AREASBBS, TRUE);
276 
277     if (areas_bbs == NULL) {
278         fprintf(stderr, "%s: no areas.bbs specified\n", PROGRAM);
279         exit_free();
280         exit(EX_USAGE);
281     }
282 
283     if ((p = cf_get_string("TickMode", TRUE))) {
284         tick_mode = atooct(p) & 0777;
285     } else {
286         tick_mode = PACKET_MODE;
287     }
288 #if defined(USE_FILEBOX) || defined (FECHO_PASSTHROUGHT)
289     if ((p = cf_get_string("PassthroughtBoxesDir", TRUE))) {
290         BUF_EXPAND(pass_path, p);
291     }
292 #endif                          /* USE_FILEBOX || FECHO_PASSTHROUGHT */
293     if ((p = cf_get_string("DefaultCharset", TRUE))) {
294         cs_out = xstrtok(p, ":");
295         xstrtok(NULL, ":");
296         cs_in = xstrtok(NULL, ":");
297         charset_init();
298         charset_set_in_out(cs_in, cs_out);
299     }
300 
301     /* Read PASSWD */
302     passwd_init();
303     /* Read FAreas.BBS */
304     if (areasbbs_init(areas_bbs) == ERROR) {
305         fglog("$ERROR: can't open %s", areas_bbs);
306         ret = EX_OSFILE;
307     }
308 
309     /* Hatch it! */
310     ret = hatch(area, file, desc, r_flag);
311     tmps_freeall();
312 
313     exit_free();
314     exit(ret);
315 }
316