00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include <stdlib.h>
00010 #include <fcntl.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 
00014 #include "warnings.h"
00015 #include "interface.h"
00016 #include "global.h"
00017 
00018 
00025 const char *wa__warn_action_text[_WA__LAST_INDEX] =
00026 {
00027   [WA__WARN_ONCE]   = "once",
00028   [WA__WARN_ALWAYS] = "always",
00029   [WA__IGNORE]          = "ignore",
00030   [WA__STOP]                = "stop",
00031   [WA__COUNT]           = "count",
00032 };
00033 
00035 static struct wa__warnings wa___warn_options[_WRN__LAST_INDEX]=
00036 {
00037   [WRN__META_MTIME_INVALID]     = { "meta-mtime" },
00038   [WRN__META_USER_INVALID]      = { "meta-user" },
00039   [WRN__META_GROUP_INVALID]     = { "meta-group" },
00040   [WRN__META_UMASK_INVALID]     = { "meta-umask" },
00041 
00042     [WRN__NO_URLLIST]                       =   { "no-urllist" },
00043 
00044     [WRN__CHARSET_INVALID]          =   { "charset-invalid" },
00045 
00046     [WRN__CHMOD_EPERM]                  =   { "chmod-eperm", WA__WARN_ONCE},
00047     [WRN__CHOWN_EPERM]                  =   { "chown-eperm", WA__WARN_ONCE},
00048     [WRN__CHMOD_OTHER]                  =   { "chmod-other", WA__STOP },
00049     [WRN__CHOWN_OTHER]                  =   { "chown-other", WA__STOP },
00050 
00051     [WRN__OVERLAYED_ENTRIES]        =   { "overlayed-entries", WA__WARN_ALWAYS },
00052     [WRN__MIXED_REV_WC]                 =   { "mixed-rev-wc", WA__WARN_ALWAYS },
00053 
00054     [WRN__PROP_NAME_RESERVED]       =   { "propname-reserved", WA__STOP },
00055 
00056     [WRN__DIFF_EXIT_STATUS]         =   { "diff-status", WA__IGNORE },
00057 
00058     [WRN__IGNPAT_WCBASE]                =   { "ignpat-wcbase", WA__WARN_ALWAYS },
00059 
00060     [WRN__TEST_WARNING]                 =   { "_test-warning", WA__IGNORE },
00061 };
00062 
00065 static FILE *warn_out;
00066 
00067 
00070 int wa__split_process(char *warn, int prio)
00071 {
00072     int status;
00073     char *input;
00074 
00075     status=0;
00076     input=warn;
00077     while (warn && *warn)
00078     {
00079         warn=strtok(input, ",; \r\t\n");
00080         if (!warn) break;
00081 
00082         
00083         input=NULL;
00084 
00085         STOPIF( wa__set_warn_option(warn, prio),
00086                 "In string %s", warn);
00087     }
00088 
00089 ex:
00090     return status;
00091 }
00092 
00093 
00103 int wa__set_warn_option(char *stg, enum opt__prio_e prio)
00104 {
00105     char *delim;
00106     int status;
00107     int index, action, len;
00108     struct wa__warnings *warning;
00109 
00110     status=0;
00111     delim=strchr(stg, '=');
00112     STOPIF_CODE_ERR(!delim, EINVAL,
00113             "!The warning option '%s' is invalid",
00114             stg);
00115 
00116     
00117 
00118 
00119     for(action=_WA__LAST_INDEX-1; action>=0; action--)
00120         if (strcmp(wa__warn_action_text[action], delim+1) == 0)
00121             break;
00122     STOPIF_CODE_ERR(action < 0, EINVAL,
00123             "The warning action specification '%s' is invalid",
00124             delim+1);
00125 
00126     
00127 
00128 
00129     status=EINVAL;
00130     len=delim-stg;
00131     warning=wa___warn_options;
00132     for(index=0; index<_WRN__LAST_INDEX; index++, warning++)
00133     {
00134         if (strncmp(warning->text, stg, len) == 0)
00135         {
00136             if (warning->prio <= prio)
00137             {
00138                 warning->action=action;
00139                 warning->prio=prio;
00140                 DEBUGP("warning option set: %s=%s, prio %d",
00141                         warning->text, 
00142                         wa__warn_action_text[warning->action],
00143                         prio);
00144             }
00145             status=0;
00146         }
00147     }
00148 
00149     STOPIF_CODE_ERR(status, status,
00150             "The given warning option '%*s' matches no warnings",
00151             len, stg);
00152 
00153 ex:
00154     return status;
00155 }
00156 
00157 
00164 int wa__warn(warning_e index, int stat, char *format, ...)
00165 {
00166     va_list va;
00167     int status, ret;
00168 
00169     if (!warn_out)
00170         warn_out=stderr;
00171 
00172     wa___warn_options[index].count++;
00173     status=0;
00174     switch (wa___warn_options[index].action)
00175     {
00176         case WA__IGNORE:
00177         case WA__COUNT:
00178             break;
00179         case WA__STOP:
00180             status=stat;
00181             if (!status) status=EAGAIN;
00182 
00183             
00184         case WA__WARN_ONCE:
00185             
00186 
00187         case WA__WARN_ALWAYS:
00188             
00189             va_start(va, format);
00190             ret=fprintf(warn_out, "\nWARNING");
00191             if (opt__is_verbose() > 0)
00192                 ret|=fprintf(warn_out, "(%s)", wa___warn_options[index].text);
00193             ret|=fprintf(warn_out, ": ");
00194             ret|=vfprintf(warn_out, format, va);
00195             ret|=fprintf(warn_out, "\n\n");
00196 
00197             if (!status)
00198                 
00199 
00200                 STOPIF_CODE_ERR(ret<0, errno,
00201                         "Error while printing warning");
00202 
00203             if (wa___warn_options[index].action == WA__WARN_ONCE)
00204                 
00205                 wa___warn_options[index].action=WA__COUNT;
00206             break;
00207         default:
00208             BUG("Invalid warning action encountered");
00209     }
00210 
00211 ex:
00212     return status;
00213 }
00214 
00215 
00219 int wa__summary(void)
00220 {
00221     int i, status;
00222     int flag;
00223 
00224 
00225     status=0;
00226     
00227 
00228     STOPIF_CODE_EPIPE( fflush(NULL), NULL);
00229 
00230     flag=0;
00231     for(i=0; i<_WRN__LAST_INDEX; i++)
00232     {
00233         DEBUGP("%d# %s: %dx",
00234                 i,
00235                 wa___warn_options[i].text,
00236                 wa___warn_options[i].count);
00237 
00238         if (wa___warn_options[i].action != WA__IGNORE &&
00239                 wa___warn_options[i].count)
00240         {
00241             
00242 
00243             if (!flag++)
00244                 STOPIF_CODE_ERR( fprintf(warn_out, "\nWarning summary:\n")<0, errno,
00245                         "Error writing warning summary header");
00246 
00247             STOPIF_CODE_ERR( fprintf(warn_out, "   %s occurred %d time%s\n",
00248                         wa___warn_options[i].text,
00249                         wa___warn_options[i].count,
00250                         wa___warn_options[i].count == 1 ? "" : "s") <0, errno,
00251                     "Cannot write warning summary line");
00252         }
00253     }
00254 
00255 ex:
00256     return status;
00257 }
00258 
00259