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