-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.3 2004/10/14 14:52:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.11 2006/02/07 11:19:02 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2006 */
/* See the file NOTICE for conditions of use and distribution. */
NULL, /* check_string (default changed for non-bsmtp file)*/
NULL, /* escape_string (ditto) */
NULL, /* file_format */
+ 0, /* quota_value */
+ 0, /* quota_warn_threshold_value */
-1, /* mailbox_size_value */
-1, /* mailbox_filecount_value */
- 0, /* quota_value */
0, /* quota_filecount_value */
- 0, /* quota_warn_threshold_value */
APPENDFILE_MODE, /* mode */
APPENDFILE_DIRECTORY_MODE, /* dirmode */
APPENDFILE_LOCKFILE_MODE, /* lockfile_mode */
appendfile_transport_options_block *ob =
(appendfile_transport_options_block *)(tblock->options_block);
uschar *q = ob->quota;
-int *v = &(ob->quota_value);
-int default_value = 0;
+double default_value = 0.0;
int i;
addrlist = addrlist; /* Keep picky compilers happy */
for (i = 0; i < 5; i++)
{
- if (q == NULL) *v = default_value; else
+ double d;
+
+ if (q == NULL) d = default_value; else
{
- double d;
uschar *rest;
uschar *s = expand_string(q);
d = Ustrtod(s, &rest);
- /* Handle following characters K, M, %, the latter being permitted
+ /* Handle following characters K, M, G, %, the latter being permitted
for quota_warn_threshold only. A threshold with no quota setting is
just ignored. */
if (tolower(*rest) == 'k') { d *= 1024.0; rest++; }
else if (tolower(*rest) == 'm') { d *= 1024.0*1024.0; rest++; }
+ else if (tolower(*rest) == 'g') { d *= 1024.0*1024.0*1024.0; rest++; }
else if (*rest == '%' && i == 2)
{
if (ob->quota_value <= 0 && !ob->maildir_use_size_file) d = 0;
"in %s transport", s, q, tblock->name);
return FAIL;
}
-
- *v = (int)d;
}
switch (i)
{
case 0:
+ ob->quota_value = (off_t)d;
q = ob->quota_filecount;
- v = &(ob->quota_filecount_value);
break;
case 1:
+ ob->quota_filecount_value = (int)d;
q = ob->quota_warn_threshold;
- v = &(ob->quota_warn_threshold_value);
break;
case 2:
+ ob->quota_warn_threshold_value = (off_t)d;
q = ob->mailbox_size_string;
- v = &(ob->mailbox_size_value);
- default_value = -1;
+ default_value = -1.0;
break;
case 3:
+ ob->mailbox_size_value = (off_t)d;
q = ob->mailbox_filecount_string;
- v = &(ob->mailbox_filecount_value);
+ break;
+
+ case 4:
+ ob->mailbox_filecount_value = (int)d;
break;
}
}
*/
static void
-notify_comsat(uschar *user, int offset)
+notify_comsat(uschar *user, off_t offset)
{
struct servent *sp;
host_item host;
DEBUG(D_transport) debug_printf("notify_comsat called\n");
-sprintf(CS buffer, "%.200s@%d\n", user, offset);
+sprintf(CS buffer, "%.200s@" OFF_T_FMT "\n", user, offset);
if ((sp = getservbyname("biff", "udp")) == NULL)
{
(void)ip_connect(sock, host_af, h->address, ntohs(sp->s_port), 0);
rc = send(sock, buffer, Ustrlen(buffer) + 1, 0);
- close(sock);
+ (void)close(sock);
if (rc >= 0) break;
DEBUG(D_transport)
zero if the directory cannot be opened
*/
-int
+off_t
check_dir_size(uschar *dirname, int *countptr, const pcre *regex)
{
DIR *dir;
-int sum = 0;
+off_t sum = 0;
int count = *countptr;
struct dirent *ent;
struct stat statbuf;
if (pcre_exec(regex, NULL, CS name, Ustrlen(name), 0, 0, ovector,6) >= 2)
{
uschar *endptr;
- int size = Ustrtol(name + ovector[2], &endptr, 10);
+ off_t size = (off_t)Ustrtod(name + ovector[2], &endptr);
if (endptr == name + ovector[3])
{
sum += size;
DEBUG(D_transport)
- debug_printf("check_dir_size: size from %s is %d\n", name, size);
+ debug_printf("check_dir_size: size from %s is " OFF_T_FMT "\n", name,
+ size);
continue;
}
}
closedir(dir);
DEBUG(D_transport)
- debug_printf("check_dir_size: dir=%s sum=%d count=%d\n", dirname, sum, count);
+ debug_printf("check_dir_size: dir=%s sum=" OFF_T_FMT " count=%d\n", dirname,
+ sum, count);
+
*countptr = count;
return sum;
}
#define MBX_NUSERFLAGS 30
static int
-copy_mbx_message(int to_fd, int from_fd, int saved_size)
+copy_mbx_message(int to_fd, int from_fd, off_t saved_size)
{
-int used, size;
+int used;
+off_t size;
struct stat statbuf;
/* If the current mailbox size is zero, write a header block */
if (fstat(from_fd, &statbuf) < 0) return DEFER;
size = statbuf.st_size;
-sprintf (CS deliver_out_buffer, "%s,%lu;%08lx%04x-%08x\015\012",
- tod_stamp(tod_mbx), (long unsigned int)size, 0L, 0, 0);
+sprintf (CS deliver_out_buffer, "%s," OFF_T_FMT ";%08lx%04x-%08x\015\012",
+ tod_stamp(tod_mbx), size, 0L, 0, 0);
used = Ustrlen(deliver_out_buffer);
/* Rewind the temporary file, and copy it over in chunks. */
gid_t gid = getegid();
int mbformat;
int mode = (addr->mode > 0)? addr->mode : ob->mode;
-int saved_size = -1;
-int mailbox_size = ob->mailbox_size_value;
+off_t saved_size = -1;
+off_t mailbox_size = ob->mailbox_size_value;
int mailbox_filecount = ob->mailbox_filecount_value;
int hd = -1;
int fd = -1;
DEBUG(D_transport)
{
- debug_printf("appendfile: mode=%o notify_comsat=%d quota=%d warning=%d%s\n"
+ debug_printf("appendfile: mode=%o notify_comsat=%d quota=" OFF_T_FMT
+ " warning=" OFF_T_FMT "%s\n"
" %s=%s format=%s\n message_prefix=%s\n message_suffix=%s\n "
"maildir_use_size_file=%s\n",
- mode, ob->notify_comsat, ob->quota_value, ob->quota_warn_threshold_value,
+ mode, ob->notify_comsat, ob->quota_value,
+ ob->quota_warn_threshold_value,
ob->quota_warn_threshold_is_percent? "%" : "",
isdirectory? "directory" : "file",
path, mailbox_formats[mbformat],
if (cfd >= 0)
{
transport_instance *tt = check_file_format(cfd, tblock, addr);
- close(cfd);
+ (void)close(cfd);
/* If another transport is indicated, call it and return; if no transport
was found, just return - the error data will have been set up.*/
sufficiently worried. */
if ((rc = Ulink(hitchname, lockname)) != 0) fstat(hd, &statbuf);
- close(hd);
+ (void)close(hd);
Uunlink(hitchname);
if (rc != 0 && statbuf.st_nlink != 2)
{
/* We have successfully created and opened the file. Ensure that the group
and the mode are correct. */
- Uchown(filename, uid, gid);
- Uchmod(filename, mode);
+ (void)Uchown(filename, uid, gid);
+ (void)Uchmod(filename, mode);
}
goto RETURN;
}
- Uchmod(mbx_lockname, 0600);
+ (void)Uchmod(mbx_lockname, 0600);
if (apply_lock(mbx_lockfd, F_WRLCK, ob->use_fcntl,
ob->lock_fcntl_timeout, ob->use_flock, ob->lock_flock_timeout) >= 0)
DEBUG(D_transport) debug_printf("failed to lock %s: %s\n", mbx_lockname,
strerror(errno));
- close(mbx_lockfd);
+ (void)close(mbx_lockfd);
mbx_lockfd = -1;
}
else
DEBUG(D_transport)
debug_printf("fcntl(), flock(), or MBX locking failed - retrying\n");
- close(fd);
+ (void)close(fd);
fd = -1;
use_lstat = TRUE; /* Reset to use lstat first */
/* if (???? || ob->quota_value > 0) */
{
- int size, filecount;
+ off_t size;
+ int filecount;
maildirsize_fd = maildir_ensure_sizefile(check_path, ob, regex, dir_regex,
&size, &filecount);
if ((mailbox_size < 0 || mailbox_filecount < 0) &&
(ob->quota_value > 0 || THRESHOLD_CHECK))
{
- int size;
+ off_t size;
int filecount = 0;
DEBUG(D_transport)
debug_printf("quota checks on directory %s\n", check_path);
/* Why are these here? Put in because they are present in the non-maildir
directory case above. */
- Uchown(filename, uid, gid);
- Uchmod(filename, mode);
+ (void)Uchown(filename, uid, gid);
+ (void)Uchmod(filename, mode);
}
#endif /* SUPPORT_MAILDIR */
/* Why are these here? Put in because they are present in the non-maildir
directory case above. */
- Uchown(filename, uid, gid);
- Uchmod(filename, mode);
+ (void)Uchown(filename, uid, gid);
+ (void)Uchmod(filename, mode);
/* Built a C stream from the open file descriptor. */
addr->transport_return = PANIC;
addr->message = string_sprintf("fdopen of %s ("
"for %s transport) failed", filename, tblock->name);
- close(fd);
+ (void)close(fd);
Uunlink(filename);
return FALSE;
}
addr->message = string_sprintf("Expansion of \"%s\" (mailstore "
"prefix for %s transport) failed: %s", ob->mailstore_prefix,
tblock->name, expand_string_message);
- fclose(env_file);
+ (void)fclose(env_file);
Uunlink(filename);
return FALSE;
}
addr->message = string_sprintf("Expansion of \"%s\" (mailstore "
"suffix for %s transport) failed: %s", ob->mailstore_suffix,
tblock->name, expand_string_message);
- fclose(env_file);
+ (void)fclose(env_file);
Uunlink(filename);
return FALSE;
}
Uunlink(filename);
return FALSE;
}
- Uchown(dataname, uid, gid);
- Uchmod(dataname, mode);
+ (void)Uchown(dataname, uid, gid);
+ (void)Uchmod(dataname, mode);
}
#endif /* SUPPORT_MAILSTORE */
/* In all cases of writing to a new file, ensure that the file which is
going to be renamed has the correct ownership and mode. */
- Uchown(filename, uid, gid);
- Uchmod(filename, mode);
+ (void)Uchown(filename, uid, gid);
+ (void)Uchmod(filename, mode);
}
{
DEBUG(D_transport)
{
- debug_printf("Exim quota = %d old size = %d this message = %d "
- "(%sincluded)\n", ob->quota_value, mailbox_size, message_size,
+ debug_printf("Exim quota = " OFF_T_FMT " old size = " OFF_T_FMT
+ " this message = %d (%sincluded)\n",
+ ob->quota_value, mailbox_size, message_size,
ob->quota_is_inclusive? "" : "not ");
debug_printf(" file count quota = %d count = %d\n",
ob->quota_filecount_value, mailbox_filecount);
/* Preserve errno while closing the temporary file. */
mbx_save_errno = errno;
- fclose(temp_file);
+ (void)fclose(temp_file);
errno = mbx_save_errno;
}
#endif /* SUPPORT_MBX */
maildir_record_length(maildirsize_fd, message_size);
maildir_save_errno = errno; /* Preserve errno while closing the file */
-close(maildirsize_fd);
+(void)close(maildirsize_fd);
errno = maildir_save_errno;
#endif /* SUPPORT_MAILDIR */
if (THRESHOLD_CHECK)
{
- int threshold = ob->quota_warn_threshold_value;
+ off_t threshold = ob->quota_warn_threshold_value;
if (ob->quota_warn_threshold_is_percent)
- threshold = (int)(((double)ob->quota_value * threshold) / 100);
+ threshold = (off_t)(((double)ob->quota_value * threshold) / 100);
DEBUG(D_transport)
- debug_printf("quota = %d threshold = %d old size = %d message size = %d\n",
- ob->quota_value, threshold, mailbox_size, message_size);
+ debug_printf("quota = " OFF_T_FMT
+ " threshold = " OFF_T_FMT
+ " old size = " OFF_T_FMT
+ " message size = %d\n",
+ ob->quota_value, threshold, mailbox_size,
+ message_size);
if (mailbox_size <= threshold && mailbox_size + message_size > threshold)
addr->special_action = SPECIAL_WARN;
from child_close() is in more_errno. */
else if (errno == ERRNO_FILTER_FAIL)
- {
+ {
yield = PANIC;
addr->message = string_sprintf("transport filter process failed (%d) "
"while writing to %s%s", addr->more_errno, dataname,
(addr->more_errno == EX_EXECFAILED)? ": unable to execute command" : "");
- }
+ }
/* Handle failure to expand header changes */
investigated so far have ftruncate(), whereas not all have the F_FREESP
fcntl() call (BSDI & FreeBSD do not). */
- if (!isdirectory) ftruncate(fd, saved_size);
+ if (!isdirectory) (void)ftruncate(fd, saved_size);
}
/* Handle successful writing - we want the modification time to be now for
debug_printf("unlinking MBX lock file %s\n", mbx_lockname);
Uunlink(mbx_lockname);
}
- close(mbx_lockfd);
+ (void)close(mbx_lockfd);
}
#endif /* SUPPORT_MBX */