diff -urNb qpopper4.0.5/popper/main.c qpopper4.0.5_pidfile/popper/main.c --- qpopper4.0.5/popper/main.c Fri Mar 21 15:09:14 2003 +++ qpopper4.0.5_pidfile/popper/main.c Fri Mar 21 14:47:17 2003 @@ -141,6 +141,14 @@ # define SERV_TCP_PORT 110 #endif /* _DEBUG */ +#ifndef PIDFILEDIR +# define PIDFILEDIR "/var/run" +#endif + +#ifndef PIDFILE +# define PIDFILE "pid" +#endif + #define BAD_ADDR ( (unsigned long) -1 ) /* @@ -170,6 +178,7 @@ int hupit ( SIGPARAM ); int cleanup ( SIGPARAM ); void roll_it ( void ); +void pid_rewrite(char *, char *); void motherforker ( int newsockfd, int sockfd ); @@ -188,6 +197,8 @@ char msg_buf [ 2048 ] = ""; FILE *msg_out = NULL; FILE *err_out = NULL; +char pid_name[ 128 ] = ""; +FILE *pid_file = NULL; /* @@ -325,7 +336,7 @@ /* * See if debug or trace options specified */ - i = getopt ( Qargc, Qargv, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:" ); + i = getopt ( Qargc, Qargv, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:z:" ); while ( i != EOF ) { switch ( i ) @@ -345,11 +356,24 @@ trace_name, fileno(trace_file) ); break; + case 'z': + pid_rewrite(pid_name,optarg); + if ( strcmp(pid_name,"") != 0) + { + pid_file = fopen ( pid_name, "w" ); + if ( pid_file == NULL ) + err_dump ( HERE, "Unable to open pid file \"%s\"", pid_name); + TRACE ( trace_file, POP_DEBUG, HERE, + "Opened pid file \"%s\" as %d", + pid_name, fileno(pid_file) ); + } + break; + default: break; } - i = getopt ( Qargc, Qargv, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:" ); + i = getopt ( Qargc, Qargv, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:z:" ); } optind = 1; /* reset for pop_init */ @@ -451,7 +475,15 @@ TRACE ( trace_file, POP_DEBUG, HERE, "closing file descs %d to 0", sysconf ( _SC_OPEN_MAX ) ); for ( i = sysconf ( _SC_OPEN_MAX ); i >= 0; i-- ) { - if ( debug == FALSE || trace_file == NULL || i != fileno(trace_file) ) + if ( debug == TRUE ) + if ( trace_file != NULL ) + if ( i == fileno(trace_file) ) + continue; + + if ( pid_file != NULL ) + if ( i == fileno(pid_file) ) + continue; + close ( i ); } @@ -537,6 +569,18 @@ inet_ntoa ( serv_addr.sin_addr ), ntohs ( serv_addr.sin_port ) ); + /* + * Store our PID into a file, like a good unix daemon. + * We do this late in the game as we don't wish to overwrite that file + * if we cannot bind to a port. + */ + if ( pid_file != NULL ) + { + fprintf(pid_file, "%i", getpid()); + fclose(pid_file); + } + + TRACE ( trace_file, POP_DEBUG, HERE, "listening using socket fd %d", sockfd ); listen ( sockfd, 5 ); @@ -581,6 +625,12 @@ fclose ( trace_file ); trace_file = NULL; } + if ( pid_file != NULL ) + { + fclose ( pid_file ); + pid_file = NULL; + /* unlink ( pid_name ); -- don't, after chdir(/) may be bad */ + } exit ( 0 ); } @@ -720,6 +770,12 @@ fclose ( trace_file ); trace_file = NULL; } + if ( pid_file != NULL ) + { + fclose ( pid_file ); + pid_file = NULL; + /* unlink ( pid_name ); -- don't, after chdir(/) may be bad */ + } fflush ( err_out ); @@ -884,6 +940,58 @@ trace_name, fileno(trace_file) ); } + +/* + * Interprets what the user wants when placing a PID file. + */ +void pid_rewrite(char *result, char *file_guess) +{ + struct stat filestat; + int error = 0; + + strcpy(result,""); + + if (stat(file_guess,&filestat) == 0) /* if it exists... */ + { + if (S_ISDIR(filestat.st_mode)) + { /* a directory means that we must supply the filename */ + strncpy(result,file_guess,122); + strcat(result,"/"); + if (strstr(file_guess,pname) == NULL) + { + strncat(result,pname,127-(strlen(file_guess)-4) ); + strcat(result,".pid"); + } + else + strcat(result,PIDFILE); + } + else if (S_ISREG(filestat.st_mode)) + strcpy(result,file_guess); + else /* goofy destinations like /dev/null */ + error = 1; + } else { + if (errno == ENOENT) /* does not exist, create it */ + { + if (strchr(file_guess,'/') == NULL) /* just a file, needs a dir */ + { + strcpy(result,PIDFILEDIR); + strcat(result,"/"); + strncat(result,file_guess,126-strlen(PIDFILEDIR)); + } + else + strncpy(result,file_guess,127); + } + else + error = 1; + } + + + TRACE ( trace_file, POP_DEBUG, HERE, + "User wants to use PID file: \"%s\" Rewriting to: \"%s\"", + file_guess, result); + if (error) + TRACE ( trace_file, POP_DEBUG, HERE, + "ERROR, non-normal entity: \"%s\" ignoring option", file_guess); } diff -urNb qpopper4.0.5/popper/pop_init.c qpopper4.0.5_pidfile/popper/pop_init.c --- qpopper4.0.5/popper/pop_init.c Fri Mar 21 15:09:14 2003 +++ qpopper4.0.5_pidfile/popper/pop_init.c Fri Mar 21 14:47:17 2003 @@ -694,7 +694,7 @@ /* * Process command line arguments */ - while ( ( c = getopt ( argcount, argmessage, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:") ) != EOF ) + while ( ( c = getopt ( argcount, argmessage, "b:BcCdD:e:f:FkK:l:L:p:RsSt:T:uUvy:z:") ) != EOF ) switch ( c ) { case 'b': /* Bulletins requested */ @@ -922,6 +922,9 @@ errflag++; } + case 'z': /* PID file (handled in main.c) -- DO NOT USE */ + break; + default: /* Unknown option received */ errflag++; } @@ -993,6 +996,7 @@ "[-u] " "[-U] " "[-v] " + "[-z PID file] " "\n", argmessage[0], xB, /* -B (or not) */