/[jscoverage]/trunk/jscoverage-server.c
ViewVC logotype

Diff of /trunk/jscoverage-server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 133 by siliconforks, Thu Jun 19 05:53:29 2008 UTC revision 275 by siliconforks, Sat Oct 11 22:38:05 2008 UTC
# Line 22  Line 22 
22  #include <assert.h>  #include <assert.h>
23  #include <ctype.h>  #include <ctype.h>
24  #include <signal.h>  #include <signal.h>
25    #include <stdint.h>
26  #include <string.h>  #include <string.h>
27    
28  #include <dirent.h>  #include <dirent.h>
# Line 29  Line 30 
30  #include <pthread.h>  #include <pthread.h>
31  #endif  #endif
32    
33    #include "encoding.h"
34    #include "global.h"
35  #include "http-server.h"  #include "http-server.h"
36  #include "instrument-js.h"  #include "instrument-js.h"
37  #include "resource-manager.h"  #include "resource-manager.h"
38  #include "stream.h"  #include "stream.h"
39  #include "util.h"  #include "util.h"
40    
41    const char * jscoverage_encoding = "ISO-8859-1";
42    bool jscoverage_highlight = true;
43    
44  typedef struct SourceCache {  typedef struct SourceCache {
45    char * url;    char * url;
46    Stream * source;    uint16_t * characters;
47      size_t num_characters;
48    struct SourceCache * next;    struct SourceCache * next;
49  } SourceCache;  } SourceCache;
50    
# Line 78  Line 85 
85  #define UNLOCK pthread_mutex_unlock  #define UNLOCK pthread_mutex_unlock
86  #endif  #endif
87    
88  static Stream * find_cached_source(const char * url) {  static const SourceCache * find_cached_source(const char * url) {
89    Stream * result = NULL;    SourceCache * result = NULL;
90    LOCK(&source_cache_mutex);    LOCK(&source_cache_mutex);
91    for (SourceCache * p = source_cache; p != NULL; p = p->next) {    for (SourceCache * p = source_cache; p != NULL; p = p->next) {
92      if (strcmp(url, p->url) == 0) {      if (strcmp(url, p->url) == 0) {
93        result = p->source;        result = p;
94        break;        break;
95      }      }
96    }    }
# Line 91  Line 98 
98    return result;    return result;
99  }  }
100    
101  static void add_cached_source(const char * url, Stream * source) {  static void add_cached_source(const char * url, uint16_t * characters, size_t num_characters) {
102    SourceCache * new_source_cache = xmalloc(sizeof(SourceCache));    SourceCache * new_source_cache = xmalloc(sizeof(SourceCache));
103    new_source_cache->url = xstrdup(url);    new_source_cache->url = xstrdup(url);
104    new_source_cache->source = source;    new_source_cache->characters = characters;
105      new_source_cache->num_characters = num_characters;
106    LOCK(&source_cache_mutex);    LOCK(&source_cache_mutex);
107    new_source_cache->next = source_cache;    new_source_cache->next = source_cache;
108    source_cache = new_source_cache;    source_cache = new_source_cache;
109    UNLOCK(&source_cache_mutex);    UNLOCK(&source_cache_mutex);
110  }  }
111    
112  static int get(const char * url, Stream * stream) __attribute__((warn_unused_result));  static int get(const char * url, uint16_t ** characters, size_t * num_characters) __attribute__((warn_unused_result));
113    
114  static int get(const char * url, Stream * stream) {  static int get(const char * url, uint16_t ** characters, size_t * num_characters) {
115    char * host = NULL;    char * host = NULL;
116    uint16_t port;    uint16_t port;
117    char * abs_path = NULL;    char * abs_path = NULL;
118    char * query = NULL;    char * query = NULL;
119    HTTPConnection * connection = NULL;    HTTPConnection * connection = NULL;
120    HTTPExchange * exchange = NULL;    HTTPExchange * exchange = NULL;
121      Stream * stream = NULL;
122    
123    int result = URL_parse(url, &host, &port, &abs_path, &query);    int result = URL_parse(url, &host, &port, &abs_path, &query);
124    if (result != 0) {    if (result != 0) {
# Line 134  Line 143 
143      goto done;      goto done;
144    }    }
145    
146      stream = Stream_new(0);
147    result = HTTPExchange_read_entire_response_entity_body(exchange, stream);    result = HTTPExchange_read_entire_response_entity_body(exchange, stream);
148    if (result != 0) {    if (result != 0) {
149      goto done;      goto done;
150    }    }
151      char * encoding = HTTPMessage_get_charset(HTTPExchange_get_response_message(exchange));
152      if (encoding == NULL) {
153        encoding = xstrdup(jscoverage_encoding);
154      }
155      result = jscoverage_bytes_to_characters(encoding, stream->data, stream->length, characters, num_characters);
156      free(encoding);
157      if (result != 0) {
158        goto done;
159      }
160    
161    result = 0;    result = 0;
162    
163  done:  done:
164      if (stream != NULL) {
165        Stream_delete(stream);
166      }
167    if (exchange != NULL) {    if (exchange != NULL) {
168      HTTPExchange_delete(exchange);      HTTPExchange_delete(exchange);
169    }    }
# Line 215  Line 237 
237    return result;    return result;
238  }  }
239    
240    static unsigned int hex_value(char c) {
241      if ('0' <= c && c <= '9') {
242        return c - '0';
243      }
244      else if ('A' <= c && c <= 'F') {
245        return c - 'A' + 10;
246      }
247      else if ('a' <= c && c <= 'f') {
248        return c - 'a' + 10;
249      }
250      else {
251        return 0;
252      }
253    }
254    
255    static char * decode_uri_component(const char * s) {
256      size_t length = strlen(s);
257      char * result = xmalloc(length + 1);
258      char * p = result;
259      while (*s != '\0') {
260        if (*s == '%') {
261          if (s[1] == '\0' || s[2] == '\0') {
262            *p = '\0';
263            return result;
264          }
265          *p = hex_value(s[1]) * 16 + hex_value(s[2]);
266          s += 2;
267        }
268        else {
269          *p = *s;
270        }
271        p++;
272        s++;
273      }
274      *p = '\0';
275      return result;
276    }
277    
278  static const char * get_entity(char c) {  static const char * get_entity(char c) {
279    switch(c) {    switch(c) {
280    case '<':    case '<':
# Line 400  Line 460 
460    putc('"', f);    putc('"', f);
461  }  }
462    
463    static void write_source(const char * id, const uint16_t * characters, size_t num_characters, FILE * f) {
464      Stream * output = Stream_new(num_characters);
465      jscoverage_write_source(id, characters, num_characters, output);
466      fwrite(output->data, 1, output->length, f);
467      Stream_delete(output);
468    }
469    
470  static void write_json_for_file(const FileCoverage * file_coverage, int i, void * p) {  static void write_json_for_file(const FileCoverage * file_coverage, int i, void * p) {
471    FILE * f = p;    FILE * f = p;
472    
# Line 410  Line 477 
477    write_js_quoted_string(f, file_coverage->id, strlen(file_coverage->id));    write_js_quoted_string(f, file_coverage->id, strlen(file_coverage->id));
478    
479    fputs(":{\"coverage\":[", f);    fputs(":{\"coverage\":[", f);
480    for (uint32_t i = 0; i <= file_coverage->num_lines; i++) {    for (uint32_t i = 0; i < file_coverage->num_coverage_lines; i++) {
481      if (i > 0) {      if (i > 0) {
482        putc(',', f);        putc(',', f);
483      }      }
484      int timesExecuted = file_coverage->lines[i];      int timesExecuted = file_coverage->coverage_lines[i];
485      if (timesExecuted < 0) {      if (timesExecuted < 0) {
486        fputs("null", f);        fputs("null", f);
487      }      }
# Line 423  Line 490 
490      }      }
491    }    }
492    fputs("],\"source\":", f);    fputs("],\"source\":", f);
493    if (file_coverage->source == NULL) {    if (file_coverage->source_lines == NULL) {
494      if (proxy) {      if (proxy) {
495        Stream * stream = find_cached_source(file_coverage->id);        const SourceCache * cached = find_cached_source(file_coverage->id);
496        if (stream == NULL) {        if (cached == NULL) {
497          stream = Stream_new(0);          uint16_t * characters;
498          if (get(file_coverage->id, stream) == 0) {          size_t num_characters;
499            write_js_quoted_string(f, stream->data, stream->length);          if (get(file_coverage->id, &characters, &num_characters) == 0) {
500            add_cached_source(file_coverage->id, stream);            write_source(file_coverage->id, characters, num_characters, f);
501              add_cached_source(file_coverage->id, characters, num_characters);
502          }          }
503          else {          else {
504            fputs("\"\"", f);            fputs("[]", f);
505            HTTPServer_log_err("Warning: cannot retrieve URL: %s\n", file_coverage->id);            HTTPServer_log_err("Warning: cannot retrieve URL: %s\n", file_coverage->id);
           Stream_delete(stream);  
506          }          }
507        }        }
508        else {        else {
509          write_js_quoted_string(f, stream->data, stream->length);          write_source(file_coverage->id, cached->characters, cached->num_characters, f);
510        }        }
511      }      }
512      else {      else {
# Line 449  Line 516 
516          FILE * source_file = fopen(source_path, "rb");          FILE * source_file = fopen(source_path, "rb");
517          free(source_path);          free(source_path);
518          if (source_file == NULL) {          if (source_file == NULL) {
519            fputs("\"\"", f);            fputs("[]", f);
520            HTTPServer_log_err("Warning: cannot open file: %s\n", file_coverage->id);            HTTPServer_log_err("Warning: cannot open file: %s\n", file_coverage->id);
521          }          }
522          else {          else {
523            Stream * stream = Stream_new(0);            Stream * stream = Stream_new(0);
524            Stream_write_file_contents(stream, source_file);            Stream_write_file_contents(stream, source_file);
525            fclose(source_file);            fclose(source_file);
526            write_js_quoted_string(f, stream->data, stream->length);            uint16_t * characters;
527              size_t num_characters;
528              int result = jscoverage_bytes_to_characters(jscoverage_encoding, stream->data, stream->length, &characters, &num_characters);
529            Stream_delete(stream);            Stream_delete(stream);
530              if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {
531                fputs("[]", f);
532                HTTPServer_log_err("Warning: encoding %s not supported\n", jscoverage_encoding);
533              }
534              else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {
535                fputs("[]", f);
536                HTTPServer_log_err("Warning: error decoding %s in file %s\n", jscoverage_encoding, file_coverage->id);
537              }
538              else {
539                write_source(file_coverage->id, characters, num_characters, f);
540                free(characters);
541              }
542          }          }
543        }        }
544        else {        else {
545          /* path does not begin with / */          /* path does not begin with / */
546          fputs("\"\"", f);          fputs("[]", f);
547          HTTPServer_log_err("Warning: invalid source path: %s\n", file_coverage->id);          HTTPServer_log_err("Warning: invalid source path: %s\n", file_coverage->id);
548        }        }
549      }      }
550    }    }
551    else {    else {
552      write_js_quoted_string(f, file_coverage->source, strlen(file_coverage->source));      fputc('[', f);
553        for (uint32_t i = 0; i < file_coverage->num_source_lines; i++) {
554          if (i > 0) {
555            fputc(',', f);
556          }
557          char * source_line = file_coverage->source_lines[i];
558          write_js_quoted_string(f, source_line, strlen(source_line));
559        }
560        fputc(']', f);
561    }    }
562    fputc('}', f);    fputc('}', f);
563  }  }
# Line 477  Line 566 
566    
567  static int write_json(Coverage * coverage, const char * path) {  static int write_json(Coverage * coverage, const char * path) {
568    /* write the JSON */    /* write the JSON */
569    FILE * f = fopen(path, "w");    FILE * f = fopen(path, "wb");
570    if (f == NULL) {    if (f == NULL) {
571      return -1;      return -1;
572    }    }
# Line 525  Line 614 
614      }      }
615    
616      mkdir_if_necessary(report_directory);      mkdir_if_necessary(report_directory);
617      char * path = make_path(report_directory, "jscoverage.json");      char * current_report_directory;
618        if (str_starts_with(abs_path, "/jscoverage-store/") && abs_path[18] != '\0') {
619          char * dir = decode_uri_component(abs_path + 18);
620          current_report_directory = make_path(report_directory, dir);
621          free(dir);
622        }
623        else {
624          current_report_directory = xstrdup(report_directory);
625        }
626        mkdir_if_necessary(current_report_directory);
627        char * path = make_path(current_report_directory, "jscoverage.json");
628    
629      /* check if the JSON file exists */      /* check if the JSON file exists */
630      struct stat buf;      struct stat buf;
631      if (stat(path, &buf) == 0) {      if (stat(path, &buf) == 0) {
632        /* it exists: merge */        /* it exists: merge */
633        FILE * f = fopen(path, "r");        FILE * f = fopen(path, "rb");
634        if (f == NULL) {        if (f == NULL) {
635          result = 1;          result = 1;
636        }        }
# Line 542  Line 641 
641          }          }
642        }        }
643        if (result != 0) {        if (result != 0) {
644            free(current_report_directory);
645          free(path);          free(path);
646          Coverage_delete(coverage);          Coverage_delete(coverage);
647          send_response(exchange, 500, "Could not merge with existing coverage data\n");          send_response(exchange, 500, "Could not merge with existing coverage data\n");
# Line 553  Line 653 
653      free(path);      free(path);
654      Coverage_delete(coverage);      Coverage_delete(coverage);
655      if (result != 0) {      if (result != 0) {
656          free(current_report_directory);
657        send_response(exchange, 500, "Could not write coverage data\n");        send_response(exchange, 500, "Could not write coverage data\n");
658        return;        return;
659      }      }
660    
661      /* copy other files */      /* copy other files */
662      jscoverage_copy_resources(report_directory);      jscoverage_copy_resources(current_report_directory);
663      path = make_path(report_directory, "jscoverage.js");      path = make_path(current_report_directory, "jscoverage.js");
664        free(current_report_directory);
665      FILE * f = fopen(path, "ab");      FILE * f = fopen(path, "ab");
666      free(path);      free(path);
667      if (f == NULL) {      if (f == NULL) {
# Line 616  Line 718 
718    }    }
719  }  }
720    
721  static void instrument_js(const char * id, Stream * input_stream, Stream * output_stream) {  static void instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output_stream) {
   LOCK(&javascript_mutex);  
   jscoverage_instrument_js(id, input_stream, output_stream);  
   UNLOCK(&javascript_mutex);  
   
722    const struct Resource * resource = get_resource("report.js");    const struct Resource * resource = get_resource("report.js");
723    Stream_write(output_stream, resource->data, resource->length);    Stream_write(output_stream, resource->data, resource->length);
724    
725      LOCK(&javascript_mutex);
726      jscoverage_instrument_js(id, characters, num_characters, output_stream);
727      UNLOCK(&javascript_mutex);
728  }  }
729    
730  static bool is_hop_by_hop_header(const char * h) {  static bool is_hop_by_hop_header(const char * h) {
# Line 740  Line 842 
842      }      }
843    
844      const char * request_uri = HTTPExchange_get_request_uri(client_exchange);      const char * request_uri = HTTPExchange_get_request_uri(client_exchange);
845        char * encoding = HTTPMessage_get_charset(HTTPExchange_get_response_message(server_exchange));
846        if (encoding == NULL) {
847          encoding = xstrdup(jscoverage_encoding);
848        }
849        uint16_t * characters;
850        size_t num_characters;
851        int result = jscoverage_bytes_to_characters(encoding, input_stream->data, input_stream->length, &characters, &num_characters);
852        free(encoding);
853        Stream_delete(input_stream);
854        if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {
855          send_response(client_exchange, 502, "Encoding not supported\n");
856          goto done;
857        }
858        else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {
859          send_response(client_exchange, 502, "Error decoding response\n");
860          goto done;
861        }
862    
863      Stream * output_stream = Stream_new(0);      Stream * output_stream = Stream_new(0);
864      instrument_js(request_uri, input_stream, output_stream);      instrument_js(request_uri, characters, num_characters, output_stream);
865    
866      /* send the headers to the client */      /* send the headers to the client */
867      for (const HTTPHeader * h = HTTPExchange_get_response_headers(server_exchange); h != NULL; h = h->next) {      for (const HTTPHeader * h = HTTPExchange_get_response_headers(server_exchange); h != NULL; h = h->next) {
# Line 758  Line 878 
878        HTTPServer_log_err("Warning: error writing to client\n");        HTTPServer_log_err("Warning: error writing to client\n");
879      }      }
880    
881      /* input_stream goes on the cache */      /* characters go on the cache */
882      /*      /*
883      Stream_delete(input_stream);      free(characters);
884      */      */
885      Stream_delete(output_stream);      Stream_delete(output_stream);
886      add_cached_source(request_uri, input_stream);      add_cached_source(request_uri, characters, num_characters);
887    }    }
888    else {    else {
889      /* does not need instrumentation */      /* does not need instrumentation */
# Line 811  Line 931 
931    /* add the `Server' response-header (RFC 2616 14.38, 3.8) */    /* add the `Server' response-header (RFC 2616 14.38, 3.8) */
932    HTTPExchange_add_response_header(exchange, HTTP_SERVER, "jscoverage-server/" VERSION);    HTTPExchange_add_response_header(exchange, HTTP_SERVER, "jscoverage-server/" VERSION);
933    
934      char * decoded_path = NULL;
935    char * filesystem_path = NULL;    char * filesystem_path = NULL;
936    
937    const char * abs_path = HTTPExchange_get_abs_path(exchange);    const char * abs_path = HTTPExchange_get_abs_path(exchange);
938    assert(*abs_path != '\0');    assert(*abs_path != '\0');
939    
940    if (str_starts_with(abs_path, "/jscoverage")) {    decoded_path = decode_uri_component(abs_path);
941    
942      if (str_starts_with(decoded_path, "/jscoverage")) {
943      handle_jscoverage_request(exchange);      handle_jscoverage_request(exchange);
944      goto done;      goto done;
945    }    }
946    
947    if (strstr(abs_path, "..") != NULL) {    if (strstr(decoded_path, "..") != NULL) {
948      send_response(exchange, 403, "Forbidden\n");      send_response(exchange, 403, "Forbidden\n");
949      goto done;      goto done;
950    }    }
951    
952    filesystem_path = make_path(document_root, abs_path + 1);    filesystem_path = make_path(document_root, decoded_path + 1);
953    size_t filesystem_path_length = strlen(filesystem_path);    size_t filesystem_path_length = strlen(filesystem_path);
954    if (filesystem_path_length > 0 && filesystem_path[filesystem_path_length - 1] == '/') {    if (filesystem_path_length > 0 && filesystem_path[filesystem_path_length - 1] == '/') {
955      /* stat on Windows doesn't work with trailing slash */      /* stat on Windows doesn't work with trailing slash */
# Line 883  Line 1006 
1006    
1007      const char * content_type = get_content_type(filesystem_path);      const char * content_type = get_content_type(filesystem_path);
1008      HTTPExchange_set_response_header(exchange, HTTP_CONTENT_TYPE, content_type);      HTTPExchange_set_response_header(exchange, HTTP_CONTENT_TYPE, content_type);
1009      const char * request_uri = HTTPExchange_get_request_uri(exchange);      if (strcmp(content_type, "text/javascript") == 0 && ! is_no_instrument(abs_path)) {
     if (strcmp(content_type, "text/javascript") == 0 && ! is_no_instrument(request_uri)) {  
1010        Stream * input_stream = Stream_new(0);        Stream * input_stream = Stream_new(0);
       Stream * output_stream = Stream_new(0);  
   
1011        Stream_write_file_contents(input_stream, f);        Stream_write_file_contents(input_stream, f);
1012    
1013        instrument_js(request_uri, input_stream, output_stream);        uint16_t * characters;
1014          size_t num_characters;
1015          int result = jscoverage_bytes_to_characters(jscoverage_encoding, input_stream->data, input_stream->length, &characters, &num_characters);
1016          Stream_delete(input_stream);
1017    
1018          if (result == JSCOVERAGE_ERROR_ENCODING_NOT_SUPPORTED) {
1019            send_response(exchange, 500, "Encoding not supported\n");
1020            goto done;
1021          }
1022          else if (result == JSCOVERAGE_ERROR_INVALID_BYTE_SEQUENCE) {
1023            send_response(exchange, 500, "Error decoding JavaScript file\n");
1024            goto done;
1025          }
1026    
1027          Stream * output_stream = Stream_new(0);
1028          instrument_js(abs_path, characters, num_characters, output_stream);
1029          free(characters);
1030    
1031        if (HTTPExchange_write_response(exchange, output_stream->data, output_stream->length) != 0) {        if (HTTPExchange_write_response(exchange, output_stream->data, output_stream->length) != 0) {
1032          HTTPServer_log_err("Warning: error writing to client\n");          HTTPServer_log_err("Warning: error writing to client\n");
1033        }        }
   
       Stream_delete(input_stream);  
1034        Stream_delete(output_stream);        Stream_delete(output_stream);
1035      }      }
1036      else {      else {
# Line 917  Line 1051 
1051    
1052  done:  done:
1053    free(filesystem_path);    free(filesystem_path);
1054      free(decoded_path);
1055  }  }
1056    
1057  static void handler(HTTPExchange * exchange) {  static void handler(HTTPExchange * exchange) {
# Line 957  Line 1092 
1092      else if (strcmp(argv[i], "--report-dir") == 0) {      else if (strcmp(argv[i], "--report-dir") == 0) {
1093        i++;        i++;
1094        if (i == argc) {        if (i == argc) {
1095          fatal("--report-dir: option requires an argument");          fatal_command_line("--report-dir: option requires an argument");
1096        }        }
1097        report_directory = argv[i];        report_directory = argv[i];
1098      }      }
# Line 968  Line 1103 
1103      else if (strcmp(argv[i], "--document-root") == 0) {      else if (strcmp(argv[i], "--document-root") == 0) {
1104        i++;        i++;
1105        if (i == argc) {        if (i == argc) {
1106          fatal("--document-root: option requires an argument");          fatal_command_line("--document-root: option requires an argument");
1107        }        }
1108        document_root = argv[i];        document_root = argv[i];
1109      }      }
# Line 976  Line 1111 
1111        document_root = argv[i] + 16;        document_root = argv[i] + 16;
1112      }      }
1113    
1114        else if (strcmp(argv[i], "--encoding") == 0) {
1115          i++;
1116          if (i == argc) {
1117            fatal_command_line("--encoding: option requires an argument");
1118          }
1119          jscoverage_encoding = argv[i];
1120        }
1121        else if (strncmp(argv[i], "--encoding=", 11) == 0) {
1122          jscoverage_encoding = argv[i] + 11;
1123        }
1124    
1125      else if (strcmp(argv[i], "--ip-address") == 0) {      else if (strcmp(argv[i], "--ip-address") == 0) {
1126        i++;        i++;
1127        if (i == argc) {        if (i == argc) {
1128          fatal("--ip-address: option requires an argument");          fatal_command_line("--ip-address: option requires an argument");
1129        }        }
1130        ip_address = argv[i];        ip_address = argv[i];
1131      }      }
# Line 987  Line 1133 
1133        ip_address = argv[i] + 13;        ip_address = argv[i] + 13;
1134      }      }
1135    
1136        else if (strcmp(argv[i], "--no-highlight") == 0) {
1137          jscoverage_highlight = false;
1138        }
1139    
1140      else if (strcmp(argv[i], "--no-instrument") == 0) {      else if (strcmp(argv[i], "--no-instrument") == 0) {
1141        i++;        i++;
1142        if (i == argc) {        if (i == argc) {
1143          fatal("--no-instrument: option requires an argument");          fatal_command_line("--no-instrument: option requires an argument");
1144        }        }
1145        no_instrument[num_no_instrument] = argv[i];        no_instrument[num_no_instrument] = argv[i];
1146        num_no_instrument++;        num_no_instrument++;
# Line 1003  Line 1153 
1153      else if (strcmp(argv[i], "--port") == 0) {      else if (strcmp(argv[i], "--port") == 0) {
1154        i++;        i++;
1155        if (i == argc) {        if (i == argc) {
1156          fatal("--port: option requires an argument");          fatal_command_line("--port: option requires an argument");
1157        }        }
1158        port = argv[i];        port = argv[i];
1159      }      }
# Line 1020  Line 1170 
1170      }      }
1171    
1172      else if (strncmp(argv[i], "-", 1) == 0) {      else if (strncmp(argv[i], "-", 1) == 0) {
1173        fatal("unrecognized option `%s'", argv[i]);        fatal_command_line("unrecognized option `%s'", argv[i]);
1174      }      }
1175      else {      else {
1176        fatal("too many arguments");        fatal_command_line("too many arguments");
1177      }      }
1178    }    }
1179    
# Line 1031  Line 1181 
1181    char * end;    char * end;
1182    unsigned long numeric_port = strtoul(port, &end, 10);    unsigned long numeric_port = strtoul(port, &end, 10);
1183    if (*end != '\0') {    if (*end != '\0') {
1184      fatal("--port: option must be an integer");      fatal_command_line("--port: option must be an integer");
1185    }    }
1186    if (numeric_port > UINT16_MAX) {    if (numeric_port > UINT16_MAX) {
1187      fatal("--port: option must be 16 bits");      fatal_command_line("--port: option must be 16 bits");
1188    }    }
1189    
1190    /* is this a shutdown? */    /* is this a shutdown? */
# Line 1042  Line 1192 
1192  #ifdef __MINGW32__  #ifdef __MINGW32__
1193      WSADATA data;      WSADATA data;
1194      if (WSAStartup(MAKEWORD(1, 1), &data) != 0) {      if (WSAStartup(MAKEWORD(1, 1), &data) != 0) {
1195        fatal("Could not start Winsock");        fatal("could not start Winsock");
1196      }      }
1197  #endif  #endif
1198    
# Line 1104  Line 1254 
1254      SourceCache * p = source_cache;      SourceCache * p = source_cache;
1255      source_cache = source_cache->next;      source_cache = source_cache->next;
1256      free(p->url);      free(p->url);
1257      Stream_delete(p->source);      free(p->characters);
1258      free(p);      free(p);
1259    }    }
1260    UNLOCK(&source_cache_mutex);    UNLOCK(&source_cache_mutex);

Legend:
Removed from v.133  
changed lines
  Added in v.275

  ViewVC Help
Powered by ViewVC 1.1.24