1 /*****************************************************************************
2 * HTICK --- FTN Ticker / Request Processor
3 *****************************************************************************
4 * This file is part of HTICK, part of the Husky fidosoft project
5 * http://husky.physcip.uni-stuttgart.de
6 *
7 * HTICK is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * HTICK is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HTICK; see the file COPYING. If not, write to the Free
19 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 *****************************************************************************
21 * $Id$
22 *****************************************************************************/
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include <huskylib/compiler.h>
31
32 #ifdef HAS_PROCESS_H
33 # include <process.h>
34 #endif
35
36 #ifdef HAS_DOS_H
37 # include <dos.h>
38 #endif
39
40 #if HAS_UNISTD_H
41 # include <unistd.h>
42 #endif
43
44 #include <huskylib/huskylib.h>
45
46 #include <fidoconf/fidoconf.h>
47 #include <fidoconf/common.h>
48 #include <huskylib/recode.h>
49 #include <huskylib/xstr.h>
50 #include <huskylib/dirlayer.h>
51 #include <areafix/areafix.h> /* for print_ch() */
52
53 #ifdef USE_HPTZIP
54 # include <hptzip/hptzip.h>
55 #endif
56
57
58 #include <add_desc.h>
59 #include <global.h>
60 #include <toss.h>
61 #include <filecase.h>
62
63 /* Return:
64 * 0 if success
65 * 1 if error
66 * -1 if ivalid parameter
67 */
add_description(char * descr_file_name,char * file_name,char ** description,unsigned int count_desc)68 int add_description( char *descr_file_name, char *file_name, char **description,
69 unsigned int count_desc )
70 {
71 FILE *descr_file;
72 unsigned int i;
73 char *desc_line = NULL;
74 char *namefile = NULL;
75 int descOnNewLine = 0;
76
77 if( !descr_file_name || !file_name || !description )
78 {
79 w_log( LL_CRIT,
80 __FILE__
81 ":: Parameter is NULL: add_description(%s,%s,%s,count_desc). This is serious error in program, please report to developers.",
82 descr_file_name ? "descr_file_name" : "NULL", file_name ? "file_name" : "NULL",
83 description ? "description" : "NULL" );
84 return -1;
85 }
86 for( i = 0; i < count_desc; i++ )
87 {
88 if( !description[i] )
89 {
90 w_log( LL_CRIT,
91 __FILE__
92 "::add_description(...,description,%i) Array in parameter has NULL element: description[%i]. This is serious error in program, please report to developers.",
93 count_desc, i );
94 return -1;
95 }
96 }
97
98 descr_file = fopen( descr_file_name, "a" );
99 if( descr_file == NULL )
100 return 1;
101
102 namefile = sstrdup( file_name );
103
104 MakeProperCase( namefile );
105 xscatprintf( &desc_line, "%-12s", namefile );
106 /* fprintf (descr_file, "%-12s", namefile); */
107 if( config->addDLC && config->DLCDigits > 0 && config->DLCDigits < 10 )
108 {
109 char dlc[10];
110
111 dlc[0] = ' ';
112 dlc[1] = '[';
113 for( i = 1; i <= config->DLCDigits; i++ )
114 dlc[i + 1] = '0';
115 dlc[i + 1] = ']';
116 dlc[i + 2] = '\x00';
117 /* fprintf (descr_file, "%s", dlc); */
118 xstrcat( &desc_line, dlc );
119 }
120 if( ( strlen( namefile ) > 12 ) && ( strlen( desc_line ) + strlen( description[0] ) > 78 ) )
121 {
122 fprintf( descr_file, "%s\n", desc_line );
123 descOnNewLine = 1;
124 }
125 else
126 {
127 fprintf( descr_file, "%s", desc_line );
128 }
129 for( i = 0; i < count_desc; i++ )
130 {
131 desc_line = sstrdup( description[i] );
132 if( config->intab != NULL )
133 recodeToInternalCharset( desc_line );
134 if( descOnNewLine == 0 )
135 {
136 fprintf( descr_file, " %s\n", desc_line );
137 descOnNewLine = 1;
138 }
139 else
140 {
141 if( config->fileDescPos == 0 )
142 config->fileDescPos = 1;
143 fprintf( descr_file, "%s%s%s\n", print_ch( config->fileDescPos - 1, ' ' ),
144 ( config->fileLDescString == NULL ) ? " " : config->fileLDescString, desc_line );
145
146 }
147 nfree( desc_line );
148 }
149 if( count_desc == 0 )
150 fprintf( descr_file, "\n" );
151 fclose( descr_file );
152 nfree( namefile );
153 return 0;
154 }
155
156 /* Return:
157 * 0 if success
158 * 1 if error
159 * -1 if ivalid parameter
160 */
removeDesc(char * descr_file_name,char * file_name)161 int removeDesc( char *descr_file_name, char *file_name )
162 {
163 FILE *f1, *f2;
164 char *line, *tmp, *token, *descr_file_name_tmp, *LDescString;
165 int flag = 0;
166
167 if( !descr_file_name || !file_name )
168 {
169 w_log( LL_CRIT,
170 __FILE__
171 ":: Parameter is NULL: removeDesc(%s,%s). This is serious error in program, please report to developers.",
172 descr_file_name ? "descr_file_name" : "NULL", file_name ? "file_name" : "NULL" );
173 return -1;
174 }
175
176 line = tmp = token = descr_file_name_tmp = LDescString = NULL;
177 f1 = fopen( descr_file_name, "r" );
178 if( f1 == NULL )
179 return 1;
180
181 /* strcpy(descr_file_name_tmp,descr_file_name); */
182 /* strcat(descr_file_name_tmp,".tmp"); */
183
184 xstrscat( &descr_file_name_tmp, descr_file_name, ".tmp", NULL );
185
186 f2 = fopen( descr_file_name_tmp, "w" );
187 if( f2 == NULL )
188 {
189 fclose( f1 );
190 nfree( descr_file_name_tmp );
191 return 1;
192 }
193
194 if( config->fileLDescString == NULL )
195 LDescString = sstrdup( ">" );
196 else
197 LDescString = sstrdup( config->fileLDescString );
198
199 while( ( line = readLine( f1 ) ) != NULL )
200 {
201 if( *line == 0 || *line == 10 || *line == 13 )
202 continue;
203
204 if( line[strlen( line ) - 1] == '\r' )
205 line[strlen( line ) - 1] = 0;
206
207 if( flag && ( *line == '\t' || *line == ' ' || *line == *LDescString ) )
208 continue;
209 else
210 flag = 0;
211
212 tmp = sstrdup( line );
213 token = strtok( tmp, " \t\0" );
214
215 if( token != NULL )
216 {
217 if( stricmp( token, file_name ) != 0 )
218 {
219 fputs( line, f2 );
220 fputs( "\n", f2 );
221 }
222 else
223 flag = 1;
224 }
225 nfree( tmp );
226 nfree( line );
227 }
228
229 nfree( LDescString );
230 fclose( f1 );
231 fclose( f2 );
232 move_file( descr_file_name_tmp, descr_file_name, 1 ); /* overwrite old file */
233 nfree( descr_file_name_tmp );
234 return 0;
235 }
236
237 /* Return:
238 * 0 if success
239 * 1 if error
240 * -1 if ivalid parameter
241 */
announceNewFileecho(char * announcenewfileecho,char * c_area,char * hisaddr)242 int announceNewFileecho( char *announcenewfileecho, char *c_area, char *hisaddr )
243 {
244 FILE *ann_file;
245
246 if( !announcenewfileecho || !c_area || !hisaddr )
247 {
248 w_log( LL_CRIT,
249 __FILE__
250 ":: Parameter is NULL: announceNewFileecho(%s,%s,%s). This is serious error in program, please report to developers.",
251 announcenewfileecho ? "announcenewfileecho" : "NULL", c_area ? "c_area" : "NULL",
252 hisaddr ? "hisaddr" : "NULL" );
253 return -1;
254 }
255
256 if( !fexist( announcenewfileecho ) )
257 {
258 ann_file = fopen( announcenewfileecho, "w" );
259 if( ann_file == NULL )
260 return 1;
261 fprintf( ann_file, "Action Name By\n" );
262 fprintf( ann_file,
263 "-------------------------------------------------------------------------------\n" );
264 }
265 else
266 {
267 ann_file = fopen( announcenewfileecho, "a" );
268 if( ann_file == NULL )
269 return 1;
270 }
271 fprintf( ann_file, "Created %-52s %s\n", c_area, hisaddr );
272 fclose( ann_file );
273 return 0;
274 }
275
276 /* Return:
277 * 0 if success
278 * 1 if error
279 * -1 if ivalid parameter
280 */
GetDescFormBbsFile(char * descr_file_name,char * file_name,s_ticfile * tic)281 int GetDescFormBbsFile( char *descr_file_name, char *file_name, s_ticfile * tic )
282 {
283 FILE *filehandle;
284 char *line = NULL, *tmp = NULL, *token = NULL;
285 char *p = token;
286 int flag = 0, rc = 1;
287
288 if( !descr_file_name || !file_name || !tic )
289 {
290 w_log( LL_CRIT,
291 __FILE__
292 ":: Parameter is NULL: GetDescFormBbsFile(%s,%s,%s). This is serious error in program, please report to developers.",
293 descr_file_name ? "descr_file_name" : "NULL", file_name ? "file_name" : "NULL",
294 tic ? "tic" : "NULL" );
295 return -1;
296 }
297
298 filehandle = fopen( descr_file_name, "r+b" );
299 if( filehandle == NULL )
300 return 1;
301
302 while( ( line = readLine( filehandle ) ) != NULL )
303 {
304
305 if( flag && ( *line == '\t' || *line == ' ' || *line == '>' ) )
306 {
307 token = stripLeadingChars( line, " >" );
308 if( *token == '>' )
309 token++;
310 tic->desc = srealloc( tic->desc, ( tic->anzdesc + 1 ) * sizeof( *tic->desc ) );
311 tic->desc[tic->anzdesc] = sstrdup( token );
312 tic->anzdesc++;
313 nfree( line );
314 continue;
315 }
316 else
317 {
318 if( rc == 0 )
319 {
320 nfree( line );
321 break;
322 }
323 else
324 flag = 0;
325 }
326 tmp = sstrdup( line );
327 token = tmp;
328 p = token;
329 while( p && *p != '\0' && !isspace( *p ) )
330 p++;
331 if( p && *p != '\0' )
332 *p = '\0';
333 else
334 p = NULL;
335
336 if( stricmp( token, file_name ) == 0 )
337 {
338 UINT i;
339
340 if( p == NULL )
341 {
342 token = "";
343 }
344 else
345 {
346 p++;
347 while( p && *p != '\0' && isspace( *p ) )
348 p++;
349 if( p && *p != '\0' )
350 token = p;
351 else
352 token = "";
353 }
354 if( config->addDLC && config->DLCDigits > 0 && config->DLCDigits < 10 && token[0] == '[' )
355 {
356 while( ']' != *p )
357 p++;
358 p++;
359 while( p && !isspace( *p ) )
360 p++;
361 token = p;
362 }
363 for( i = 0; i < tic->anzdesc; i++ )
364 nfree( tic->desc[i] );
365 tic->anzdesc = 0;
366 tic->desc = srealloc( tic->desc, ( tic->anzdesc + 1 ) * sizeof( *tic->desc ) );
367 tic->desc[tic->anzdesc] = sstrdup( token );
368 tic->anzdesc++;
369 flag = 1;
370 rc = 0;
371 }
372 nfree( line );
373 nfree( tmp );
374 }
375
376 fclose( filehandle );
377 w_log( LL_FILE, "getDesc OK for file: %s", file_name );
378 return rc;
379 }
380
381 /* Return:
382 * 0 if description is not set
383 * 1 if description is set from specified file
384 * 3 if error opening file
385 * -1 if ivalid parameter
386 */
GetDescFormFile(char * fileName,s_ticfile * tic)387 int GetDescFormFile( char *fileName, s_ticfile * tic )
388 {
389 FILE *filehandle = NULL;
390 UINT i;
391 char *line = NULL;
392
393 if( !fileName || !tic )
394 {
395 w_log( LL_CRIT,
396 __FILE__
397 ":: Parameter is NULL: GetDescFormFile(%s,%s). This is serious error in program, please report to developers.",
398 fileName ? "fileName" : "NULL", tic ? "tic" : "NULL" );
399 return -1;
400 }
401
402 if( ( filehandle = fopen( fileName, "r" ) ) == NULL )
403 {
404 w_log( LL_ERROR, "Error at opening file \"%s\": %s", fileName, strerror( errno ) );
405 return 3;
406 };
407
408 for( i = 0; i < tic->anzldesc; i++ )
409 nfree( tic->ldesc[i] );
410 tic->anzldesc = 0;
411
412 while( ( line = readLine( filehandle ) ) != NULL )
413 {
414 tic->ldesc = srealloc( tic->ldesc, ( tic->anzldesc + 1 ) * sizeof( *tic->ldesc ) );
415 tic->ldesc[tic->anzldesc] = sstrdup( line );
416 tic->anzldesc++;
417 nfree( line );
418 } /* endwhile */
419 fclose( filehandle );
420 return tic->anzldesc ? 1 : 0;
421 }
422
423 /* Return:
424 * 1 if description is set from description file ("file_id.diz" from archive)
425 * 0 if description not set
426 * -1 if ivalid parameter
427 * 2 if error opening file
428 * 3 if unpacker not found for this file or all diz-files don't unpacked
429 */
GetDescFormDizFile(char * fileName,s_ticfile * tic)430 int GetDescFormDizFile( char *fileName, s_ticfile * tic )
431 {
432 FILE *filehandle = NULL;
433 char *dizfile = NULL;
434 int j, found;
435 UINT i, unpacker;
436 signed int cmdexit;
437 char cmd[256] = "";
438 char buffer[256] = "";
439
440 if( !fileName || !tic )
441 {
442 w_log( LL_CRIT,
443 __FILE__
444 ":: Parameter is NULL: GetDescFormFile(%s,%s). This is serious error in program, please report to developers.",
445 fileName ? "fileName" : "NULL", tic ? "tic" : "NULL" );
446 return -1;
447 }
448
449 /* find what unpacker to use */
450 for( i = 0, found = 0; ( i < config->unpackCount ) && !found; i++ )
451 {
452 filehandle = fopen( fileName, "rb" );
453 if( filehandle == NULL )
454 return 2;
455 /* is offset is negative we look at the end */
456 fseek( filehandle, config->unpack[i].offset,
457 config->unpack[i].offset >= 0 ? SEEK_SET : SEEK_END );
458 if( ferror( filehandle ) )
459 {
460 fclose( filehandle );
461 continue;
462 };
463 for( found = 1, j = 0; j < config->unpack[i].codeSize; j++ )
464 {
465 if( ( getc( filehandle ) & config->unpack[i].mask[j] ) != config->unpack[i].matchCode[j] )
466 found = 0;
467 }
468 fclose( filehandle );
469 }
470
471 if( found == 0 )
472 {
473 w_log( LL_ALERT, "file %s: cannot find unpacker", fileName );
474 return 3;
475 }
476 unpacker = i - 1;
477 getcwd( buffer, 256 );
478 /* unpack file_id.diz (config->fileDescName) */
479 for( i = 0; i < config->fDescNameCount; i++ )
480 {
481 fillCmdStatement( cmd, config->unpack[unpacker].call, fileName, config->fileDescNames[i],
482 config->tempInbound );
483 w_log( LL_EXEC, "File %s: unpacking with \"%s\"", fileName, cmd );
484 chdir( config->tempInbound );
485 if( fc_stristr( config->unpack[unpacker].call, ZIPINTERNAL ) )
486 {
487 #ifdef USE_HPTZIP
488 cmdexit = UnPackWithZlib( fileName, config->fileDescNames[i], config->tempInbound );
489 #else
490 cmdexit = 0;
491 w_log( LL_ERROR,
492 "\"%s\" don't implemented in this build (disabled at compile time). Please use your unzip program.",
493 ZIPINTERNAL );
494 continue;
495 #endif
496 }
497 else
498 {
499 cmdexit = cmdcall( cmd );
500 }
501
502 chdir( buffer );
503
504 if( cmdexit != 0 )
505 {
506 w_log( LL_ERROR, "exec failed, code %d", cmdexit );
507 continue;
508 }
509
510 xscatprintf( &dizfile, "%s%s", config->tempInbound, config->fileDescNames[i] );
511
512 if( fexist( dizfile ) )
513 found = GetDescFormFile( dizfile, tic );
514
515 if( found == 1 )
516 {
517 remove( dizfile );
518 i = config->fDescNameCount;
519 }
520 nfree( dizfile );
521 }
522 return found;
523 }
524