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__MIXED_REV_WC] = { "mixed-rev-wc", WA__WARN_ALWAYS },
00052
00053 [WRN__PROP_NAME_RESERVED] = { "propname-reserved", WA__STOP },
00054
00055 [WRN__DIFF_EXIT_STATUS] = { "diff-status", WA__IGNORE },
00056
00057 [WRN__IGNPAT_WCBASE] = { "ignpat-wcbase", WA__WARN_ALWAYS },
00058
00059 [WRN__TEST_WARNING] = { "_test-warning", WA__IGNORE },
00060 };
00061
00064 static FILE *warn_out;
00065
00066
00069 int wa__split_process(char *warn, int prio)
00070 {
00071 int status;
00072 char *input;
00073
00074 status=0;
00075 input=warn;
00076 while (warn && *warn)
00077 {
00078 warn=strtok(input, ",; \r\t\n");
00079 if (!warn) break;
00080
00081
00082 input=NULL;
00083
00084 STOPIF( wa__set_warn_option(warn, prio),
00085 "In string %s", warn);
00086 }
00087
00088 ex:
00089 return status;
00090 }
00091
00092
00102 int wa__set_warn_option(char *stg, enum opt__prio_e prio)
00103 {
00104 char *delim;
00105 int status;
00106 int index, action, len;
00107 struct wa__warnings *warning;
00108
00109 status=0;
00110 delim=strchr(stg, '=');
00111 STOPIF_CODE_ERR(!delim, EINVAL,
00112 "!The warning option '%s' is invalid",
00113 stg);
00114
00115
00116
00117
00118 for(action=_WA__LAST_INDEX-1; action>=0; action--)
00119 if (strcmp(wa__warn_action_text[action], delim+1) == 0)
00120 break;
00121 STOPIF_CODE_ERR(action < 0, EINVAL,
00122 "The warning action specification '%s' is invalid",
00123 delim+1);
00124
00125
00126
00127
00128 status=EINVAL;
00129 len=delim-stg;
00130 warning=wa___warn_options;
00131 for(index=0; index<_WRN__LAST_INDEX; index++, warning++)
00132 {
00133 if (strncmp(warning->text, stg, len) == 0)
00134 {
00135 if (warning->prio <= prio)
00136 {
00137 warning->action=action;
00138 warning->prio=prio;
00139 DEBUGP("warning option set: %s=%s, prio %d",
00140 warning->text,
00141 wa__warn_action_text[warning->action],
00142 prio);
00143 }
00144 status=0;
00145 }
00146 }
00147
00148 STOPIF_CODE_ERR(status, status,
00149 "The given warning option '%*s' matches no warnings",
00150 len, stg);
00151
00152 ex:
00153 return status;
00154 }
00155
00156
00163 int wa__warn(warning_e index, int stat, char *format, ...)
00164 {
00165 va_list va;
00166 int status, ret;
00167
00168 if (!warn_out)
00169 warn_out=stderr;
00170
00171 wa___warn_options[index].count++;
00172 status=0;
00173 switch (wa___warn_options[index].action)
00174 {
00175 case WA__IGNORE:
00176 case WA__COUNT:
00177 break;
00178 case WA__STOP:
00179 status=stat;
00180 if (!status) status=EAGAIN;
00181
00182
00183 case WA__WARN_ONCE:
00184
00185
00186 case WA__WARN_ALWAYS:
00187
00188 va_start(va, format);
00189 ret=fprintf(warn_out, "\nWARNING");
00190 if (opt__is_verbose() > 0)
00191 ret|=fprintf(warn_out, "(%s)", wa___warn_options[index].text);
00192 ret|=fprintf(warn_out, ": ");
00193 ret|=vfprintf(warn_out, format, va);
00194 ret|=fprintf(warn_out, "\n\n");
00195
00196 if (!status)
00197
00198
00199 STOPIF_CODE_ERR(ret<0, errno,
00200 "Error while printing warning");
00201
00202 if (wa___warn_options[index].action == WA__WARN_ONCE)
00203
00204 wa___warn_options[index].action=WA__COUNT;
00205 break;
00206 default:
00207 BUG("Invalid warning action encountered");
00208 }
00209
00210 ex:
00211 return status;
00212 }
00213
00214
00218 int wa__summary(void)
00219 {
00220 int i, status;
00221 int flag;
00222
00223
00224 status=0;
00225
00226
00227 STOPIF_CODE_EPIPE( fflush(NULL), NULL);
00228
00229 flag=0;
00230 for(i=0; i<_WRN__LAST_INDEX; i++)
00231 {
00232 DEBUGP("%d# %s: %dx",
00233 i,
00234 wa___warn_options[i].text,
00235 wa___warn_options[i].count);
00236
00237 if (wa___warn_options[i].action != WA__IGNORE &&
00238 wa___warn_options[i].count)
00239 {
00240
00241
00242 if (!flag++)
00243 STOPIF_CODE_ERR( fprintf(warn_out, "\nWarning summary:\n")<0, errno,
00244 "Error writing warning summary header");
00245
00246 STOPIF_CODE_ERR( fprintf(warn_out, " %s occurred %d time%s\n",
00247 wa___warn_options[i].text,
00248 wa___warn_options[i].count,
00249 wa___warn_options[i].count == 1 ? "" : "s") <0, errno,
00250 "Cannot write warning summary line");
00251 }
00252 }
00253
00254 ex:
00255 return status;
00256 }
00257
00258