00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include <assert.h>
00025 #include <ctype.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 
00030 #define SIZEOF(t) (sizeof (t) / (sizeof ((t)[0])))
00031 
00032 
00033 typedef struct _info_t info_t;
00034 typedef struct _state_t state_t;
00035 typedef struct _transition_t transition_t;
00036 
00037 struct _info_t
00038 {
00039   const char *name;
00040   const char *value;
00041   int namelen;
00042 };
00043 
00044 struct _state_t
00045 {
00046   int num;
00047   const char *value;
00048   transition_t *transitions;
00049 };
00050 
00051 struct _transition_t
00052 {
00053   int value;
00054   state_t *state;
00055   transition_t *next;
00056 };
00057 
00058 
00059 info_t fields[] = {
00060   {"Accept", "MIME_FIELD_ACCEPT", 0},
00061   {"Accept-Charset", "MIME_FIELD_ACCEPT_CHARSET", 0},
00062   {"Accept-Encoding", "MIME_FIELD_ACCEPT_ENCODING", 0},
00063   {"Accept-Language", "MIME_FIELD_ACCEPT_LANGUAGE", 0},
00064   {"Accept-Ranges", "MIME_FIELD_ACCEPT_RANGES", 0},
00065   {"Age", "MIME_FIELD_AGE", 0},
00066   {"Allow", "MIME_FIELD_ALLOW", 0},
00067   {"Approved", "MIME_FIELD_APPROVED", 0},
00068   {"Authorization", "MIME_FIELD_AUTHORIZATION", 0},
00069   {"Bytes", "MIME_FIELD_BYTES", 0},
00070   {"Cache-Control", "MIME_FIELD_CACHE_CONTROL", 0},
00071   {"Connection", "MIME_FIELD_CONNECTION", 0},
00072   {"Content-Base", "MIME_FIELD_CONTENT_BASE", 0},
00073   {"Content-Encoding", "MIME_FIELD_CONTENT_ENCODING", 0},
00074   {"Content-Language", "MIME_FIELD_CONTENT_LANGUAGE", 0},
00075   {"Content-Length", "MIME_FIELD_CONTENT_LENGTH", 0},
00076   {"Content-Location", "MIME_FIELD_CONTENT_LOCATION", 0},
00077   {"Content-Md5", "MIME_FIELD_CONTENT_MD5", 0},
00078   {"Content-Range", "MIME_FIELD_CONTENT_RANGE", 0},
00079   {"Content-Type", "MIME_FIELD_CONTENT_TYPE", 0},
00080   {"Control", "MIME_FIELD_CONTROL", 0},
00081   {"Cookie", "MIME_FIELD_COOKIE", 0},
00082   {"Date", "MIME_FIELD_DATE", 0},
00083   {"Distribution", "MIME_FIELD_DISTRIBUTION", 0},
00084   {"Etag", "MIME_FIELD_ETAG", 0},
00085   {"Expires", "MIME_FIELD_EXPIRES", 0},
00086   {"Followup-To", "MIME_FIELD_FOLLOWUP_TO", 0},
00087   {"From", "MIME_FIELD_FROM", 0},
00088   {"Host", "MIME_FIELD_HOST", 0},
00089   {"If-Match", "MIME_FIELD_IF_MATCH", 0},
00090   {"If-Modified-Since", "MIME_FIELD_IF_MODIFIED_SINCE", 0},
00091   {"If-None-Match", "MIME_FIELD_IF_NONE_MATCH", 0},
00092   {"If-Range", "MIME_FIELD_IF_RANGE", 0},
00093   {"If-Unmodified-Since", "MIME_FIELD_IF_UNMODIFIED_SINCE", 0},
00094   {"Keywords", "MIME_FIELD_KEYWORDS", 0},
00095   {"Last-Modified", "MIME_FIELD_LAST_MODIFIED", 0},
00096   {"Lines", "MIME_FIELD_LINES", 0},
00097   {"Location", "MIME_FIELD_LOCATION", 0},
00098   {"Max-Forwards", "MIME_FIELD_MAX_FORWARDS", 0},
00099   {"Message-ID", "MIME_FIELD_MESSAGE_ID", 0},
00100   {"Newsgroups", "MIME_FIELD_NEWSGROUPS", 0},
00101   {"Organization", "MIME_FIELD_ORGANIZATION", 0},
00102   {"Path", "MIME_FIELD_PATH", 0},
00103   {"Pragma", "MIME_FIELD_PRAGMA", 0},
00104   {"Proxy-Authenticate", "MIME_FIELD_PROXY_AUTHENTICATE", 0},
00105   {"Proxy-Authorization", "MIME_FIELD_PROXY_AUTHORIZATION", 0},
00106   {"Proxy-Connection", "MIME_FIELD_PROXY_CONNECTION", 0},
00107   {"Public", "MIME_FIELD_PUBLIC", 0},
00108   {"Range", "MIME_FIELD_RANGE", 0},
00109   {"References", "MIME_FIELD_REFERENCES", 0},
00110   {"Referer", "MIME_FIELD_REFERER", 0},
00111   {"Reply-To", "MIME_FIELD_REPLY_TO", 0},
00112   {"Retry-After", "MIME_FIELD_RETRY_AFTER", 0},
00113   {"Sender", "MIME_FIELD_SENDER", 0},
00114   {"Server", "MIME_FIELD_SERVER", 0},
00115   {"Set-Cookie", "MIME_FIELD_SET_COOKIE", 0},
00116   {"Subject", "MIME_FIELD_SUBJECT", 0},
00117   {"Summary", "MIME_FIELD_SUMMARY", 0},
00118   {"Transfer-Encoding", "MIME_FIELD_TRANSFER_ENCODING", 0},
00119   {"Upgrade", "MIME_FIELD_UPGRADE", 0},
00120   {"User-Agent", "MIME_FIELD_USER_AGENT", 0},
00121   {"Vary", "MIME_FIELD_VARY", 0},
00122   {"Via", "MIME_FIELD_VIA", 0},
00123   {"Warning", "MIME_FIELD_WARNING", 0},
00124   {"Www-Authenticate", "MIME_FIELD_WWW_AUTHENTICATE", 0},
00125   {"Xref", "MIME_FIELD_XREF", 0},
00126   {NULL, "MIME_FIELD_EXTENSION", 0},
00127 };
00128 
00129 info_t schemes[] = {
00130   {"file", "URL_SCHEME_FILE", 0},
00131   {"ftp", "URL_SCHEME_FTP", 0},
00132   {"gopher", "URL_SCHEME_GOPHER", 0},
00133   {"http", "URL_SCHEME_HTTP", 0},
00134   {"https", "URL_SCHEME_HTTPS", 0},
00135   {"mailto", "URL_SCHEME_MAILTO", 0},
00136   {"news", "URL_SCHEME_NEWS", 0},
00137   {"nntp", "URL_SCHEME_NNTP", 0},
00138   {"prospero", "URL_SCHEME_PROSPERO", 0},
00139   {"telnet", "URL_SCHEME_TELNET", 0},
00140   {"wais", "URL_SCHEME_WAIS", 0},
00141   {NULL, "URL_SCHEME_NONE", 0},
00142 };
00143 
00144 info_t methods[] = {
00145   {"CONNECT", "HTTP_METHOD_CONNECT", -1},
00146   {"DELETE", "HTTP_METHOD_DELETE", -1},
00147   {"GET", "HTTP_METHOD_GET", -1},
00148   {"HEAD", "HTTP_METHOD_HEAD", -1},
00149   {"HTTP/", "HTTP_METHOD_HTTP", -1},
00150   {"OPTIONS", "HTTP_METHOD_OPTIONS", -1},
00151   {"POST", "HTTP_METHOD_POST", -1},
00152   {"PURGE", "HTTP_METHOD_PURGE", -1},
00153   {"PUT", "HTTP_METHOD_PUT", -1},
00154   {"TRACE", "HTTP_METHOD_TRACE", -1},
00155   {NULL, "HTTP_METHOD_NONE", 0},
00156 };
00157 
00158 info_t statuses[] = {
00159   {"100", "HTTP_STATUS_CONTINUE", -1},
00160   {"101", "HTTP_STATUS_SWITCHING_PROTOCOL", -1},
00161   {"200", "HTTP_STATUS_OK", -1},
00162   {"201", "HTTP_STATUS_CREATED", -1},
00163   {"202", "HTTP_STATUS_ACCEPTED", -1},
00164   {"203", "HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION", -1},
00165   {"204", "HTTP_STATUS_NO_CONTENT", -1},
00166   {"205", "HTTP_STATUS_RESET_CONTENT", -1},
00167   {"206", "HTTP_STATUS_PARTIAL_CONTENT", -1},
00168   {"300", "HTTP_STATUS_MULTIPLE_CHOICES", -1},
00169   {"301", "HTTP_STATUS_MOVED_PERMANENTLY", -1},
00170   {"302", "HTTP_STATUS_MOVED_TEMPORARILY", -1},
00171   {"303", "HTTP_STATUS_SEE_OTHER", -1},
00172   {"304", "HTTP_STATUS_NOT_MODIFIED", -1},
00173   {"305", "HTTP_STATUS_USE_PROXY", -1},
00174   {"400", "HTTP_STATUS_BAD_REQUEST", -1},
00175   {"401", "HTTP_STATUS_UNAUTHORIZED", -1},
00176   {"402", "HTTP_STATUS_PAYMENT_REQUIRED", -1},
00177   {"403", "HTTP_STATUS_FORBIDDEN", -1},
00178   {"404", "HTTP_STATUS_NOT_FOUND", -1},
00179   {"405", "HTTP_STATUS_METHOD_NOT_ALLOWED", -1},
00180   {"406", "HTTP_STATUS_NOT_ACCEPTABLE", -1},
00181   {"407", "HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED", -1},
00182   {"408", "HTTP_STATUS_REQUEST_TIMEOUT", -1},
00183   {"409", "HTTP_STATUS_CONFLICT", -1},
00184   {"410", "HTTP_STATUS_GONE", -1},
00185   {"411", "HTTP_STATUS_LENGTH_REQUIRED", -1},
00186   {"412", "HTTP_STATUS_PRECONDITION_FAILED", -1},
00187   {"413", "HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE", -1},
00188   {"414", "HTTP_STATUS_REQUEST_URI_TOO_LONG", -1},
00189   {"415", "HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE", -1},
00190   {"500", "HTTP_STATUS_INTERNAL_SERVER_ERROR", -1},
00191   {"501", "HTTP_STATUS_NOT_IMPLEMENTED", -1},
00192   {"502", "HTTP_STATUS_BAD_GATEWAY", -1},
00193   {"503", "HTTP_STATUS_SERVICE_UNAVAILABLE", -1},
00194   {"504", "HTTP_STATUS_GATEWAY_TIMEOUT", -1},
00195   {"505", "HTTP_STATUS_HTTPVER_NOT_SUPPORTED", -1},
00196   {NULL, "HTTP_STATUS_NONE", 0},
00197 };
00198 
00199 info_t days[] = {
00200   {"Fri", "FRIDAY", -1},
00201   {"Friday", "FRIDAY", -1},
00202   {"Mon", "MONDAY", -1},
00203   {"Monday", "MONDAY", -1},
00204   {"Sat", "SATURDAY", -1},
00205   {"Saturday", "SATURDAY", -1},
00206   {"Sun", "SUNDAY", -1},
00207   {"Sunday", "SUNDAY", -1},
00208   {"Thu", "THURSDAY", -1},
00209   {"Thursday", "THURSDAY", -1},
00210   {"Tue", "TUESDAY", -1},
00211   {"Tuesday", "TUESDAY", -1},
00212   {"Wed", "WEDNESDAY", -1},
00213   {"Wednesday", "WEDNESDAY", -1},
00214   {NULL, "UNKNOWN_DAY", -1},
00215 };
00216 
00217 info_t months[] = {
00218   {"Apr", "APRIL", -1},
00219   {"Aug", "AUGUST", -1},
00220   {"Dec", "DECEMBER", -1},
00221   {"Feb", "FEBRUARY", -1},
00222   {"Jan", "JANUARY", -1},
00223   {"Jul", "JULY", -1},
00224   {"Jun", "JUNE", -1},
00225   {"Mar", "MARCH", -1},
00226   {"May", "MAY", -1},
00227   {"Nov", "NOVEMBER", -1},
00228   {"Oct", "OCTOBER", -1},
00229   {"Sep", "SEPTEMBER", -1},
00230   {NULL, "UNKNOWN_MONTH", -1},
00231 };
00232 
00233 info_t connections[] = {
00234   {"CLOSE", "HTTP_CONNECTION_CLOSE", -1},
00235   {"KEEP-ALIVE", "HTTP_CONNECTION_KEEP_ALIVE", -1},
00236   {NULL, "HTTP_CONNECTION_NONE", -1},
00237 };
00238 
00239 info_t cache_controls[] = {
00240   {"max-age", "HTTP_CACHE_DIRECTIVE_MAX_AGE", -1},
00241   {"max-stale", "HTTP_CACHE_DIRECTIVE_MAX_STALE", -1},
00242   {"min-fresh", "HTTP_CACHE_DIRECTIVE_MIN_FRESH", -1},
00243   {"must-revalidate", "HTTP_CACHE_DIRECTIVE_MUST_REVALIDATE", -1},
00244   {"no-cache", "HTTP_CACHE_DIRECTIVE_NO_CACHE", -1},
00245   {"no-store", "HTTP_CACHE_DIRECTIVE_NO_STORE", -1},
00246   {"no-transform", "HTTP_CACHE_DIRECTIVE_NO_TRANSFORM", -1},
00247   {"only-if-cached", "HTTP_CACHE_DIRECTIVE_ONLY_IF_CACHED", -1},
00248   {"private", "HTTP_CACHE_DIRECTIVE_PRIVATE", -1},
00249   {"proxy-revalidate", "HTTP_CACHE_DIRECTIVE_PROXY_REVALIDATE", -1},
00250   {"public", "HTTP_CACHE_DIRECTIVE_PUBLIC", -1},
00251   {"s-maxage", "HTTP_CACHE_DIRECTIVE_S_MAX_AGE", -1},
00252   {NULL, "HTTP_CACHE_DIRECTIVE_CACHE_EXTENSION", -1},
00253 };
00254 
00255 
00256 state_t *start = NULL;
00257 int state_count = 0;
00258 
00259 int *map = NULL;
00260 int *basetbl = NULL;
00261 int *nexttbl = NULL;
00262 int *checktbl = NULL;
00263 const char **accepttbl = NULL;
00264 char **prefixtbl = NULL;
00265 
00266 
00267 state_t *
00268 mkstate()
00269 {
00270   state_t *state;
00271 
00272   state = (state_t *) malloc(sizeof(state_t));
00273   state->num = state_count++;
00274   state->value = NULL;
00275   state->transitions = NULL;
00276 
00277   return state;
00278 }
00279 
00280 transition_t *
00281 mktransition()
00282 {
00283   transition_t *transition;
00284 
00285   transition = (transition_t *) malloc(sizeof(transition_t));
00286   transition->value = 0;
00287   transition->state = NULL;
00288   transition->next = NULL;
00289 
00290   return transition;
00291 }
00292 
00293 void
00294 prstate(state_t * state)
00295 {
00296   transition_t *transitions;
00297 
00298   printf("%3d:", state->num);
00299 
00300   if (state->value)
00301     printf(" %s", state->value);
00302   printf("\n");
00303 
00304   transitions = state->transitions;
00305   while (transitions) {
00306     printf("     %c --> %d\n", tolower(transitions->value), transitions->state->num);
00307     transitions = transitions->next;
00308   }
00309 
00310   transitions = state->transitions;
00311   while (transitions) {
00312     prstate(transitions->state);
00313     transitions = transitions->next;
00314   }
00315 }
00316 
00317 void
00318 add_states(state_t * state, info_t * info, int pos)
00319 {
00320   transition_t *transitions;
00321 
00322   if (info->namelen == pos) {
00323     state->value = info->value;
00324     return;
00325   }
00326 
00327   transitions = state->transitions;
00328   while (transitions) {
00329     if (tolower(transitions->value) == tolower(info->name[pos])) {
00330       if ((transitions->state->value && (info->namelen == (pos + 1))) || (info->namelen != (pos + 1))) {
00331         add_states(transitions->state, info, pos + 1);
00332         return;
00333       }
00334     }
00335 
00336     transitions = transitions->next;
00337   }
00338 
00339   if (state->transitions) {
00340     transitions = state->transitions;
00341     while (transitions->next)
00342       transitions = transitions->next;
00343 
00344     transitions->next = mktransition();
00345     transitions = transitions->next;
00346   } else {
00347     transitions = mktransition();
00348     state->transitions = transitions;
00349   }
00350 
00351   transitions->value = info->name[pos];
00352   transitions->state = mkstate();
00353 
00354   add_states(transitions->state, info, pos + 1);
00355 }
00356 
00357 void
00358 prtable(const char *type, const char *name, int *table, int size)
00359 {
00360   int i;
00361 
00362   printf("  static %s %s[%d] =\n", type, name, size);
00363   printf("  {\n");
00364 
00365   for (i = 0; i < size; i++) {
00366     if ((i % 12) == 0)
00367       printf("    %3d,", table[i]);
00368     else if ((i % 12) == 11)
00369       printf(" %3d,\n", table[i]);
00370     else
00371       printf(" %3d,", table[i]);
00372   }
00373 
00374   if ((i % 12) != 0)
00375     printf("\n");
00376 
00377   printf("  };\n");
00378 }
00379 
00380 int
00381 mkmap(state_t * state)
00382 {
00383   static int count = 1;
00384 
00385   transition_t *transitions;
00386 
00387   transitions = state->transitions;
00388   while (transitions) {
00389     if (map[tolower(transitions->value)] == 0) {
00390       map[tolower(transitions->value)] = count;
00391       map[toupper(transitions->value)] = count;
00392       count += 1;
00393     }
00394 
00395     mkmap(transitions->state);
00396 
00397     transitions = transitions->next;
00398   }
00399 
00400   return count;
00401 }
00402 
00403 void
00404 mkaccept(state_t * state, const char *defvalue)
00405 {
00406   transition_t *transitions;
00407 
00408   if (state->value)
00409     accepttbl[state->num] = state->value;
00410   else
00411     accepttbl[state->num] = defvalue;
00412 
00413   transitions = state->transitions;
00414   while (transitions) {
00415     mkaccept(transitions->state, defvalue);
00416     transitions = transitions->next;
00417   }
00418 }
00419 
00420 void
00421 mkprefix(state_t * state, char *prefix, int length)
00422 {
00423   transition_t *transitions;
00424 
00425   prefixtbl[state->num] = (char *) malloc(sizeof(char) * (length + 1));
00426   strncpy(prefixtbl[state->num], prefix, length);
00427   prefixtbl[state->num][length] = '\0';
00428 
00429   transitions = state->transitions;
00430   while (transitions) {
00431     prefix[length] = transitions->value;
00432     mkprefix(transitions->state, prefix, length + 1);
00433     transitions = transitions->next;
00434   }
00435 }
00436 
00437 int
00438 checkbase(state_t * state, int base)
00439 {
00440   transition_t *transitions;
00441 
00442   transitions = state->transitions;
00443   while (transitions) {
00444     if (checktbl[base + map[transitions->value]] != -1)
00445       return 0;
00446     transitions = transitions->next;
00447   }
00448 
00449   return 1;
00450 }
00451 
00452 void
00453 mktranstables(state_t * state)
00454 {
00455   transition_t *transitions;
00456   int base;
00457 
00458   base = 0;
00459   while (base < state_count) {
00460     if (checkbase(state, base))
00461       break;
00462     base += 1;
00463   }
00464 
00465   assert(base < state_count);
00466 
00467   basetbl[state->num] = base;
00468 
00469   transitions = state->transitions;
00470   while (transitions) {
00471     assert(checktbl[basetbl[state->num] + map[transitions->value]] == -1);
00472 
00473     checktbl[basetbl[state->num] + map[transitions->value]] = state->num;
00474     nexttbl[basetbl[state->num] + map[transitions->value]] = transitions->state->num;
00475     transitions = transitions->next;
00476   }
00477 
00478   transitions = state->transitions;
00479   while (transitions) {
00480     mktranstables(transitions->state);
00481     transitions = transitions->next;
00482   }
00483 }
00484 
00485 void
00486 mktables(state_t * state, const char *defvalue, int useprefix)
00487 {
00488   char prefix[1024];
00489   int char_count;
00490   int i;
00491 
00492   
00493   map = (int *) malloc(sizeof(int) * 256);
00494   for (i = 0; i < 256; i++)
00495     map[i] = 0;
00496 
00497   char_count = mkmap(state);
00498 
00499   prtable("int", "map", map, 256);
00500   printf("\n");
00501 
00502   
00503   accepttbl = (const char **) malloc(sizeof(const char *) * state_count);
00504   for (i = 0; i < state_count; i++)
00505     accepttbl[i] = NULL;
00506 
00507   mkaccept(state, defvalue);
00508 
00509   
00510   printf("  static int accepttbl[%d] =\n", state_count);
00511   printf("  {\n");
00512 
00513   for (i = 0; i < state_count; i++)
00514     printf("    %s,\n", accepttbl[i]);
00515 
00516   printf("  };\n\n");
00517 
00518   
00519   if (useprefix) {
00520     prefixtbl = (char **) malloc(sizeof(char *) * state_count);
00521     for (i = 0; i < state_count; i++)
00522       prefixtbl[i] = NULL;
00523 
00524     mkprefix(state, prefix, 0);
00525 
00526     
00527     printf("  static const char *prefixtbl[%d] =\n", state_count);
00528     printf("  {\n");
00529 
00530     for (i = 0; i < state_count; i++)
00531       printf("    \"%s\",\n", prefixtbl[i]);
00532 
00533     printf("  };\n\n");
00534   }
00535 
00536   
00537 
00538   basetbl = (int *) malloc(sizeof(int) * state_count);
00539   nexttbl = (int *) malloc(sizeof(int) * (state_count + char_count));
00540   checktbl = (int *) malloc(sizeof(int) * (state_count + char_count));
00541 
00542   for (i = 0; i < state_count; i++) {
00543     basetbl[i] = -1;
00544   }
00545 
00546   for (i = 0; i < (state_count + char_count); i++) {
00547     nexttbl[i] = 0;
00548     checktbl[i] = -1;
00549   }
00550 
00551   mktranstables(state);
00552 
00553   prtable("int", "basetbl", basetbl, state_count);
00554   printf("\n");
00555   prtable("int", "nexttbl", nexttbl, state_count + char_count);
00556   printf("\n");
00557   prtable("int", "checktbl", checktbl, state_count + char_count);
00558 }
00559 
00560 const char *
00561 rundfa(const char *buf, int length)
00562 {
00563   const char *end;
00564   int state;
00565   int ch, tmp;
00566 
00567   state = 0;
00568   end = buf + length;
00569 
00570   while (buf != end) {
00571     ch = map[(int) *buf++];
00572 
00573     tmp = basetbl[state] + ch;
00574     if (checktbl[tmp] != state)
00575       return NULL;
00576     state = nexttbl[tmp];
00577   }
00578 
00579   return accepttbl[state];
00580 }
00581 
00582 void
00583 mkdfa(info_t * infos, int ninfos, int useprefix, int debug)
00584 {
00585   
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598   int i;
00599 
00600   start = mkstate();
00601 
00602   for (i = 0; i < (ninfos - 1); i++)
00603     infos[i].namelen = strlen(infos[i].name);
00604 
00605   for (i = 0; i < (ninfos - 1); i++)
00606     add_states(start, &infos[i], 0);
00607 
00608   mktables(start, infos[ninfos - 1].value, useprefix);
00609 
00610   if (debug) {
00611     printf("\n/*\n");
00612     prstate(start);
00613     printf("*/\n");
00614 
00615     
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634   }
00635 }
00636 
00637 int
00638 main(int argc, char *argv[])
00639 {
00640   if (argc < 2)
00641     return 1;
00642 
00643   if (strcmp(argv[1], "fields") == 0)
00644     mkdfa(fields, SIZEOF(fields), 1, (argc == 3));
00645   else if (strcmp(argv[1], "methods") == 0)
00646     mkdfa(methods, SIZEOF(methods), 0, (argc == 3));
00647   else if (strcmp(argv[1], "statuses") == 0)
00648     mkdfa(statuses, SIZEOF(statuses), 0, (argc == 3));
00649   else if (strcmp(argv[1], "schemes") == 0)
00650     mkdfa(schemes, SIZEOF(schemes), 0, (argc == 3));
00651   else if (strcmp(argv[1], "days") == 0)
00652     mkdfa(days, SIZEOF(days), 0, (argc == 3));
00653   else if (strcmp(argv[1], "months") == 0)
00654     mkdfa(months, SIZEOF(months), 0, (argc == 3));
00655   else if (strcmp(argv[1], "connections") == 0)
00656     mkdfa(connections, SIZEOF(connections), 0, (argc == 3));
00657   else if (strcmp(argv[1], "cache-controls") == 0)
00658     mkdfa(cache_controls, SIZEOF(cache_controls), 0, (argc == 3));
00659 
00660   return 0;
00661 }