home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / comm / tcp / httplog14.lha / httplog.c < prev    next >
C/C++ Source or Header  |  1995-12-28  |  23KB  |  968 lines

  1. /*
  2. // httplog.c
  3. //
  4. // (c) Armin Obersteiner
  5. //
  6. // Parsing ncsa/cern httpd logfile
  7. //
  8. // USAGE: httplog [-s <keyword>] [-l] <logfile>
  9. //
  10. // <logfile>      -  httpd <logfile>
  11. // -l             -  long: country statistics
  12. // -lt            -  long: time statistics
  13. // -s <keyword>   -  search for <keyword>
  14. //
  15. // compiles on:   MaxonC++ (amiga)
  16. //                gcc (amiga)
  17. //                gcc (bsd)
  18. // (it should actually compile on any platform then :)
  19. //
  20. //  ->>>  gcc -o httplog httplog.c -lm
  21. //
  22. // it´s made to work on logfiles with american date format and austrian/german time format (24h)
  23. //
  24. //
  25. //    to include new countries:
  26. //
  27. //          -   add lines to structure "struct dummy c"
  28. //       -  don´t forget to increase "country_anz"
  29. //
  30. //    to adapt time and date for other logfile formats:
  31. //
  32. //          -   do the same with "struct dummy d" / "struct dummy t"
  33. //       -  don´t forget to increase/decrease "day_anz" :)  / "time_anz"
  34. //
  35. //    the second entry in these stuctures (dummy) is the string to search for
  36. //       (use spaces or brackets, because it´s more reliable then)
  37. //    the third entry is the string for output
  38. //
  39. //
  40. // CU Armin :)
  41. //
  42. //    ( Armin.Obersteiner@giga.or.at )
  43. */
  44. /* Armin Obersteiner wrote a nice httpd log parser.
  45.  * I played with it, to suit my fancy.
  46.  * First of all, I found that there were many numeric addresses in
  47.  * my logfiles.  That made for a large number of unidentified domains
  48.  * when run with the -l flag.  I didn't like that, so I invoked AmiTCP
  49.  * to find the name that goes with the missing address.  It doesn't always
  50.  * work, if the local DNS server cannot find a name to go with an IP
  51.  * number, but when the server is helpful, it does work.
  52.  * Next, I added all of the countries to be found in the ISO 3166
  53.  * document.  Then, I made the output for -l sorted by increasing
  54.  * number of hits.
  55.  * Added getadd(), site_ext  26 Nov 95 TCW
  56.  * Added ISO 3166 countries 28 Nov 95 TCW
  57.  * Compiles under SAS/C 6.56
  58.  * Requires AmiTCP >=4.0
  59.  * TCW:= tomas willis <tomas@cae.wisc.edu>
  60.  */
  61.  
  62. #include <stdio.h>
  63. #include <string.h>
  64. #include <stdlib.h>
  65. #include <math.h>
  66. #include <ctype.h>
  67. #include "httplog_rev.h"
  68. /*TCW*/
  69. #include <sys/types.h>
  70. #include <sys/socket.h>
  71. #include <sys/param.h>
  72. #include <arpa/inet.h>
  73. #include <netinet/in.h>
  74. #include <netdb.h>
  75.  
  76. FILE *f;
  77.  
  78. static char *revstag = VERSTAG;    /* TCW 16 Nov 95 */
  79.  
  80.   struct dummy {
  81.       int count;
  82.       char *ext;
  83.       char *name;
  84.   };
  85.  
  86. /* 27 Nov 95: TCW:
  87. * Added _all_ of the ISO 3166 country codes.
  88. * Now, you should hardly every encounter unknown networks.
  89. * Sorted to help most likely hits occur at the top of the list
  90. * for _my_ site.  If in Europe, you milage (kilometrage?) may vary.
  91. * Kept old (e.g. .uk, .gov) stuff.
  92. */
  93. /*int country_anz=26;*/
  94. struct dummy c[] =
  95. {
  96. /* localhost --- many hits from testing, perhaps */
  97.     {0, "localhost", "localhost"},
  98.  
  99. /* north america --- many hits from many computers */
  100.     {0, ".edu", "usa education"},
  101.     {0, ".com", "usa commercial"},
  102.     {0, ".gov", "usa goverment"},
  103.     {0, ".mil", "usa military"},
  104.     {0, ".org", "usa organization"},
  105.     {0, ".us", "united states"},
  106.     {0, ".ca", "canada"},
  107.  
  108. /* this is new and official, but not busy yet.  still, that will change. */
  109.     {0, ".int", "international organization"},
  110.  
  111. /* the network */
  112.     {0, ".net", "network"},
  113.  
  114. /* europe --- many hits from many computers. sorted, a little */
  115.     {0, ".de", "germany"},
  116.     {0, ".uk", "united kingdom (.uk)"},
  117.     {0, ".fi", "finland"},
  118.     {0, ".nl", "netherlands"},
  119.     {0, ".se", "sweden"},
  120.     {0, ".no", "norway"},
  121.     {0, ".at", "austria"},
  122.     {0, ".be", "belgium"},
  123.     {0, ".ch", "switzerland"},
  124.     {0, ".dk", "denmark"},
  125.     {0, ".es", "spain"},
  126.     {0, ".fr", "france"},
  127.     {0, ".fx", "france, metropolitan"},
  128.     {0, ".gb", "united kingdom (.gb)"},
  129.     {0, ".gr", "greece"},
  130.     {0, ".ie", "ireland"},
  131.     {0, ".is", "iceland"},
  132.     {0, ".it", "italy"},
  133.     {0, ".pt", "portugal"},
  134.  
  135. /* places with computers */
  136.     {0, ".au", "australia"},
  137.     {0, ".il", "israel"},
  138.     {0, ".jp", "japan"},
  139.     {0, ".kr", "korea, south"},
  140.     {0, ".mx", "mexico"},
  141.     {0, ".nz", "new zealand"},
  142.     {0, ".sg", "singapore"},
  143.     {0, ".za", "south africa"},
  144.     {0, ".tw", "taiwan"},
  145.  
  146. /* more europe --- fewer hits, sorted a bit */
  147.     {0, ".pl", "poland"},
  148.     {0, ".ru", "russian federation"},
  149.     {0, ".si", "slovenia"},
  150.     {0, ".sk", "slovakia"},
  151.     {0, ".tr", "turkey"},
  152.     {0, ".ua", "ukraine"},
  153.     {0, ".al", "albania"},
  154.     {0, ".am", "armenia"},
  155.     {0, ".ba", "bosnia and herzegowina"},
  156.     {0, ".bg", "bulgaria"},
  157.     {0, ".cy", "cyprus"},
  158.     {0, ".cz", "czech republic"},
  159.     {0, ".ee", "estonia"},
  160.     {0, ".ge", "georgia"},
  161.     {0, ".hr", "croatia"},
  162.     {0, ".hu", "hungary"},
  163.     {0, ".li", "liechtenstein"},
  164.     {0, ".lt", "lithuania"},
  165.     {0, ".lu", "luxembourg"},
  166.     {0, ".lv", "latvia"},
  167.     {0, ".md", "moldovia"},
  168.     {0, ".ro", "romania"},
  169.     {0, ".yu", "yugoslavia"},
  170.  
  171. /* may have computers */
  172.     {0, ".cn", "china"},
  173.     {0, ".in", "india"},
  174.     {0, ".eg", "egypt"},
  175.     {0, ".ph", "philippines"},
  176.  
  177.  
  178. /* americas and carribean */
  179.     {0, ".br", "brazil"},
  180.     {0, ".ar", "argentina"},
  181.     {0, ".bo", "bolivia"},
  182.     {0, ".bz", "belize"},
  183.     {0, ".cl", "chile"},
  184.     {0, ".cu", "cuba"},
  185.     {0, ".do", "dominican republic"},
  186.     {0, ".ec", "ecuador"},
  187.     {0, ".gt", "guatemala"},
  188.     {0, ".ht", "haiti"},
  189.     {0, ".jm", "jamaica"},
  190.     {0, ".ng", "nigeria"},
  191.     {0, ".pe", "peru"},
  192.     {0, ".pr", "puerto rico"},
  193.     {0, ".sv", "el salvador"},
  194.     {0, ".uy", "uruguay"},
  195.  
  196.  
  197. /* not so likely to have computers, just alphabetized */
  198.     {0, ".af", "afghanistan"},
  199.     {0, ".dz", "algeria"},
  200.     {0, ".as", "american samoa"},
  201.     {0, ".ad", "andorra"},
  202.     {0, ".ao", "angola"},
  203.     {0, ".ai", "anguilla"},
  204.     {0, ".aq", "antarctica"},
  205.     {0, ".ag", "antigua and barbuda"},
  206.     {0, ".aw", "aruba"},
  207.     {0, ".az", "azerbaijan"},
  208.     {0, ".bs", "bahamas"},
  209.     {0, ".bh", "bahrain"},
  210.     {0, ".bd", "bangladesh"},
  211.     {0, ".bb", "barbados"},
  212.     {0, ".by", "belarus"},
  213.     {0, ".bj", "benin"},
  214.     {0, ".bm", "bermuda"},
  215.     {0, ".bt", "bhutan"},
  216.     {0, ".bo", "bolivia"},
  217.     {0, ".bw", "botswana"},
  218.     {0, ".bv", "bouvet island"},
  219.     {0, ".io", "british indian ocean territory"},
  220.     {0, ".bn", "brunei darussalam"},
  221.     {0, ".bf", "burkina faso"},
  222.     {0, ".bi", "burundi"},
  223.     {0, ".kh", "cambodia"},
  224.     {0, ".cm", "cameroon"},
  225.     {0, ".cv", "cape verde"},
  226.     {0, ".ky", "cayman islands"},
  227.     {0, ".cf", "central african republic"},
  228.     {0, ".td", "chad"},
  229.     {0, ".cx", "christmas island"},
  230.     {0, ".cc", "cocos islands"},
  231.     {0, ".co", "colombia"},
  232.     {0, ".km", "comoros"},
  233.     {0, ".cg", "congo"},
  234.     {0, ".ck", "cook islands"},
  235.     {0, ".cr", "costa rica"},
  236.     {0, ".ci", "cote d'ivoire"},
  237.     {0, ".dj", "djibouti"},
  238.     {0, ".dm", "dominica"},
  239.     {0, ".tp", "east timor"},
  240.     {0, ".gq", "equatorial guinea"},
  241.     {0, ".er", "eritrea"},
  242.     {0, ".et", "ethiopia"},
  243.     {0, ".fk", "falkland islands"},
  244.     {0, ".fo", "faroe islands"},
  245.     {0, ".fj", "fiji"},
  246.     {0, ".gf", "french guiana"},
  247.     {0, ".pf", "french polynesia"},
  248.     {0, ".tf", "french southern territories"},
  249.     {0, ".ga", "gabon"},
  250.     {0, ".gm", "gambia"},
  251.     {0, ".gh", "ghana"},
  252.     {0, ".gi", "gibraltar"},
  253.     {0, ".gl", "greenland"},
  254.     {0, ".gd", "grenada"},
  255.     {0, ".gp", "guadeloupe"},
  256.     {0, ".gu", "guam"},
  257.     {0, ".gn", "guinea"},
  258.     {0, ".gw", "guinea-bissau"},
  259.     {0, ".gy", "guyana"},
  260.     {0, ".hm", "heard and mcdonald islands"},
  261.     {0, ".hn", "honduras"},
  262.     {0, ".hk", "hong kong"},
  263.     {0, ".id", "indonesia"},
  264.     {0, ".ir", "iran"},
  265.     {0, ".iq", "iraq"},
  266.     {0, ".jo", "jordan"},
  267.     {0, ".kz", "kazakhstan"},
  268.     {0, ".ke", "kenya"},
  269.     {0, ".ki", "kiribati"},
  270.     {0, ".kp", "korea, north"},
  271.     {0, ".kw", "kuwait"},
  272.     {0, ".kg", "kyrgyzstan"},
  273.     {0, ".la", "laos"},
  274.     {0, ".lb", "lebanon"},
  275.     {0, ".ls", "lesotho"},
  276.     {0, ".lr", "liberia"},
  277.     {0, ".ly", "libya"},
  278.     {0, ".mo", "macau"},
  279.     {0, ".mk", "macedonia"},
  280.     {0, ".mg", "madagascar"},
  281.     {0, ".mw", "malawi"},
  282.     {0, ".my", "malaysia"},
  283.     {0, ".mv", "maldives"},
  284.     {0, ".ml", "mali"},
  285.     {0, ".mt", "malta"},
  286.     {0, ".mh", "marshall islands"},
  287.     {0, ".mq", "martinique"},
  288.     {0, ".mr", "mauritania"},
  289.     {0, ".mu", "mauritius"},
  290.     {0, ".yt", "mayotte"},
  291.     {0, ".fm", "micronesia"},
  292.     {0, ".mc", "monaco"},
  293.     {0, ".mn", "mongolia"},
  294.     {0, ".ms", "montserrat"},
  295.     {0, ".ma", "morocco"},
  296.     {0, ".mz", "mozambique"},
  297.     {0, ".mm", "myanmar"},
  298.     {0, ".na", "namibia"},
  299.     {0, ".nr", "nauru"},
  300.     {0, ".np", "nepal"},
  301.     {0, ".an", "netherlands antilles"},
  302.     {0, ".nc", "new caledonia"},
  303.     {0, ".ni", "nicaragua"},
  304.     {0, ".ne", "niger"},
  305.     {0, ".nu", "niue"},
  306.     {0, ".nf", "norfolk island"},
  307.     {0, ".mp", "northern mariana islands"},
  308.     {0, ".om", "oman"},
  309.     {0, ".pk", "pakistan"},
  310.     {0, ".pw", "palau"},
  311.     {0, ".pa", "panama"},
  312.     {0, ".pg", "papua new guinea"},
  313.     {0, ".py", "paraguay"},
  314.     {0, ".pn", "pitcairn"},
  315.     {0, ".qa", "qatar"},
  316.     {0, ".re", "reunion"},
  317.     {0, ".rw", "rwanda"},
  318.     {0, ".kn", "saint kitts and nevis"},
  319.     {0, ".lc", "saint lucia"},
  320.     {0, ".vc", "saint vincent and the grenadines"},
  321.     {0, ".ws", "samoa"},
  322.     {0, ".sm", "san marino"},
  323.     {0, ".st", "sao tome and principe"},
  324.     {0, ".sa", "saudi arabia"},
  325.     {0, ".sn", "senegal"},
  326.     {0, ".sc", "seychelles"},
  327.     {0, ".sl", "sierra leone"},
  328.     {0, ".sb", "solomon islands"},
  329.     {0, ".so", "somalia"},
  330.     {0, ".gs", "south georgia and the south sandwich islands"},
  331.     {0, ".lk", "sri lanka"},
  332.     {0, ".sh", "st. helena"},
  333.     {0, ".pm", "st. pierre and miquelon"},
  334.     {0, ".sd", "sudan"},
  335.     {0, ".sr", "suriname"},
  336.     {0, ".sj", "svalbard and jan mayen islands"},
  337.     {0, ".sz", "swaziland"},
  338.     {0, ".sy", "syria"},
  339.     {0, ".tj", "tajikistan"},
  340.     {0, ".tz", "tanzania"},
  341.     {0, ".th", "thailand"},
  342.     {0, ".tg", "togo"},
  343.     {0, ".tk", "tokelau"},
  344.     {0, ".to", "tonga"},
  345.     {0, ".tt", "trinidad and tobago"},
  346.     {0, ".tn", "tunisia"},
  347.     {0, ".tm", "turkmenistan"},
  348.     {0, ".tc", "turks and caicos islands"},
  349.     {0, ".tv", "tuvalu"},
  350.     {0, ".ug", "uganda"},
  351.     {0, ".ae", "united arab emirates"},
  352.     {0, ".um", "united states minor outlying islands"},
  353.     {0, ".uz", "uzbekistan"},
  354.     {0, ".vu", "vanuatu"},
  355.     {0, ".va", "vatican city"},
  356.     {0, ".ve", "venezuela"},
  357.     {0, ".vn", "viet nam"},
  358.     {0, ".vg", "virgin islands (british)"},
  359.     {0, ".vi", "virgin islands (u.s.)"},
  360.     {0, ".wf", "wallis and futuna islands"},
  361.     {0, ".eh", "western sahara"},
  362.     {0, ".ye", "yemen"},
  363.     {0, ".zr", "zaire"},
  364.     {0, ".zm", "zambia"},
  365.     {0, ".zw", "zimbabwe"},
  366. };
  367.  
  368. int day_anz = 7;
  369. struct dummy d[7] =
  370. {
  371.     {0, "Mon ", "mon"},
  372.     {0, "Tue ", "tue"},
  373.     {0, "Wed ", "wed"},
  374.     {0, "Thu ", "thu"},
  375.     {0, "Fri ", "fri"},
  376.     {0, "Sat ", "sat"},
  377.     {0, "Sun ", "sun"},
  378. };
  379.  
  380. int time_anz = 24;
  381. struct dummy t[24] =
  382. {
  383.     {0, " 00:", "00"},
  384.     {0, " 01:", "01"},
  385.     {0, " 02:", "02"},
  386.     {0, " 03:", "03"},
  387.     {0, " 04:", "04"},
  388.     {0, " 05:", "05"},
  389.     {0, " 06:", "06"},
  390.     {0, " 07:", "07"},
  391.     {0, " 08:", "08"},
  392.     {0, " 09:", "09"},
  393.     {0, " 10:", "10"},
  394.     {0, " 11:", "11"},
  395.     {0, " 12:", "12"},
  396.     {0, " 13:", "13"},
  397.     {0, " 14:", "14"},
  398.     {0, " 15:", "15"},
  399.     {0, " 16:", "16"},
  400.     {0, " 17:", "17"},
  401.     {0, " 18:", "18"},
  402.     {0, " 19:", "19"},
  403.     {0, " 20:", "20"},
  404.     {0, " 21:", "21"},
  405.     {0, " 22:", "22"},
  406.     {0, " 23:", "23"},
  407. };
  408.  
  409. char prg[256];
  410.  
  411.   struct cache {
  412.       int year;
  413.       int value;
  414.   };
  415.  
  416. struct cache ca =
  417. {0, 0};
  418.  
  419. /* prototypes */
  420. void main(int, char **);
  421. void ende(int, char *);
  422. void parse_cern(char *);
  423. int date2day(int, int, int);
  424. int sjahr(int);
  425. char *from_address(char *);
  426. int dummy_count_compare(void *, void *);
  427. int dummy_name_compare(void *, void *);
  428. int dummy_ext_compare(void *, void *);
  429. void sort_dummy_count(struct dummy *, int);
  430. void sort_dummy_ext(struct dummy *, int);
  431. void sort_dummy_name(struct dummy *, int);
  432.  
  433.  
  434.  
  435. void
  436. main(int argc, char *argv[])
  437. {
  438.     int anz = 0, i = 0, x;
  439.     double sonst = 0;
  440.     int minus_l = 0;
  441.     int minus_lt = 0;
  442.     int minus_s = 0;
  443.     double prozent;
  444.     char file[256];
  445.     char such[256];
  446.     char line[1024], site[1024], back[1024], date[1024], back1[1024];
  447.     /* char method[1024],file[1024],protocol[1024]; */
  448.     int country_anz = sizeof(c) / sizeof(struct dummy);
  449.     /* TCW */
  450.     char site_ext[32];        /* I doubt more than 6 are needed */
  451.     int ii;
  452.     char *cp;
  453.     int improved_count = 0, not_improved_count = 0;
  454.     int try_ext_matching;
  455.     int unknown_ext_found = 0;
  456.  
  457.     if (argc < 2) {
  458.     printf("USAGE: %s [-s <keyword>] [-l[t]] <logfile> \n", argv[0]);
  459.     }
  460.     else {
  461.     strcpy(prg, argv[0]);
  462.  
  463.     if (!strcmp(argv[1], "-s")) {
  464.         if (argc == 4) {
  465.         strcpy(such, argv[2]);
  466.         if (!strcmp(argv[2], "-l") || !strcmp(argv[2], "-lt"))
  467.             ende(1, "wrong arguments");
  468.         if (!strcmp(argv[3], "-l") || !strcmp(argv[3], "-lt"))
  469.             ende(1, "wrong arguments");
  470.         strcpy(file, argv[3]);
  471.         minus_s = 1;
  472.         }
  473.         else if (argc == 5) {
  474.         strcpy(such, argv[2]);
  475.         if (!strcmp(argv[2], "-l") || !strcmp(argv[2], "-lt"))
  476.             ende(1, "wrong arguments");
  477.         if (strcmp(argv[3], "-l") && strcmp(argv[3], "-lt"))
  478.             ende(1, "wrong arguments");
  479.         strcpy(file, argv[4]);
  480.         minus_s = 1;
  481.         if (!strcmp(argv[3], "-l")) {
  482.             minus_l = 1;
  483.         }
  484.         else
  485.             minus_lt = 1;
  486.  
  487.         }
  488.         else
  489.         ende(1, "wrong arguments");
  490.     }
  491.     else if (!strcmp(argv[1], "-l")) {
  492.         if (argc != 3)
  493.         ende(1, "wrong arguments");
  494.  
  495.         minus_l = 1;
  496.         strcpy(file, argv[2]);
  497.     }
  498.     else if (!strcmp(argv[1], "-lt")) {
  499.         if (argc != 3)
  500.         ende(1, "wrong arguments");
  501.  
  502.         minus_lt = 1;
  503.         strcpy(file, argv[2]);
  504.     }
  505.     else
  506.         strcpy(file, argv[1]);
  507.  
  508.  
  509.     if ((f = fopen(file, "r")) != NULL) {
  510.         char site_old[1024] = "";
  511.  
  512.         int first = 1;
  513.         int cern = 0;
  514.  
  515.         while (((fgets(line, 1024, f)) != NULL)) {
  516.         if (first) {
  517.             first = 0;
  518.             strcpy(back1, line);
  519.             if (strstr(back1, "- -") != NULL)
  520.             cern = 1;
  521.         }
  522.  
  523.         if (minus_s)
  524.             strcpy(back, line);
  525.  
  526.         i++;
  527.         /*fprintf(stderr,"%d\r",i);*/
  528.         strcpy(site, strtok(line, "["));
  529.         strcpy(date, strtok(NULL, "]"));
  530.         /*strcpy(method,strtok(NULL," "));
  531.                strcpy(file,strtok(NULL," "));
  532.                strcpy(protocol,strtok(NULL," \0\n")); */
  533.         /*TCW*/
  534.         /* strip trailing whitespace from site[] */
  535.         for (ii = (strlen(site) - 1); ii >= 0; --ii) {
  536.             if (isspace(site[ii]))
  537.             site[ii] = (char) 0;
  538.             else
  539.             break;
  540.         }
  541.         try_ext_matching = 1;
  542.         if (isdigit(site[strlen(site) - 1])) {    /* we are numberic */
  543.             /*printf("The old site is `%s'\t",site);*/
  544.             cp = from_address(site);
  545.             if (strcmp(cp, site)) {    /* ie, they are different */
  546.             strncpy(site, cp, 1024);
  547.             ++improved_count;
  548.             }
  549.             else {
  550.             ++not_improved_count;
  551.             try_ext_matching = 0;
  552.             }
  553.             /*printf("The new site is `%s'\n",site);*/
  554.         }
  555.  
  556.         if (try_ext_matching) {
  557.             /* find the extension of site, that is, the last .bit */
  558.             /* work backwords to find a '.' if not localhost*/
  559.             if (0 == strcmp(site, "localhost"))
  560.             strcpy(site_ext, "localhost");
  561.             else {
  562.             for (ii = (strlen(site) - 1); ii >= 0; --ii) {
  563.                 if ('.' == site[ii]) {
  564.                 cp = site + ii;
  565.                 break;
  566.                 }
  567.             }
  568.             strncpy(site_ext, cp, 32);
  569.             }
  570.             /*printf("The extension is `%s'\n",site_ext);*/
  571.         }
  572.  
  573.         if (minus_s) {
  574.             if (strstr(back, such) != NULL) {
  575.             if (minus_l) {
  576.                 int ext_found;
  577.  
  578.                 if (try_ext_matching) {
  579.                 ext_found = 0;
  580.                 for (x = 0; x < country_anz; x++) {
  581.                     if (0 == strcmp(site_ext, c[x].ext)) {
  582.                     (c[x].count)++;
  583.                     ext_found = 1;
  584.                     break;
  585.                     }
  586.                 }
  587.                 if (0 == ext_found)
  588.                     ++unknown_ext_found;
  589.                 /*fprintf(stderr, "New extension found: `%s'\n", site_ext);*/
  590.                 }
  591.             }
  592.             if (minus_lt) {
  593.                 if (cern == 0) {
  594.                 for (x = 0; x < day_anz; x++)
  595.                     if (strstr(date, d[x].ext) != NULL)
  596.                     (d[x].count)++;
  597.                 for (x = 0; x < time_anz; x++)
  598.                     if (strstr(date, t[x].ext) != NULL)
  599.                     (t[x].count)++;
  600.                 }
  601.                 else
  602.                 parse_cern(date);
  603.             }
  604.             anz++;
  605.             }
  606.         }
  607.         else {
  608.             if (minus_l) {
  609.             int ext_found;
  610.  
  611.             if (try_ext_matching) {
  612.                 ext_found = 0;
  613.                 for (x = 0; x < country_anz; x++) {
  614.                 if (0 == strcmp(site_ext, c[x].ext)) {
  615.                     (c[x].count)++;
  616.                     ext_found = 1;
  617.                     break;
  618.                 }
  619.                 }
  620.                 if (0 == ext_found)
  621.                 ++unknown_ext_found;
  622.                 /*fprintf(stderr, "New extension found: `%s'\n", site_ext);*/
  623.             }
  624.             }
  625.  
  626.             if (minus_lt) {
  627.             if (cern == 0) {
  628.                 for (x = 0; x < day_anz; x++)
  629.                 if (strstr(date, d[x].ext) != NULL)
  630.                     (d[x].count)++;
  631.                 for (x = 0; x < time_anz; x++)
  632.                 if (strstr(date, t[x].ext) != NULL)
  633.                     (t[x].count)++;
  634.             }
  635.             else
  636.                 parse_cern(date);
  637.             }
  638.             if (strcmp(site, site_old) != 0)
  639.             anz++;
  640.         }
  641.  
  642.         if (!minus_s)
  643.             strcpy(site_old, site);
  644.         }
  645.  
  646.         fclose(f);
  647.  
  648.         if (minus_s) {
  649.         printf("searching for: %s\n\n", such);
  650.         printf("access: %d/%d  %8.4f %%\n", anz, i, (double) anz * (double) 100 / (double) i);
  651.         }
  652.         else
  653.         printf("access: %d/%d\n", anz, i);
  654.         if (minus_l) {
  655.         if (i == 0)
  656.             ende(2, "logfile wrong");
  657.  
  658.         printf("\n");
  659.         sort_dummy_count(c, country_anz);
  660.         for (x = 0; x < country_anz; x++)
  661.             if (c[x].count) {
  662.             if (!minus_s) {
  663.                 prozent = (double) c[x].count * (double) 100 / (double) i;
  664.             }
  665.             else {
  666.                 prozent = (double) c[x].count * (double) 100 / (double) anz;
  667.             }
  668.  
  669.             if (prozent > 0.001)
  670.                 printf("%6.2f %% : %s\n", prozent, c[x].name);
  671.             sonst = sonst + prozent;
  672.             }
  673.         prozent = (double) 100 - sonst;
  674.  
  675.         if (prozent > 0.001)
  676.             printf("\n%6.2f %% : others\n", prozent);
  677.         printf("%d of %d numeric IP addresses improved.\n",
  678.           improved_count, (improved_count + not_improved_count));
  679.         if (unknown_ext_found > 0)
  680.             printf("Found unknown non-numeric extensions %d times.\n",
  681.                unknown_ext_found);
  682.  
  683.         }
  684.         if (minus_lt) {
  685.         if (i == 0)
  686.             ende(2, "logfile wrong");
  687.  
  688.         printf("\n");
  689.  
  690.         for (x = 0; x < day_anz; x++)
  691.             if (d[x].count) {
  692.             if (!minus_s) {
  693.                 prozent = (double) d[x].count * (double) 100 / (double) i;
  694.             }
  695.             else {
  696.                 prozent = (double) d[x].count * (double) 100 / (double) anz;
  697.             }
  698.  
  699.             if (prozent > 0.009)
  700.                 printf("%s: %6.2f %%\n", d[x].name, prozent);
  701.             }
  702.         printf("\n");
  703.         for (x = 0; x < time_anz; x++)
  704.             if (t[x].count) {
  705.             if (!minus_s) {
  706.                 prozent = (double) t[x].count * (double) 100 / (double) i;
  707.             }
  708.             else {
  709.                 prozent = (double) t[x].count * (double) 100 / (double) anz;
  710.             }
  711.  
  712.             if (prozent > 0.009)
  713.                 printf("%s: %6.2f %%\n", t[x].name, prozent);
  714.             }
  715.         }
  716.     }
  717.     else
  718.         ende(5, "can´t open logfile");
  719.  
  720.     ende(0, "");
  721.     }
  722. }
  723.  
  724. void
  725. ende(int n, char *end)
  726. {
  727.     if (f)
  728.     fclose(f);
  729.  
  730.     if (strcmp(end, "") != 0)
  731.     printf("%s: %s !\n", &prg, end);
  732.     exit(n);
  733. }
  734.  
  735. void
  736. parse_cern(char *dd)
  737. {
  738.     char date[1024], hour[10];
  739.     char da[3], mo[4], yea[5];
  740.  
  741.     int h, x;
  742.     int day, mon, year;
  743.  
  744.     strcpy(date, strtok(dd, ":"));
  745.     strcpy(hour, strtok(NULL, ":"));
  746.  
  747.     h = atoi(hour);
  748.  
  749.     for (x = 0; x < time_anz; x++)
  750.     if (h == x)
  751.         (t[x].count)++;
  752.  
  753.     strcpy(da, strtok(date, "/"));
  754.     strcpy(mo, strtok(NULL, "/"));
  755.     strcpy(yea, strtok(NULL, "\0"));
  756.  
  757.     day = atoi(da);
  758.  
  759.     if (!strcmp(mo, "Jan"))
  760.     mon = 1;
  761.     if (!strcmp(mo, "Feb"))
  762.     mon = 2;
  763.     if (!strcmp(mo, "Mar"))
  764.     mon = 3;
  765.     if (!strcmp(mo, "Apr"))
  766.     mon = 4;
  767.     if (!strcmp(mo, "May"))
  768.     mon = 5;
  769.     if (!strcmp(mo, "Jun"))
  770.     mon = 6;
  771.     if (!strcmp(mo, "Jul"))
  772.     mon = 7;
  773.     if (!strcmp(mo, "Aug"))
  774.     mon = 8;
  775.     if (!strcmp(mo, "Sep"))
  776.     mon = 9;
  777.     if (!strcmp(mo, "Oct"))
  778.     mon = 10;
  779.     if (!strcmp(mo, "Nov"))
  780.     mon = 11;
  781.     if (!strcmp(mo, "Dec"))
  782.     mon = 12;
  783.  
  784.     year = atoi(yea);
  785.  
  786.     h = date2day(day, mon, year);
  787.  
  788.     if (h != 0)
  789.     for (x = 0; x < day_anz; x++)
  790.         if (h == (x + 1))
  791.         (d[x].count)++;
  792. }
  793.  
  794. /* Updated routine */
  795. /*  date2day
  796.     (c) Armin.Obersteiner@giga.or.at
  797.  
  798.     input: <int> day,month,year
  799.     output:<int> 0,1-7
  800.  
  801.     0: error (before 1.1.1500 - this should be enough)
  802.  
  803.     1-7: Monday-Sunday
  804. */
  805.  
  806. int 
  807. date2day(int day, int month, int year)
  808. {
  809.     int md[12] =
  810.     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  811.  
  812.     int i;
  813.     int tag = 0;
  814.     int s;
  815.  
  816.     if (year < 1500)
  817.     return 0;
  818.     if ((month < 1) || (month > 12))
  819.     return 0;
  820.     if (day < 1)
  821.     return 0;
  822.  
  823.     s = sjahr(year);
  824.  
  825.     if ((day > md[month - 1])) {
  826.     if (!s)
  827.         return 0;
  828.     if ((s) && (month = 2) && (day > 29))
  829.         return 0;
  830.     }
  831.  
  832.     for (i = 1; i < month; i++)
  833.     tag = tag + md[i - 1];
  834.     if (s && (month > 2))
  835.     tag = tag + 1;
  836.  
  837.     tag = tag + day + year + (year / 4) - (year / 100) + (year / 400);
  838.     if (s)
  839.     tag--;
  840.  
  841.     return (((tag - 2) % 7) + 1);
  842. }
  843.  
  844. /* Updated routine */
  845. /*  sjahr
  846.     (c) Armin.Obersteiner@giga.or.at
  847.  
  848.     input:  <int> year
  849.     output: <int> 0,1
  850.  
  851.     0: normal year
  852.     1: leap-year
  853. */
  854.  
  855. int 
  856. sjahr(int year)
  857. {
  858.     int schalt = 0;
  859.  
  860.     if ((year % 4) == 0)
  861.     schalt = 1;
  862.     if ((year % 100) == 0)
  863.     if ((year % 400) != 0)
  864.         schalt = 0;
  865.  
  866.     return schalt;
  867. }
  868.  
  869. extern struct hostent *gethostbyaddr();
  870.  
  871. char *
  872. from_address(char *astring)
  873. {
  874.     unsigned long addr;        /* address in host order */
  875.     struct hostent *host;    /* structure returned by gethostbyaddr() */
  876.  
  877.     /* parse string into address */
  878.     if ((addr = inet_addr(astring)) == -1) {
  879.     /*fprintf(stderr, "%s is not a valid address\n", astring) ;*/
  880.     return astring;
  881.     }
  882.  
  883.     /* try to find hostentry, caddr_t defined in sys/types.h */
  884.     if ((host = (struct hostent *) gethostbyaddr((caddr_t) & addr, sizeof(addr), AF_INET)) == NULL) {
  885.     return astring;
  886.     }
  887.     else {
  888.     return (host->h_name);
  889.     }
  890. }
  891.  
  892. int
  893. dummy_count_compare(void *d1, void *d2)
  894. {
  895.     int v1 = ((struct dummy *) d1)->count;
  896.     int v2 = ((struct dummy *) d2)->count;
  897.  
  898.     return ((v1 < v2) ? -1 : ((v1 > v2) ? 1 : 0));
  899. }
  900.  
  901. int
  902. dummy_name_compare(void *d1, void *d2)
  903. {
  904.     char *v1 = ((struct dummy *) d1)->name;
  905.     char *v2 = ((struct dummy *) d2)->name;
  906.     int retval;
  907.  
  908.     retval = strcmp(v1, v2);
  909.     if (retval < 0) {
  910.     return -1;
  911.     }
  912.     else {
  913.     if (retval > 0) {
  914.         return 1;
  915.     }
  916.     else {
  917.         return 0;
  918.     }
  919.     }
  920. }
  921.  
  922. int
  923. dummy_ext_compare(void *d1, void *d2)
  924. {
  925.     char *v1 = ((struct dummy *) d1)->ext;
  926.     char *v2 = ((struct dummy *) d2)->ext;
  927.     int retval;
  928.  
  929.     retval = strcmp(v1, v2);
  930.     if (retval < 0) {
  931.     return -1;
  932.     }
  933.     else {
  934.     if (retval > 0) {
  935.         return 1;
  936.     }
  937.     else {
  938.         return 0;
  939.     }
  940.     }
  941. }
  942.  
  943.  
  944.  
  945. void
  946. sort_dummy_count(struct dummy *d, int size)
  947. {
  948.     qsort((void *) d, (size_t) size, sizeof(struct dummy), dummy_count_compare);
  949. }
  950.  
  951. #if ACTUALLY_USED
  952.  
  953. void
  954. sort_dummy_ext(struct dummy *d, int size)
  955. {
  956.     qsort((void *) d, (size_t) size, sizeof(struct dummy),
  957.       dummy_ext_compare);
  958. }
  959.  
  960. void
  961. sort_dummy_name(struct dummy *d, int size)
  962. {
  963.     qsort((void *) d, (size_t) size, sizeof(struct dummy),
  964.       dummy_name_compare);
  965. }
  966.  
  967. #endif                /* ACTUALLY_USED */
  968.