"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.4.1/src/sigfile.c" (12 Oct 2016, 7748 Bytes) of archive /linux/misc/tin-2.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sigfile.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.0_vs_2.4.1.

    1 /*
    2  *  Project   : tin - a Usenet reader
    3  *  Module    : sigfile.c
    4  *  Author    : M. Gleason & I. Lea
    5  *  Created   : 1992-10-17
    6  *  Updated   : 2013-11-21
    7  *  Notes     : Generate random signature for posting/mailing etc.
    8  *
    9  * Copyright (c) 1992-2017 Mike Gleason
   10  * All rights reserved.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. The name of the author may not be used to endorse or promote
   21  *    products derived from this software without specific prior written
   22  *    permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   25  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   28  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   30  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35  */
   36 
   37 
   38 #ifndef TIN_H
   39 #   include "tin.h"
   40 #endif /* !TIN_H */
   41 
   42 #define MAXLOOPS 1000
   43 
   44 #define CURRENTDIR "."
   45 
   46 static char sigfile[PATH_LEN];
   47 
   48 static FILE *open_random_sig(char *sigdir);
   49 static int thrashdir(char *sigdir);
   50 
   51 
   52 void
   53 msg_write_signature(
   54     FILE *fp,
   55     t_bool include_dot_signature,
   56     struct t_group *thisgroup)
   57 {
   58     FILE *fixfp;
   59     FILE *sigfp;
   60     char cwd[PATH_LEN];
   61     char path[PATH_LEN];
   62     char pathfixed[PATH_LEN];
   63 
   64 #ifdef NNTP_INEWS
   65     if (read_news_via_nntp && 0 == strcasecmp(tinrc.inews_prog, INTERNAL_CMD))
   66         include_dot_signature = TRUE;
   67 #endif /* NNTP_INEWS */
   68 
   69     if (thisgroup && !thisgroup->bogus) {
   70         if (!strcmp(thisgroup->attribute->sigfile, "--none"))
   71             return;
   72 
   73         /* TODO: handle DONT_HAVE_PIPING case */
   74 #ifndef DONT_HAVE_PIPING
   75         if (thisgroup->attribute->sigfile[0] == '!') {
   76             FILE *pipe_fp;
   77             char *sigcmd;
   78             char cmd[PATH_LEN];
   79 
   80             fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SIGDASHES : "\n");
   81             sigcmd = my_malloc(strlen(thisgroup->attribute->sigfile + 1) + strlen(thisgroup->name) + 4);
   82             sprintf(sigcmd, "%s \"%s\"", thisgroup->attribute->sigfile + 1, thisgroup->name);
   83 
   84             if ((pipe_fp = popen(sigcmd, "r")) != NULL) {
   85                 while (fgets(cmd, PATH_LEN, pipe_fp))
   86                     fputs(cmd, fp);
   87                 pclose(pipe_fp);
   88             } /* else issue an error-message? */
   89             free(sigcmd);
   90 
   91             return;
   92         }
   93 #endif /* !DONT_HAVE_PIPING */
   94         get_cwd(cwd);
   95 
   96         if (!strfpath(thisgroup->attribute->sigfile, path, sizeof(path), thisgroup, FALSE)) {
   97             if (!strfpath(tinrc.sigfile, path, sizeof(path), thisgroup, FALSE))
   98                 joinpath(path, sizeof(path), homedir, ".Sig");
   99         }
  100 
  101         /*
  102          * Check to see if sigfile is a directory & if it is
  103          * generate a random signature from sigs in sigdir. If
  104          * the file path/.sigfixed or ~/.sigfixed exists (fixed
  105          * part of random sig) then read it in first and append
  106          * the random sig part onto the end.
  107          */
  108         if ((sigfp = open_random_sig(path)) != NULL) {
  109 #ifdef DEBUG
  110             if (debug & DEBUG_MISC)
  111                 error_message(2, "USING random sig=[%s]", sigfile);
  112 #endif /* DEBUG */
  113             fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SIGDASHES : "\n");
  114             joinpath(pathfixed, sizeof(pathfixed), path, ".sigfixed");
  115 #ifdef DEBUG
  116             if (debug & DEBUG_MISC)
  117                 error_message(2, "TRYING fixed sig=[%s]", pathfixed);
  118 #endif /* DEBUG */
  119             if ((fixfp = fopen(pathfixed, "r")) != NULL) {
  120                 copy_fp(fixfp, fp);
  121                 fclose(fixfp);
  122             } else {
  123                 joinpath(pathfixed, sizeof(pathfixed), homedir, ".sigfixed");
  124 #ifdef DEBUG
  125                 if (debug & DEBUG_MISC)
  126                     error_message(2, "TRYING fixed sig=[%s]", pathfixed);
  127 #endif /* DEBUG */
  128                 if ((fixfp = fopen(pathfixed, "r")) != NULL) {
  129                     copy_fp(fixfp, fp);
  130                     fclose(fixfp);
  131                 }
  132             }
  133             copy_fp(sigfp, fp);
  134             fclose(sigfp);
  135             chdir(cwd);
  136             return;
  137         }
  138 
  139         if ((sigfp = fopen(path, "r")) != NULL) {
  140             fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SIGDASHES : "\n");
  141             copy_fp(sigfp, fp);
  142             fclose(sigfp);
  143             return;
  144         }
  145 
  146         /*
  147          * Use ~/.signature as a last resort, but only if mailing or
  148          * using internal inews (external inews appends it automagically).
  149          */
  150         if ((sigfp = fopen(default_signature, "r")) != NULL) {
  151             if (include_dot_signature) {
  152                 fprintf(fp, "\n%s", thisgroup->attribute->sigdashes ? SIGDASHES : "\n");
  153                 copy_fp(sigfp, fp);
  154             }
  155             fclose(sigfp);
  156         }
  157     }
  158 }
  159 
  160 
  161 static FILE *
  162 open_random_sig(
  163     char *sigdir)
  164 {
  165     srand((unsigned int) time(NULL));
  166 
  167     if (chdir(sigdir) == 0) {
  168         if (thrashdir(sigdir) || !*sigfile) {
  169 #ifdef DEBUG
  170             if (debug & DEBUG_MISC)
  171                 error_message(2, "NO sigfile=[%s]", sigfile);
  172 #endif /* DEBUG */
  173             return (FILE *) 0;
  174         } else {
  175 #ifdef DEBUG
  176             if (debug & DEBUG_MISC)
  177                 error_message(2, "sigfile=[%s]", sigfile);
  178 #endif /* DEBUG */
  179             return fopen(sigfile, "r");
  180         }
  181     }
  182 
  183     return (FILE *) 0;
  184 }
  185 
  186 
  187 static int
  188 thrashdir(
  189     char *sigdir)
  190 {
  191     DIR *dirp;
  192     DIR_BUF *dp;
  193     char *cwd;
  194     int safeguard, recurse;
  195     int c = 0, numentries = 0, pick;
  196     struct stat st;
  197 
  198     sigfile[0] = '\0';
  199 
  200     if ((dirp = opendir(CURRENTDIR)) == NULL)
  201         return 1;
  202 
  203     while (readdir(dirp) != NULL)
  204         numentries++;
  205 
  206     /*
  207      * consider "." and ".." non-entries
  208      * consider all entries starting with "." non-entries
  209      */
  210     if (numentries < 3) {
  211         CLOSEDIR(dirp);
  212         return -1;
  213     }
  214 
  215     cwd = my_malloc(PATH_LEN);
  216 
  217     get_cwd(cwd);
  218     recurse = strcmp(cwd, sigdir);
  219 
  220     /*
  221      * If we are using the root sig directory, we don't want
  222      * to recurse, or else we might use a custom sig intended
  223      * for a specific newsgroup (and not this one).
  224      */
  225     for (safeguard = 0, dp = NULL; safeguard < MAXLOOPS && dp == NULL; safeguard++) {
  226 #ifdef DEBUG
  227         if (debug & DEBUG_MISC)
  228             error_message(2, "sig loop=[%d] recurse=[%d]", safeguard, recurse);
  229 #endif /* DEBUG */
  230 #ifdef HAVE_REWINDDIR
  231         rewinddir(dirp);
  232 #else
  233         CLOSEDIR(dirp);
  234         if ((dirp = opendir(CURRENTDIR)) == NULL) {
  235             free(cwd);
  236             return 1;
  237         }
  238 #endif /* HAVE_REWINDDIR */
  239         pick = rand() % numentries + 1;
  240         while (--pick >= 0) {
  241             if ((dp = readdir(dirp)) == NULL)
  242                 break;
  243         }
  244         if (dp != NULL) {   /* if we could open the dir entry */
  245             if (!strcmp(dp->d_name, CURRENTDIR) || (dp->d_name[0] == '.'))
  246                 dp = NULL;
  247             else {  /* if we have a non-dot entry */
  248                 if (stat(dp->d_name, &st) == -1) {
  249                     CLOSEDIR(dirp);
  250                     free(cwd);
  251                     return 1;
  252                 }
  253                 if (S_ISDIR(st.st_mode)) {
  254                     if (recurse) {
  255                         /*
  256                          * do subdirectories
  257                          */
  258                         if ((chdir(dp->d_name) < 0) || ((c = thrashdir(sigdir)) == 1)) {
  259                             CLOSEDIR(dirp);
  260                             free(cwd);
  261                             return 1;
  262                         }
  263                         if (c == -1) {
  264                             /*
  265                              * the one we picked was an
  266                              * empty dir so try again.
  267                              */
  268                             dp = NULL;
  269                             chdir(cwd);
  270                         }
  271                     } else
  272                         dp = NULL;
  273                 } else {    /* end dir; we have a file */
  274                     get_cwd(sigfile);
  275                     strcat(sigfile, "/");
  276                     strcat(sigfile, dp->d_name);
  277 #ifdef DEBUG
  278                     if (debug & DEBUG_MISC)
  279                         error_message(2, "Found a file=[%s]", sigfile);
  280 #endif /* DEBUG */
  281                 }
  282             }
  283         }
  284     }
  285     free(cwd);
  286 #ifdef DEBUG
  287     if (debug & DEBUG_MISC)
  288         error_message(2, "return 0: sigfile=[%s]", sigfile);
  289 #endif /* DEBUG */
  290     CLOSEDIR(dirp);
  291 
  292     return 0;
  293 }