1 /*****************************************************************************
2  * HTICK --- FTN Ticker / Request Processor
3  *****************************************************************************
4  * Copyright (C) 1999 by
5  *
6  * Gabriel Plutzar
7  *
8  * Fido:     2:31/1
9  * Internet: gabriel@hit.priv.at
10  *
11  * Vienna, Austria, Europe
12  *
13  * This file is part of HTICK, which is based on HPT by Matthias Tichy,
14  * 2:2432/605.14 2:2433/1245, mtt@tichy.de
15  *
16  * HTICK is free software; you can redistribute it and/or modify it
17  * under the terms of the GNU General Public License as published by the
18  * Free Software Foundation; either version 2, or (at your option) any
19  * later version.
20  *
21  * HTICK is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with HTICK; see the file COPYING.  If not, write to the Free
28  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29  *****************************************************************************
30  * $Id$
31  *****************************************************************************/
32 
33 #include <time.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #include <stdio.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <huskylib/compiler.h>
43 
44 #ifdef HAS_UNISTD_H
45 # include <unistd.h>
46 #endif
47 
48 #ifdef HAS_DIRECT_H
49 # include <direct.h>
50 #endif
51 
52 #ifdef HAS_PROCESS_H
53 # include <process.h>
54 #endif
55 
56 #ifdef HAS_DIR_H
57 # include <dir.h>
58 #endif
59 
60 #include <huskylib/dirlayer.h>
61 #include <huskylib/xstr.h>
62 #include <huskylib/recode.h>
63 
64 #include <fidoconf/fidoconf.h>
65 #include <fidoconf/common.h>
66 
67 #include <areafix/areafix.h>
68 
69 #include <fcommon.h>
70 #include <global.h>
71 #include <toss.h>
72 #include <add_desc.h>
73 
74 #ifndef FALSE
75 # define FALSE 0
76 #endif
77 #ifndef TRUE
78 # define TRUE 1
79 #endif
80 
exit_htick(char * logstr,int print)81 void exit_htick( char *logstr, int print )
82 {
83 
84   w_log( LL_FUNC, "exit_htick()" );
85   if( logstr && *logstr )
86   {
87     w_log( LL_CRIT, logstr );
88     if( !config->logEchoToScreen && print )
89       fprintf( stderr, "%s\n", logstr );
90   }
91 
92   doneCharsets(  );
93   w_log( LL_STOP, "Exit" );
94   closeLog(  );
95   if( config->lockfile )
96   {
97     FreelockFile( config->lockfile, lock_fd );
98   }
99   disposeConfig( config );
100   exit( EX_SOFTWARE );
101 }
102 
fileNameAlreadyUsed(char * pktName,char * packName)103 int fileNameAlreadyUsed( char *pktName, char *packName )
104 {
105   unsigned int i;
106 
107   for( i = 0; i < config->linkCount; i++ )
108   {
109     if( ( config->links[i]->pktFile != NULL ) && ( pktName != NULL ) )
110       if( ( stricmp( pktName, config->links[i]->pktFile ) == 0 ) )
111         return 1;
112     if( ( config->links[i]->packFile != NULL ) && ( packName != NULL ) )
113       if( ( stricmp( packName, config->links[i]->packFile ) == 0 ) )
114         return 1;
115   }
116 
117   return 0;
118 }
119 
createOutboundFileNameAka(s_link * link,e_flavour prio,e_pollType typ,hs_addr * aka)120 int createOutboundFileNameAka( s_link * link, e_flavour prio, e_pollType typ, hs_addr * aka )
121 {
122   int nRet = NCreateOutboundFileNameAka( config, link, prio, typ, aka );
123 
124   if( nRet == -1 )
125     exit_htick( "cannot create *.bsy file!", 0 );
126   return nRet;
127 }
128 
createOutboundFileName(s_link * link,e_flavour prio,e_pollType typ)129 int createOutboundFileName( s_link * link, e_flavour prio, e_pollType typ )
130 {
131   return createOutboundFileNameAka( link, prio, typ, &( link->hisAka ) );
132 }
133 
removeFileMask(char * directory,char * mask)134 int removeFileMask( char *directory, char *mask )
135 {
136   husky_DIR *dir;
137   char *file;
138   char *removefile = NULL;
139   char *descr_file_name = NULL;
140   unsigned int numfiles = 0;
141 
142   if( ( directory == NULL ) || ( mask == NULL ) )
143   {
144     w_log( LL_CRIT, "Parameter is NULL: removeFileMask(%s,%s)",
145            directory ? "directory" : "NULL", mask ? "mask" : "NULL" );
146     return ( 0 );
147   }
148 
149   dir = husky_opendir( directory );
150   if( dir != NULL )
151   {
152     while( ( file = husky_readdir( dir ) ) != NULL )
153     {
154       if( stricmp( file, "." ) == 0 || stricmp( file, ".." ) == 0 )
155         continue;
156       if( patimat( file, mask ) == 1 )
157       {
158 
159         /* remove file */
160         xstrscat( &removefile, directory, file, NULL );
161         if( removefile )
162           remove( removefile );
163         w_log( '6', "Removed file: %s", removefile );
164         numfiles++;
165         nfree( removefile );
166 
167         /* remove description for file */
168         xstrscat( &descr_file_name, directory, config->fileDescription, NULL );
169         adaptcase( descr_file_name );
170         removeDesc( descr_file_name, file );
171         nfree( descr_file_name );
172       }
173     }
174     husky_closedir( dir );
175   }
176   return ( numfiles );
177 }
178 
179 #ifdef _WIN32_WINNT
180 # define _WINUSER_
181 # define _WINUSER_H
182 # 	ifdef __MINGW32__
183 # 		define CreateHardLink CreateHardLinkA
184 # 	endif
185 #endif
186 
link_file(const char * from,const char * to)187 int link_file( const char *from, const char *to )
188 {
189   int rc = FALSE;
190 
191 #if _WIN32_WINNT == 0x0400
192 
193   WCHAR FileLink[MAX_PATH + 1];
194   WCHAR wto[MAX_PATH + 1];
195   LPWSTR FilePart;
196 
197   HANDLE hFileSource;
198 
199   WIN32_STREAM_ID StreamId;
200   DWORD dwBytesWritten;
201   LPVOID lpContext;
202   DWORD cbPathLen;
203   DWORD StreamHeaderSize;
204 
205   BOOL bSuccess;
206 #endif
207 
208   /* Test parameters: prevent read from NULL[]  */
209   if( !from || !to )
210   {
211     if( !from )
212       w_log( LL_ERR, __FILE__ "::link_file(): source file name is NULL" );
213     if( !to )
214       w_log( LL_ERR, __FILE__ "::link_file(): destination file name is NULL" );
215     return FALSE;
216   }
217 
218 #if   _WIN32_WINNT >= 0x0500
219 
220   rc = CreateHardLink( to, from, NULL );
221 
222 #elif _WIN32_WINNT == 0x0400
223 
224   /*   */
225   /*  open existing file that we link to */
226   /*   */
227   hFileSource = CreateFile( from, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,  /*  sa */
228                             OPEN_EXISTING, 0, NULL );
229 
230   if( hFileSource == INVALID_HANDLE_VALUE )
231   {
232     return rc;
233   }
234 
235   /*   */
236   /*  validate and sanitize supplied link path and use the result */
237   /*  the full path MUST be Unicode for BackupWrite */
238   /*   */
239   MultiByteToWideChar( CP_ACP, 0, to, strlen( to ) + 1, wto, sizeof( wto ) / sizeof( wto[0] ) );
240 
241   cbPathLen = GetFullPathNameW( wto, MAX_PATH, FileLink, &FilePart );
242 
243   if( cbPathLen == 0 )
244   {
245     return rc;
246   }
247 
248   cbPathLen = ( cbPathLen + 1 ) * sizeof( WCHAR );      /*  adjust for byte count */
249 
250   /*   */
251   /*  it might also be a good idea to verify the existence of the link, */
252   /*  (and possibly bail), as the file specified in FileLink will be */
253   /*  overwritten if it already exists */
254   /*   */
255 
256   /*   */
257   /*  prepare and write the WIN32_STREAM_ID out */
258   /*   */
259   lpContext = NULL;
260 
261   StreamId.dwStreamId = BACKUP_LINK;
262   StreamId.dwStreamAttributes = 0;
263   StreamId.dwStreamNameSize = 0;
264   StreamId.Size.HighPart = 0;
265   StreamId.Size.LowPart = cbPathLen;
266 
267   /*   */
268   /*  compute length of variable size WIN32_STREAM_ID */
269   /*   */
270   StreamHeaderSize = ( LPBYTE ) & StreamId.cStreamName - ( LPBYTE ) &
271       StreamId + StreamId.dwStreamNameSize;
272 
273   bSuccess = BackupWrite( hFileSource, ( LPBYTE ) & StreamId,   /*  buffer to write */
274                           StreamHeaderSize,     /*  number of bytes to write */
275                           &dwBytesWritten, FALSE,       /*  don't abort yet */
276                           FALSE,        /*  don't process security */
277                           &lpContext );
278 
279   if( bSuccess )
280   {
281 
282     /*   */
283     /*  write out the buffer containing the path */
284     /*   */
285     bSuccess = BackupWrite( hFileSource, ( LPBYTE ) FileLink,   /*  buffer to write */
286                             cbPathLen,  /*  number of bytes to write */
287                             &dwBytesWritten, FALSE,     /*  don't abort yet */
288                             FALSE,      /*  don't process security */
289                             &lpContext );
290 
291     /*   */
292     /*  free context */
293     /*   */
294     BackupWrite( hFileSource, NULL,     /*  buffer to write */
295                  0,             /*  number of bytes to write */
296                  &dwBytesWritten, TRUE, /*  abort */
297                  FALSE,         /*  don't process security */
298                  &lpContext );
299   }
300 
301   CloseHandle( hFileSource );
302 
303   if( !bSuccess )
304   {
305     return rc;
306   }
307   return TRUE;
308 
309 #elif defined (_UNISTD_H) && !defined(__OS2__)
310 
311   rc = ( link( from, to ) == 0 );
312 
313 #endif
314   return rc;
315 }
316 
317 
IncBigSize(BigSize * bs,ULONG inc)318 void IncBigSize( BigSize * bs, ULONG inc )
319 {
320   UINT b, kb, mb, res;
321 
322   if( !bs )
323   {
324     w_log( LL_CRIT, __FILE__ "::IncBigSize(): 1st parameter is NULL" );
325     return;
326   }
327 
328   b = inc % 1024;
329   inc = inc / 1024;
330   kb = inc % 1024;
331   mb = inc / 1024;
332   /* check result: res = inc */
333   res = 1024 * 1024 * mb + 1024 * kb + b;
334 
335   bs->b += b;
336   if( bs->b >= 1024 )
337   {
338     bs->b -= 1024;
339     bs->kb++;
340   }
341   bs->kb += kb;
342   if( bs->kb >= 1024 )
343   {
344     bs->kb -= 1024;
345     bs->mb++;
346   }
347   bs->mb += mb;
348 }
349 
IncBigSize2(BigSize * bs,BigSize * inc)350 void IncBigSize2( BigSize * bs, BigSize * inc )
351 {
352   if( !bs || !inc )
353   {
354     w_log( LL_CRIT, __FILE__ "::IncBigSize2(): Parameter is NULL: IncBigSize2(%s,%s",
355            bs ? "bs" : "NULL", inc ? "inc" : "NULL" );
356     return;
357   }
358 
359   bs->b += inc->b;
360   if( bs->b >= 1024 )
361   {
362     bs->b -= 1024;
363     bs->kb++;
364   }
365   bs->kb += inc->kb;
366   if( bs->kb >= 1024 )
367   {
368     bs->kb -= 1024;
369     bs->mb++;
370   }
371   bs->mb += inc->mb;
372 }
373 
PrintBigSize(BigSize * bs)374 char *PrintBigSize( BigSize * bs )
375 {
376   static char out[50];
377 
378   *out = '\0';
379 
380   if( !bs )
381   {
382     w_log( LL_CRIT, __FILE__ "::PrintBigSize(): parameter is NULL" );
383     return out;
384   }
385 
386   if( bs->mb > 9 )
387   {
388     sprintf( out, "%d.%02dM", bs->mb, ( int )( bs->kb / 10.24 ) );
389 /*
390     } else if ( bs->kb > 100) {
391         sprintf(out,"%d.%02dK", bs->mb*1024 + bs->kb, (int)(bs->b/10.24));
392 */
393   }
394   else
395   {
396     sprintf( out, "%d", bs->mb * 1024 * 1024 + bs->kb * 1024 + bs->b );
397   }
398   return out;
399 }
400