void qmgr_move(const char *src_queue, const char *dst_queue, time_t time_stamp) { const char *myname = "qmgr_move"; SCAN_DIR *queue_dir; char *queue_id; struct utimbuf tbuf; const char *path; if (strcmp(src_queue, dst_queue) == 0) msg_panic("%s: source queue %s is destination", myname, src_queue); if (msg_verbose) msg_info("start move queue %s -> %s", src_queue, dst_queue); queue_dir = scan_dir_open(src_queue); while ((queue_id = mail_scan_dir_next(queue_dir)) != 0) { if (mail_queue_id_ok(queue_id)) { if (time_stamp > 0) { tbuf.actime = tbuf.modtime = time_stamp; path = mail_queue_path((VSTRING *) 0, src_queue, queue_id); if (utime(path, &tbuf) < 0) { if (errno != ENOENT) msg_fatal("%s: update %s time stamps: %m", myname, path); msg_warn("%s: update %s time stamps: %m", myname, path); continue; } } if (mail_queue_rename(queue_id, src_queue, dst_queue)) { if (errno != ENOENT) msg_fatal("%s: rename %s from %s to %s: %m", myname, queue_id, src_queue, dst_queue); msg_warn("%s: rename %s from %s to %s: %m", myname, queue_id, src_queue, dst_queue); continue; } if (msg_verbose) msg_info("%s: moved %s from %s to %s", myname, queue_id, src_queue, dst_queue); } else { msg_warn("%s: ignored: queue %s id %s", myname, src_queue, queue_id); } } scan_dir_close(queue_dir); if (msg_verbose) msg_info("end move queue %s -> %s", src_queue, dst_queue); }
static void pickup_service(char *unused_buf, ssize_t unused_len, char *unused_service, char **argv) { SCAN_DIR *scan; char *queue_name; PICKUP_INFO info; const char *path; char *id; int file_count; /* * Sanity check. This service takes no command-line arguments. */ if (argv[0]) msg_fatal("unexpected command-line argument: %s", argv[0]); /* * Skip over things that we don't want to open, such as files that are * still being written, or garbage. Leave it up to the sysadmin to remove * garbage. Keep scanning the queue directory until we stop removing * files from it. * * When we find a file, stroke the watchdog so that it will not bark while * some application is keeping us busy by injecting lots of mail into the * maildrop directory. */ queue_name = MAIL_QUEUE_MAILDROP; /* XXX should be a list */ do { file_count = 0; scan = scan_dir_open(queue_name); while ((id = scan_dir_next(scan)) != 0) { if (mail_open_ok(queue_name, id, &info.st, &path) == MAIL_OPEN_YES) { pickup_init(&info); info.path = mystrdup(path); watchdog_pat(); if (pickup_file(&info) == REMOVE_MESSAGE_FILE) { if (REMOVE(info.path)) msg_warn("remove %s: %m", info.path); else file_count++; } pickup_free(&info); } } scan_dir_close(scan); } while (file_count); }
static int flush_refresh_service(int max_age) { const char *myname = "flush_refresh_service"; SCAN_DIR *scan; char *site_path; struct stat st; VSTRING *path = vstring_alloc(10); scan = scan_dir_open(MAIL_QUEUE_FLUSH); while ((site_path = mail_scan_dir_next(scan)) != 0) { if (!mail_queue_id_ok(site_path)) continue; /* XXX grumble. */ mail_queue_path(path, MAIL_QUEUE_FLUSH, site_path); if (stat(STR(path), &st) < 0) { if (errno != ENOENT) msg_warn("%s: stat %s: %m", myname, STR(path)); else if (msg_verbose) msg_info("%s: %s: %m", myname, STR(path)); continue; } if (st.st_size == 0) { if (st.st_mtime + var_fflush_purge < event_time()) { if (unlink(STR(path)) < 0) msg_warn("remove logfile %s: %m", STR(path)); else if (msg_verbose) msg_info("%s: unlink %s, empty and unchanged for %d days", myname, STR(path), var_fflush_purge / 86400); } else if (msg_verbose) msg_info("%s: skip logfile %s - empty log", myname, site_path); } else if (st.st_atime + max_age < event_time()) { if (msg_verbose) msg_info("%s: flush logfile %s", myname, site_path); flush_send_path(site_path, REFRESH_ONLY); } else { if (msg_verbose) msg_info("%s: skip logfile %s, unread for <%d hours(s) ", myname, site_path, max_age / 3600); } } scan_dir_close(scan); vstring_free(path); return (FLUSH_STAT_OK); }
char *qmgr_scan_next(QMGR_SCAN *scan_info) { char *path = 0; /* * Restart the scan if we reach the end and a queue scan request has * arrived in the mean time. */ if (scan_info->handle && (path = mail_scan_dir_next(scan_info->handle)) == 0) { scan_info->handle = scan_dir_close(scan_info->handle); if (msg_verbose && (scan_info->nflags & QMGR_SCAN_START) == 0) msg_info("done %s queue scan", scan_info->queue); } if (!scan_info->handle && (scan_info->nflags & QMGR_SCAN_START)) { qmgr_scan_start(scan_info); path = mail_scan_dir_next(scan_info->handle); } return (path); }