* Module : sigfile.c * Author : M. Gleason & I. Lea * Created : 1992-10-17 * Updated : 2013-11-21 * Notes : Generate random signature for posting/mailing etc. * * Copyright (c) 1992-2014 Mike Gleason * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TIN_H # include "tin.h" #endif /* !TIN_H */ #define MAXLOOPS 1000 #define CURRENTDIR "." static char sigfile[PATH_LEN]; static FILE *open_random_sig(char *sigdir); static int thrashdir(char *sigdir); void msg_write_signature( FILE *fp, t_bool include_dot_signature, struct t_group *thisgroup) { FILE *fixfp; FILE *sigfp; char cwd[PATH_LEN]; char path[PATH_LEN]; char pathfixed[PATH_LEN]; #ifdef NNTP_INEWS if (read_news_via_nntp && 0 == strcasecmp(tinrc.inews_prog, INTERNAL_CMD )) include_dot_signature = TRUE; #endif /* NNTP_INEWS */ if (thisgroup && !thisgroup->bogus) { if (!strcmp(thisgroup->attribute->sigfile, "--none")) return; /* TODO: handle DONT_HAVE_PIPING case */ #ifndef DONT_HAVE_PIPING if (thisgroup->attribute->sigfile[0] == '!') { FILE *pipe_fp; char *sigcmd; char cmd[PATH_LEN]; fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SI GDASHES : "\n"); sigcmd = my_malloc(strlen(thisgroup->attribute->sigfile + 1) + strlen(thisgroup->name) + 4); sprintf(sigcmd, "%s \"%s\"", thisgroup->attribute->sigfi le + 1, thisgroup->name); if ((pipe_fp = popen(sigcmd, "r")) != NULL) { while (fgets(cmd, PATH_LEN, pipe_fp)) fputs(cmd, fp); pclose(pipe_fp); } /* else issue an error-message? */ free(sigcmd); return; } #endif /* !DONT_HAVE_PIPING */ get_cwd(cwd); if (!strfpath(thisgroup->attribute->sigfile, path, sizeof(path), thisgroup, FALSE)) { if (!strfpath(tinrc.sigfile, path, sizeof(path), thisgro up, FALSE)) joinpath(path, sizeof(path), homedir, ".Sig"); } /* * Check to see if sigfile is a directory & if it is * generate a random signature from sigs in sigdir. If * the file path/.sigfixed or ~/.sigfixed exists (fixed * part of random sig) then read it in first and append * the random sig part onto the end. */ if ((sigfp = open_random_sig(path)) != NULL) { #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "USING random sig=[%s]", sigfil e); #endif /* DEBUG */ fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SI GDASHES : "\n"); joinpath(pathfixed, sizeof(pathfixed), path, ".sigfixed" ); #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "TRYING fixed sig=[%s]", pathfi xed); #endif /* DEBUG */ if ((fixfp = fopen(pathfixed, "r")) != NULL) { copy_fp(fixfp, fp); fclose(fixfp); } else { joinpath(pathfixed, sizeof(pathfixed), homedir, ".sigfixed"); #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "TRYING fixed sig=[%s]" , pathfixed); #endif /* DEBUG */ if ((fixfp = fopen(pathfixed, "r")) != NULL) { copy_fp(fixfp, fp); fclose(fixfp); } } copy_fp(sigfp, fp); fclose(sigfp); chdir(cwd); return; } if ((sigfp = fopen(path, "r")) != NULL) { fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SI GDASHES : "\n"); copy_fp(sigfp, fp); fclose(sigfp); return; } /* * Use ~/.signature as a last resort, but only if mailing or * using internal inews (external inews appends it automagically ). */ if ((sigfp = fopen(default_signature, "r")) != NULL) { if (include_dot_signature) { fprintf(fp, "\n%s", thisgroup->attribute->sigdas hes ? SIGDASHES : "\n"); copy_fp(sigfp, fp); } fclose(sigfp); } } } static FILE * open_random_sig( char *sigdir) { srand((unsigned int) time(NULL)); if (chdir(sigdir) == 0) { if (thrashdir(sigdir) || !*sigfile) { #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "NO sigfile=[%s]", sigfile); #endif /* DEBUG */ return (FILE *) 0; } else { #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "sigfile=[%s]", sigfile); #endif /* DEBUG */ return fopen(sigfile, "r"); } } return (FILE *) 0; } static int thrashdir( char *sigdir) { DIR *dirp; DIR_BUF *dp; char *cwd; int safeguard, recurse; int c = 0, numentries = 0, pick; struct stat st; sigfile[0] = '\0'; if ((dirp = opendir(CURRENTDIR)) == NULL) return 1; while (readdir(dirp) != NULL) numentries++; /* * consider "." and ".." non-entries * consider all entries starting with "." non-entries */ if (numentries < 3) { CLOSEDIR(dirp); return -1; } cwd = my_malloc(PATH_LEN); get_cwd(cwd); recurse = strcmp(cwd, sigdir); /* * If we are using the root sig directory, we don't want * to recurse, or else we might use a custom sig intended * for a specific newsgroup (and not this one). */ for (safeguard = 0, dp = NULL; safeguard < MAXLOOPS && dp == NULL; safeg uard++) { #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "sig loop=[%d] recurse=[%d]", safeguard , recurse); #endif /* DEBUG */ #ifdef HAVE_REWINDDIR rewinddir(dirp); #else CLOSEDIR(dirp); if ((dirp = opendir(CURRENTDIR)) == NULL) { free(cwd); return 1; } #endif /* HAVE_REWINDDIR */ pick = rand() % numentries + 1; while (--pick >= 0) { if ((dp = readdir(dirp)) == NULL) break; } if (dp != NULL) { /* if we could open the dir entry */ if (!strcmp(dp->d_name, CURRENTDIR) || (dp->d_name[0] == '.')) dp = NULL; else { /* if we have a non-dot entry */ if (stat(dp->d_name, &st) == -1) { CLOSEDIR(dirp); free(cwd); return 1; } if (S_ISDIR(st.st_mode)) { if (recurse) { /* * do subdirectories */ if ((chdir(dp->d_name) < 0) || ( (c = thrashdir(sigdir)) == 1)) { CLOSEDIR(dirp); free(cwd); return 1; } if (c == -1) { /* * the one we picked was an * empty dir so try agai n. */ dp = NULL; chdir(cwd); } } else dp = NULL; } else { /* end dir; we have a file */ get_cwd(sigfile); strcat(sigfile, "/"); strcat(sigfile, dp->d_name); #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "Found a file=[ %s]", sigfile); #endif /* DEBUG */ } } } } free(cwd); #ifdef DEBUG if (debug & DEBUG_MISC) error_message(2, "return 0: sigfile=[%s]", sigfile); #endif /* DEBUG */ CLOSEDIR(dirp); return 0; }
(Contemporary Topics in Entomology Series) Stefan Jarau, Michael Hrncir-Food Exploitation by Social Insects - Ecological, Behavioral, and Theoretical Approaches-CRC Press (2009)