2
* inbound.c -- inbound handling
4
* inbound.c is a part of binkd project
6
* Copyright (C) 1996-1997 Dima Maloff, 5047/13
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version. See COPYING.
15
* $Id: inbound.c,v 2.1 2001/04/23 07:58:57 gul Exp $
18
* Revision 2.1 2001/04/23 07:58:57 gul
19
* getfree() on large drives fixed
21
* Revision 2.0 2001/01/10 12:12:38 gul
22
* Binkd is under CVS again
24
* Revision 1.10 1997/10/23 04:03:07 mff
27
* Revision 1.9 1997/05/17 08:42:35 mff
28
* Added realname param to inb_test()
30
* Revision 1.8 1997/03/15 05:08:17 mff
31
* utime() replaced with touch()
33
* Revision 1.7 1997/03/09 07:19:37 mff
34
* Fixed bugs with `#' in filenames and incorrect killing of
37
* Revision 1.6 1997/02/13 07:08:39 mff
38
* Support for fileboxes
40
* Revision 1.5 1997/02/07 07:03:16 mff
49
#include <sys/types.h>
61
/* Removes both xxxxx.hr and it's xxxxx.dt */
62
static void remove_hr (char *path)
66
strcpy (strrchr (path, '.'), ".dt");
68
strcpy (strrchr (path, '.'), ".hr");
75
static int creat_tmp_name (char *s, char *file, off_t size,
76
time_t time, FTN_ADDR *from, char *inbound)
81
char node[FTN_ADDR_SZ + 1];
83
strnzcpy (s, inbound, MAXPATHLEN);
84
strnzcat (s, PATH_SEPARATOR, MAXPATHLEN);
88
sprintf (tmp, "%08lx.hr", rnd ());
89
strnzcat (s, tmp, MAXPATHLEN);
90
if (create_empty_sem_file (s))
92
if ((f = fopen (s, "w")) == 0)
94
Log (1, "%s: %s", s, strerror (errno));
97
ftnaddress_to_str (node, from);
98
fprintf (f, "%s %li %li %s\n",
99
file, (long int) size, (long int) time, node);
108
static int to_be_deleted (char *tmp_name, char *netname)
112
strcpy (strrchr (tmp_name, '.'), ".dt");
113
if (stat (tmp_name, &sb) == 0 && kill_old_partial_files != 0 &&
114
time (0) - sb.st_mtime > kill_old_partial_files)
116
Log (4, "found old .dt/.hr files for %s", netname);
119
strcpy (strrchr (tmp_name, '.'), ".hr");
124
* Searches for the ``file'' in the inbound and returns it's tmp name in s.
125
* S must have MAXPATHLEN chars. Returns 0 on error, 1=found, 2=created.
127
int find_tmp_name (char *s, char *file, off_t size,
128
time_t time, FTN_ADDR *from, int nfa, char *inbound)
130
char buf[MAXPATHLEN + 80];
138
inbound = temp_inbound;
140
if ((dp = opendir (inbound)) == 0)
142
Log (1, "cannot opendir %s: %s", inbound, strerror (errno));
146
strnzcpy (s, inbound, MAXPATHLEN);
147
strnzcat (s, PATH_SEPARATOR, MAXPATHLEN);
149
while ((de = readdir (dp)) != 0)
151
for (i = 0; i < 8; ++i)
152
if (!isxdigit (de->d_name[i]))
154
if (i < 8 || STRICMP (de->d_name + 8, ".hr"))
156
strnzcat (s, de->d_name, MAXPATHLEN);
157
if ((f = fopen (s, "r")) == 0 || !fgets (buf, sizeof (buf), f))
159
Log (1, "find_tmp_name: %s: %s", de->d_name, strerror (errno));
170
for (i = 0; i < 4; ++i)
171
w[i] = getwordx (buf, i + 1, GWX_NOESC);
173
if (!strcmp (w[0], file) && parse_ftnaddress (w[3], &fa))
175
for (i = 0; i < nfa; i++)
176
if (!ftnaddress_cmp (&fa, from + i))
178
if (size == (off_t) atol (w[1]) &&
179
(time & ~1) == (atol (w[2]) & ~1) &&
184
else if (kill_dup_partial_files && i < nfa)
186
Log (4, "dup partial file (%s):", w[0]);
190
else if (to_be_deleted (s, w[0]))
195
for (i = 0; i < 4; ++i)
209
Log (5, "file not found, trying to create a tmpname");
210
if (creat_tmp_name (s, file, size, time, from, inbound))
216
/* Replacing .hr with .dt */
217
strcpy (strrchr (s, '.'), ".dt");
221
FILE *inb_fopen (char *netname, off_t size,
222
time_t time, FTN_ADDR *from, int nfa, char *inbound)
224
char buf[MAXPATHLEN + 1];
228
if (!find_tmp_name (buf, netname, size, time, from, nfa, inbound))
231
if ((f = fopen (buf, "ab")) == 0)
232
Log (1, "%s: %s", buf, strerror (errno));
233
fseek (f, 0, SEEK_END); /* Work-around MSVC bug */
236
DosSetFHState(fileno(f), OPEN_FLAGS_NOINHERIT);
238
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
241
/* Checking for free space */
242
if (fstat (fileno (f), &sb) == 0)
244
/* Free space req-d (Kbytes) */
245
int req_free = (strcmp (inbound, inbound_nonsecure) ?
246
minfree : minfree_nonsecure);
249
getfree (inbound) < (unsigned long)((size - sb.st_size + 1023) / 1024 + req_free))
251
Log (1, "no enough free space in %s (%liK, req-d %liK)",
253
(long) getfree (inbound),
254
(long) (size - sb.st_size + 1023) / 1024 + req_free);
260
Log (1, "%s: fstat: %s", netname, strerror (errno));
265
int inb_reject (char *netname, off_t size,
266
time_t time, FTN_ADDR *from, int nfa, char *inbound)
268
char tmp_name[MAXPATHLEN + 1];
270
if (find_tmp_name (tmp_name, netname, size, time, from, nfa, inbound) != 1)
272
Log (1, "missing tmp file for %s!", netname);
277
Log (2, "rejecting %s", netname);
278
/* Replacing .dt with .hr and removing temp. file */
279
strcpy (strrchr (tmp_name, '.'), ".hr");
280
remove_hr (tmp_name);
286
* File is complete, rename it to it's realname. 1=ok, 0=failed.
287
* Sets realname[MAXPATHLEN]
289
int inb_done (char *netname, off_t size, time_t time,
290
FTN_ADDR *from, int nfa, char *inbound, char *real_name)
292
char tmp_name[MAXPATHLEN + 1];
297
if (find_tmp_name (tmp_name, netname, size, time, from, nfa, inbound) != 1)
299
Log (1, "missing tmp file for %s!", netname);
303
strnzcpy (real_name, inbound, MAXPATHLEN);
304
strnzcat (real_name, PATH_SEPARATOR, MAXPATHLEN);
305
s = real_name + strlen (real_name);
306
strnzcat (real_name, u = strdequote (netname), MAXPATHLEN);
309
s = real_name + strlen (real_name) - 1;
311
/* gul: for *.pkt and *.?ic (tic, zic etc.) change name but not extension */
312
/* ditto for arcmail -- mff */
313
if (ispkt (netname) || istic (netname) || isarcmail (netname))
316
if (touch (tmp_name, time) != 0)
317
Log (1, "touch %s: %s", tmp_name, strerror (errno));
321
if (!RENAME (tmp_name, real_name))
323
Log (2, "%s -> %s", netname, real_name);
328
if (errno != EEXIST && errno != EACCES && errno != EAGAIN)
330
Log (1, "cannot rename %s to it's realname: %s! (data stored in %s)",
331
netname, strerror (errno), tmp_name);
335
Log (2, "error renaming `%s' to `%s': %s",
336
netname, real_name, strerror (errno));
339
if (isalpha (*s) && toupper (*s) != 'Z')
341
else if (isdigit (*s) && toupper (*s) != '9')
345
else if (*--s == '.' || *s == '\\' || *s == '/')
347
Log (1, "cannot rename %s to it's realname! (data stored in %s)",
354
/* Replacing .dt with .hr and removing temp. file */
355
strcpy (strrchr (tmp_name, '.'), ".hr");
361
* Checks if the file already exists in our inbound. !0=ok, 0=failed.
362
* Sets realname[MAXPATHLEN]
364
int inb_test (char *filename, off_t size, time_t t,
365
char *inbound, char fp[])
370
strnzcpy (fp, inbound, MAXPATHLEN);
371
strnzcat (fp, PATH_SEPARATOR, MAXPATHLEN);
372
s = fp + strlen (fp);
373
strnzcat (fp, u = strdequote (filename), MAXPATHLEN);
377
return stat (fp, &sb) == 0 && sb.st_size == size &&
378
(sb.st_mtime & ~1) == (t & ~1);