1/* 2 * Copyright (c) 1996, Gary J. Palmer 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer, 11 * verbatim and that no modifications are made prior to this 12 * point in the file. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 *
| 1/* 2 * Copyright (c) 1996, Gary J. Palmer 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer, 11 * verbatim and that no modifications are made prior to this 12 * point in the file. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 *
|
29 * $Id: ctm_dequeue.c,v 1.1 1996/07/01 20:53:55 gpalmer Exp $
| 29 * $Id: ctm_dequeue.c,v 1.2 1996/07/12 13:12:46 gpalmer Exp $
|
30 */ 31 32/* 33 * Change this if you want to alter how many files it sends out by 34 * default 35 */ 36 37#define DEFAULT_NUM 2 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43#include <fcntl.h> 44#include <sys/types.h> 45#include <sys/stat.h> 46#include <fts.h> 47#include <sys/mman.h> 48#include <errno.h> 49#include <paths.h> 50#include "error.h" 51#include "options.h" 52 53int fts_sort(const FTSENT **, const FTSENT **); 54FILE *open_sendmail(void); 55int close_sendmail(FILE *fp); 56 57int 58main(int argc, char **argv) 59{ 60 char *log_file = NULL; 61 char *queue_dir = NULL; 62 char *list[2]; 63 char *buffer, *filename; 64 int num_to_send = DEFAULT_NUM, piece, fp, len; 65 FTS *fts; 66 FTSENT *ftsent; 67 FILE *sfp; 68 69 err_prog_name(argv[0]); 70 71 OPTIONS("[-l log] [-n num] queuedir") 72 NUMBER('n', num_to_send) 73 STRING('l', log_file) 74 ENDOPTS; 75 76 if (argc != 2) 77 usage(); 78 79 queue_dir = argv[1]; 80 list[0] = queue_dir; 81 list[1] = NULL; 82 83 fts = fts_open(list, FTS_PHYSICAL, fts_sort); 84 if (fts == NULL) 85 { 86 err("fts failed on `%s'", queue_dir); 87 exit(1); 88 } 89 90 (void) fts_read(fts); 91 92 ftsent = fts_children(fts, 0); 93 if (ftsent == NULL) 94 { 95 err("ftschildren failed"); 96 exit(1); 97 } 98 99 /* assumption :-( */ 100 len = strlen(queue_dir) + 40; 101 filename = malloc(len); 102 if (filename == NULL) 103 { 104 err("malloc failed"); 105 exit(1); 106 } 107 108 for (piece = 0; piece < num_to_send ; piece++) 109 { 110 /* Skip non-files and files we should ignore (ones starting with `.') */ 111 112#define ISFILE ((ftsent->fts_info & FTS_F) == FTS_F) 113#define IGNORE (ftsent->fts_name[0] == '.') 114#define HASNEXT (ftsent->fts_link != NULL) 115 116 while(((!ISFILE) || (IGNORE)) && (HASNEXT)) 117 ftsent = ftsent->fts_link; 118 119 if ((!ISFILE) || (IGNORE)) 120 { 121 err("No more chunks to mail"); 122 exit(0); 123 } 124 125#undef ISFILE 126#undef IGNORE 127#undef HASNEXT 128 129 if (snprintf(filename, len, "%s/%s", queue_dir, ftsent->fts_name) > len) 130 err("snprintf(filename) longer than buffer"); 131 132 fp = open(filename, O_RDONLY, 0); 133 if (fp < 0) 134 { 135 err("open(`%s') failed, errno = %d", filename, errno); 136 exit(1); 137 } 138 139 buffer = mmap(0, ftsent->fts_statp->st_size, PROT_READ, MAP_PRIVATE, fp, 0); 140 if (((int) buffer) <= 0) 141 { 142 err("mmap failed, errno = %d", errno); 143 exit(1); 144 } 145 146 sfp = open_sendmail(); 147 if (sfp == NULL) 148 exit(1); 149 150 if (fwrite(buffer, ftsent->fts_statp->st_size, 1, sfp) < 1) 151 { 152 err("fwrite failed: errno = %d", errno); 153 close_sendmail(sfp); 154 exit(1); 155 } 156 157 if (!close_sendmail(sfp)) 158 exit(1); 159 160 munmap(buffer, ftsent->fts_statp->st_size); 161 close(fp); 162 163 if (unlink(filename) < 0) 164 { 165 err("unlink of `%s' failed", filename); 166 exit(1); 167 } 168 169 err("sent file `%s'", ftsent->fts_name); 170 171 if (ftsent->fts_link != NULL) 172 ftsent = ftsent->fts_link; 173 else 174 break; 175 } 176 177 err("exiting normally"); 178 return(0); 179} 180 181int 182fts_sort(const FTSENT ** a, const FTSENT ** b) 183{ 184 int a_info, b_info; 185 186 a_info = (*a)->fts_info; 187 if (a_info == FTS_ERR) 188 return (0); 189 b_info = (*b)->fts_info; 190 if (b_info == FTS_ERR) 191 return (0); 192 193 return (strcmp((*a)->fts_name, (*b)->fts_name)); 194} 195 196/* 197 * Start a pipe to sendmail. Sendmail will decode the destination 198 * from the message contents. 199 */ 200FILE * 201open_sendmail() 202{ 203 FILE *fp; 204 char buf[100]; 205
| 30 */ 31 32/* 33 * Change this if you want to alter how many files it sends out by 34 * default 35 */ 36 37#define DEFAULT_NUM 2 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43#include <fcntl.h> 44#include <sys/types.h> 45#include <sys/stat.h> 46#include <fts.h> 47#include <sys/mman.h> 48#include <errno.h> 49#include <paths.h> 50#include "error.h" 51#include "options.h" 52 53int fts_sort(const FTSENT **, const FTSENT **); 54FILE *open_sendmail(void); 55int close_sendmail(FILE *fp); 56 57int 58main(int argc, char **argv) 59{ 60 char *log_file = NULL; 61 char *queue_dir = NULL; 62 char *list[2]; 63 char *buffer, *filename; 64 int num_to_send = DEFAULT_NUM, piece, fp, len; 65 FTS *fts; 66 FTSENT *ftsent; 67 FILE *sfp; 68 69 err_prog_name(argv[0]); 70 71 OPTIONS("[-l log] [-n num] queuedir") 72 NUMBER('n', num_to_send) 73 STRING('l', log_file) 74 ENDOPTS; 75 76 if (argc != 2) 77 usage(); 78 79 queue_dir = argv[1]; 80 list[0] = queue_dir; 81 list[1] = NULL; 82 83 fts = fts_open(list, FTS_PHYSICAL, fts_sort); 84 if (fts == NULL) 85 { 86 err("fts failed on `%s'", queue_dir); 87 exit(1); 88 } 89 90 (void) fts_read(fts); 91 92 ftsent = fts_children(fts, 0); 93 if (ftsent == NULL) 94 { 95 err("ftschildren failed"); 96 exit(1); 97 } 98 99 /* assumption :-( */ 100 len = strlen(queue_dir) + 40; 101 filename = malloc(len); 102 if (filename == NULL) 103 { 104 err("malloc failed"); 105 exit(1); 106 } 107 108 for (piece = 0; piece < num_to_send ; piece++) 109 { 110 /* Skip non-files and files we should ignore (ones starting with `.') */ 111 112#define ISFILE ((ftsent->fts_info & FTS_F) == FTS_F) 113#define IGNORE (ftsent->fts_name[0] == '.') 114#define HASNEXT (ftsent->fts_link != NULL) 115 116 while(((!ISFILE) || (IGNORE)) && (HASNEXT)) 117 ftsent = ftsent->fts_link; 118 119 if ((!ISFILE) || (IGNORE)) 120 { 121 err("No more chunks to mail"); 122 exit(0); 123 } 124 125#undef ISFILE 126#undef IGNORE 127#undef HASNEXT 128 129 if (snprintf(filename, len, "%s/%s", queue_dir, ftsent->fts_name) > len) 130 err("snprintf(filename) longer than buffer"); 131 132 fp = open(filename, O_RDONLY, 0); 133 if (fp < 0) 134 { 135 err("open(`%s') failed, errno = %d", filename, errno); 136 exit(1); 137 } 138 139 buffer = mmap(0, ftsent->fts_statp->st_size, PROT_READ, MAP_PRIVATE, fp, 0); 140 if (((int) buffer) <= 0) 141 { 142 err("mmap failed, errno = %d", errno); 143 exit(1); 144 } 145 146 sfp = open_sendmail(); 147 if (sfp == NULL) 148 exit(1); 149 150 if (fwrite(buffer, ftsent->fts_statp->st_size, 1, sfp) < 1) 151 { 152 err("fwrite failed: errno = %d", errno); 153 close_sendmail(sfp); 154 exit(1); 155 } 156 157 if (!close_sendmail(sfp)) 158 exit(1); 159 160 munmap(buffer, ftsent->fts_statp->st_size); 161 close(fp); 162 163 if (unlink(filename) < 0) 164 { 165 err("unlink of `%s' failed", filename); 166 exit(1); 167 } 168 169 err("sent file `%s'", ftsent->fts_name); 170 171 if (ftsent->fts_link != NULL) 172 ftsent = ftsent->fts_link; 173 else 174 break; 175 } 176 177 err("exiting normally"); 178 return(0); 179} 180 181int 182fts_sort(const FTSENT ** a, const FTSENT ** b) 183{ 184 int a_info, b_info; 185 186 a_info = (*a)->fts_info; 187 if (a_info == FTS_ERR) 188 return (0); 189 b_info = (*b)->fts_info; 190 if (b_info == FTS_ERR) 191 return (0); 192 193 return (strcmp((*a)->fts_name, (*b)->fts_name)); 194} 195 196/* 197 * Start a pipe to sendmail. Sendmail will decode the destination 198 * from the message contents. 199 */ 200FILE * 201open_sendmail() 202{ 203 FILE *fp; 204 char buf[100]; 205
|
206 sprintf(buf, "%s -t", _PATH_SENDMAIL);
| 206 sprintf(buf, "%s -odq -t", _PATH_SENDMAIL);
|
207 if ((fp = popen(buf, "w")) == NULL) 208 err("cannot start sendmail"); 209 return fp; 210} 211 212 213/* 214 * Close a pipe to sendmail. Sendmail will then do its bit. 215 * Return 1 on success, 0 on failure. 216 */ 217int 218close_sendmail(FILE *fp) 219{ 220 int status; 221 222 fflush(fp); 223 if (ferror(fp)) 224 { 225 err("error writing to sendmail"); 226 return 0; 227 } 228 229 if ((status = pclose(fp)) != 0) 230 err("sendmail failed with status %d", status); 231 232 return (status == 0); 233}
| 207 if ((fp = popen(buf, "w")) == NULL) 208 err("cannot start sendmail"); 209 return fp; 210} 211 212 213/* 214 * Close a pipe to sendmail. Sendmail will then do its bit. 215 * Return 1 on success, 0 on failure. 216 */ 217int 218close_sendmail(FILE *fp) 219{ 220 int status; 221 222 fflush(fp); 223 if (ferror(fp)) 224 { 225 err("error writing to sendmail"); 226 return 0; 227 } 228 229 if ((status = pclose(fp)) != 0) 230 err("sendmail failed with status %d", status); 231 232 return (status == 0); 233}
|