1 /* spooler.c -- MH style mailer to write to /usr/spool/mail/<user>
3 * Mlocal, P=/etc/spooler, F=lsDFSmn, S=10, R=20, A=spooler $u
7 #define FLOCK /* uses flock() if defined, lockf() otherwise. */
10 #include <sys/types.h>
16 #define SPOOLDIR "/usr/spool/mail"
18 char *delim = "\1\1\1\1\n";
19 char *ME = "/etc/spooler";
28 register int rc, anyerrs;
31 if( *++argv == NULL ) {
32 fprintf( stderr, "%s: no recipients.\n", ME );
36 if( argc == 2 ) { /* single recipient, don't need tmp copy */
38 rc = localmail( *argv );
41 if(( rc = copyfile( tmpfile )) == 0 ) { /* sets fp_in */
42 for( anyerrs = 0; *argv; argv++ ) {
44 if(( rc = localmail( *argv )))
61 register int count, n;
62 register char buf[BUFSIZ];
63 register char mailbox[BUFSIZ];
64 register struct stat sb;
66 sprintf( mailbox, "%s/%s", SPOOLDIR, user );
68 if( stat( mailbox, &sb ) == -1 ) {
69 if( create_mbox( mailbox, user ))
73 if(( fp = mboxopen( mailbox )) == 0 )
75 fwrite( delim, sizeof(char), strlen(delim), fp );
76 while(( count = fread( buf, sizeof(char), BUFSIZ, fp_in))) {
77 n = fwrite( buf, sizeof(char), count, fp );
79 fprintf( stderr, "%s write error: %d read, %d written\n",
85 fwrite( delim, sizeof(char), strlen(delim), fp );
92 create_mbox( mbox, user )
93 register char *mbox, *user;
96 register struct passwd *pw;
98 if(( fd = creat( mbox, 0600 )) == -1 )
100 if(( pw = getpwnam( user )) != NULL ) {
101 fchown( fd, pw->pw_uid, pw->pw_gid );
111 register char *mailbox;
116 if(( fp = fopen( mailbox, "a" )) == NULL ) {
117 fprintf( stderr, "%s: Can't open %s for appending\n", ME, mailbox );
121 /* lock the mailbox */
123 #define NLOCKTRYS 20 /* almost a 2 min. wait should be enough even */
124 /* after a long vacation */
126 for( i = 0; i < NLOCKTRYS; i++ ) {
128 if( flock( fileno(fp), LOCK_EX | LOCK_NB ) == 0) /* got it ok */
130 if( lockf( fileno(fp), F_TLOCK, 0) == 0 )
133 /* fprintf(stderr, "can't lock, sleeping 5 sec...\n"); */
137 * If lockf worked perfectly (ie, rpc.lockd didn't die) this would be
141 if( i == NLOCKTRYS ) {
142 fprintf( stderr, "%s: Can't lock %s\n", ME, mailbox);
156 /*todo: unlockit. --not really necessary */
163 * collect stdin to a tmp file
166 register char *tmpfile;
169 register int pid, count, n;
170 register char buf[BUFSIZ];
176 sprintf( tmpfile, "/tmp/spooler.%05d", pid );
177 if( stat( tmpfile, &sb ) == -1 ) /* ok, this file doesn't exist */
182 if(( fp = fopen( tmpfile, "w" )) == NULL ) {
183 fprintf( stderr, "%s: Can't open %s\n", ME, tmpfile );
187 while(( count = fread( buf, sizeof(char), BUFSIZ, stdin ))) {
188 n = fwrite( buf, sizeof(char), count, fp );
190 fprintf( stderr, "%s: copyfile, write error: %d read, %d written\n",
197 fp_in = freopen( tmpfile, "r", fp );
198 if( fp_in == NULL ) {
199 fprintf( stderr, "%s: freopen on %s failed\n", ME, tmpfile );