Changeset 212 in Main for trunk/Server/server.c
- Timestamp:
- Oct 3, 2024, 2:44:55 AM (6 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Server/server.c
r189 r212 16 16 #include "tw_version.h" 17 17 18 #ifndef _MSC_VER 18 19 #include <unistd.h> 20 #endif 19 21 #include <string.h> 20 22 #include <stdbool.h> … … 23 25 #include <stdlib.h> 24 26 #include <errno.h> 27 #include <sys/types.h> 25 28 #include <sys/stat.h> 26 #include <sys/types.h>27 29 #include <time.h> 28 30 … … 31 33 #include <cm_dir.h> 32 34 33 #if def __MINGW32__35 #if defined(__MINGW32__) || defined(_MSC_VER) 34 36 #ifndef NO_GETADDRINFO 35 37 #include <ws2tcpip.h> … … 70 72 #endif 71 73 74 #ifndef S_ISDIR 75 #define S_ISDIR(x) ((x) & _S_IFDIR) 76 #endif 77 72 78 extern struct tw_config config; 73 79 extern char tw_server[]; … … 78 84 int sockets[MAX_PORTS]; 79 85 80 #if def __MINGW32__86 #if defined(__MINGW32__) || defined(_MSC_VER) 81 87 const char* reserved_names[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}; 82 88 #endif … … 105 111 106 112 void close_socket(int sock) { 107 #if defined(__MINGW32__) 113 #if defined(__MINGW32__) || defined(_MSC_VER) 108 114 closesocket(sock); 109 115 #else … … 114 120 int tw_server_init(void) { 115 121 int i; 116 #if def __MINGW32__122 #if defined(__MINGW32__) || defined(_MSC_VER) 117 123 WSADATA wsa; 118 124 WSAStartup(MAKEWORD(2, 0), &wsa); … … 122 128 sockcount = i; 123 129 for(i = 0; config.ports[i] != -1; i++) { 130 int yes = 1; 131 int no = 0; 124 132 #ifdef NO_IPV6 125 133 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); … … 127 135 int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 128 136 #endif 129 #if def __MINGW32__137 #if defined(__MINGW32__) || defined(_MSC_VER) 130 138 if(sock == INVALID_SOCKET) 131 139 #else … … 136 144 return 1; 137 145 } 138 int yes = 1;139 146 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0) { 140 147 close_socket(sock); … … 150 157 #endif 151 158 #ifndef NO_IPV6 152 int no = 0;153 159 if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&no, sizeof(no)) < 0) { 154 160 close_socket(sock); … … 223 229 void _tw_process_page(SSL* ssl, int sock, const char* status, const char* type, FILE* f, const unsigned char* doc, size_t size, char** headers, time_t mtime, time_t cmtime) { 224 230 char construct[512]; 231 size_t incr; 225 232 if(mtime != 0 && cmtime != 0 && mtime <= cmtime) { 226 233 status = "304 Not Modified"; … … 231 238 doc = NULL; 232 239 } 240 #ifdef _MSC_VER 241 sprintf(construct, "%lu", (unsigned long)size); 242 #else 233 243 sprintf(construct, "%llu", (unsigned long long)size); 244 #endif 234 245 tw_write(ssl, sock, "HTTP/1.1 ", 9); 235 246 tw_write(ssl, sock, (char*)status, strlen(status)); … … 256 267 } 257 268 } 258 int i;259 269 if(headers != NULL) { 270 int i; 260 271 for(i = 0; headers[i] != NULL; i += 2) { 261 272 tw_write(ssl, sock, headers[i], strlen(headers[i])); … … 267 278 tw_write(ssl, sock, "\r\n", 2); 268 279 if(doc == NULL && f == NULL) return; 269 size_tincr = 0;280 incr = 0; 270 281 while(1) { 271 282 if(f != NULL) { … … 308 319 char* tw_http_default_error(int code, char* name, int port, struct tw_config_entry* vhost) { 309 320 char address[1024]; 321 char* st; 322 char* st2; 323 char* buffer; 324 char* str; 325 int i; 310 326 311 327 if((vhost->hideport == -1 ? config.root.hideport : vhost->hideport) == 1) { … … 315 331 } 316 332 317 char* st = cm_strdup(tw_http_status(code)); 318 char* st2; 319 int i; 333 st = cm_strdup(tw_http_status(code)); 320 334 for(i = 0; st[i] != 0; i++) { 321 335 if(st[i] == ' ') { … … 324 338 } 325 339 } 326 char*buffer = malloc(4096);327 char*str = cm_strcat3(ERROR_HTML);340 buffer = malloc(4096); 341 str = cm_strcat3(ERROR_HTML); 328 342 sprintf(buffer, str, st, st2); 329 343 free(str); … … 341 355 int i; 342 356 char cbuf[2]; 357 va_list va; 343 358 cbuf[1] = 0; 344 va_list va;345 359 va_start(va, add); 346 360 for(i = 0; add[i] != 0; i++) { … … 367 381 int n = va_arg(va, int); 368 382 char* h = malloc(512); 383 char* tmp = *str; 369 384 sprintf(h, "%d", n); 370 char* tmp = *str;371 385 *str = cm_strcat(tmp, h); 372 386 free(tmp); … … 388 402 char* tw_get_mime(const char* ext, struct tw_config_entry* vhost_entry) { 389 403 char* mime = "application/octet-stream"; 390 if(ext == NULL) return mime;391 404 bool set = false; 392 405 int i; 406 if(ext == NULL) return mime; 393 407 for(i = 0; i < vhost_entry->mime_count; i++) { 394 408 if(strcmp(vhost_entry->mimes[i].ext, "all") == 0 || (ext != NULL && tw_wildcard_match(vhost_entry->mimes[i].ext, ext))) { … … 409 423 char* tw_get_icon(const char* mime, struct tw_config_entry* vhost_entry) { 410 424 char* icon = ""; 411 if(mime == NULL) return "";412 425 bool set = false; 413 426 int i; 427 if(mime == NULL) return ""; 414 428 for(i = 0; i < vhost_entry->icon_count; i++) { 415 429 if(strcmp(vhost_entry->icons[i].mime, "all") == 0 || (mime != NULL && tw_wildcard_match(vhost_entry->icons[i].mime, mime))) { … … 435 449 }; 436 450 437 #if def __MINGW32__451 #if defined(__MINGW32__) || defined(_MSC_VER) 438 452 unsigned int WINAPI tw_server_pass(void* ptr) { 439 453 #elif defined(__HAIKU__) … … 442 456 int tw_server_pass(void* ptr) { 443 457 #endif 444 #if defined(__HAIKU__) || defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) 458 #if defined(__HAIKU__) || defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER) 459 #define FREE_PTR 445 460 int sock = ((struct pass_entry*)ptr)->sock; 446 461 bool ssl = ((struct pass_entry*)ptr)->ssl; 447 462 int port = ((struct pass_entry*)ptr)->port; 448 463 SOCKADDR addr = ((struct pass_entry*)ptr)->addr; 449 free(ptr);450 464 #else 451 465 void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) { 452 466 #endif 453 char* name = config.hostname; 454 467 SSL* s = NULL; 455 468 #ifndef NO_SSL 456 469 SSL_CTX* ctx = NULL; 457 SSL* s = NULL;458 470 bool sslworks = false; 459 471 if(ssl) { … … 464 476 sslworks = true; 465 477 } 466 #else 467 void* s = NULL; 468 #endif 469 478 #endif 479 char* name = config.hostname; 470 480 char address[513]; 471 address[0] = 0; 481 int ret; 482 struct tw_http_request req; 483 struct tw_http_response res; 484 struct tw_tool tools; 472 485 #ifndef NO_GETADDRINFO 473 486 struct sockaddr* sa = (struct sockaddr*)&addr; 474 487 getnameinfo(sa, sizeof(addr), address, 512, NULL, 0, NI_NUMERICHOST); 475 488 #endif 476 477 struct tw_http_request req; 478 struct tw_http_response res; 479 struct tw_tool tools; 489 address[0] = 0; 490 #ifdef FREE_PTR 491 free(ptr); 492 #endif 493 480 494 res._processed = false; 481 495 tw_init_tools(&tools); 482 intret = tw_http_parse(s, sock, &req);496 ret = tw_http_parse(s, sock, &req); 483 497 if(ret == 0) { 484 498 char date[513]; 485 499 time_t t = time(NULL); 486 500 struct tm* tm = localtime(&t); 501 char* useragent = cm_strdup(""); 502 int i; 503 char* tmp; 504 char* tmp2; 505 char* tmp3; 506 char* tmp4; 507 char* tmp5; 508 char* log; 509 char* vhost; 510 time_t cmtime; 511 bool rej; 512 char* host; 513 int port; 514 struct tw_config_entry* vhost_entry; 487 515 strftime(date, 512, "%a, %d %b %Y %H:%M:%S %Z", tm); 488 516 489 char* useragent = cm_strdup("");490 491 int i;492 517 for(i = 0; req.headers[i] != NULL; i += 2) { 493 518 if(cm_strcaseequ(req.headers[i], "User-Agent")) { … … 497 522 } 498 523 499 char*tmp = cm_strcat3(address, " - [", date);500 char*tmp2 = cm_strcat3(tmp, "] \"", req.method);501 char*tmp3 = cm_strcat3(tmp2, " ", req.path);502 char*tmp4 = cm_strcat3(tmp3, " ", req.version);503 char*tmp5 = cm_strcat3(tmp4, "\" \"", useragent);504 char*log = cm_strcat(tmp5, "\"");524 tmp = cm_strcat3(address, " - [", date); 525 tmp2 = cm_strcat3(tmp, "] \"", req.method); 526 tmp3 = cm_strcat3(tmp2, " ", req.path); 527 tmp4 = cm_strcat3(tmp3, " ", req.version); 528 tmp5 = cm_strcat3(tmp4, "\" \"", useragent); 529 log = cm_strcat(tmp5, "\""); 505 530 free(tmp); 506 531 free(tmp2); … … 512 537 free(log); 513 538 514 char*vhost = cm_strdup(config.hostname);515 time_tcmtime = 0;539 vhost = cm_strdup(config.hostname); 540 cmtime = 0; 516 541 if(req.headers != NULL) { 517 542 for(i = 0; req.headers[i] != NULL; i += 2) { … … 521 546 } else if(cm_strcaseequ(req.headers[i], "If-Modified-Since")) { 522 547 struct tm tm; 548 time_t t; 549 struct tm* btm; 523 550 strptime(req.headers[i + 1], "%a, %d %b %Y %H:%M:%S GMT", &tm); 524 #if defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(__ps2sdk__) 525 t ime_t t= 0;526 struct tm*btm = localtime(&t);551 #if defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(__ps2sdk__) || defined(_MSC_VER) 552 t = 0; 553 btm = localtime(&t); 527 554 cmtime = mktime(&tm); 528 555 cmtime -= (btm->tm_hour * 60 + btm->tm_min) * 60; … … 533 560 } 534 561 } 535 boolrej = false;562 rej = false; 536 563 cm_log("Server", "Host is %s", vhost); 537 intport = s == NULL ? 80 : 443;538 char*host = cm_strdup(vhost);564 port = s == NULL ? 80 : 443; 565 host = cm_strdup(vhost); 539 566 for(i = 0; vhost[i] != 0; i++) { 540 567 if(vhost[i] == ':') { … … 546 573 name = host; 547 574 cm_log("Server", "Hostname is `%s', port is `%d'", host, port); 548 struct tw_config_entry*vhost_entry = tw_vhost_match(host, port);575 vhost_entry = tw_vhost_match(host, port); 549 576 #ifdef HAS_CHROOT 550 577 char* chrootpath = vhost_entry->chroot_path != NULL ? vhost_entry->chroot_path : config.root.chroot_path; … … 582 609 } 583 610 if(!res._processed) { 611 char* path; 612 char* rpath; 613 struct stat st; 584 614 cm_log("Server", "Document root is %s", vhost_entry->root == NULL ? "not set" : vhost_entry->root); 585 char*path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);615 path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path); 586 616 cm_log("Server", "Filesystem path is %s", path); 587 #if def __MINGW32__588 char*rpath = cm_strdup(path);617 #if defined(__MINGW32__) || defined(_MSC_VER) 618 rpath = cm_strdup(path); 589 619 for(i = strlen(rpath) - 1; i >= 0; i--) { 590 620 if(rpath[i] == '/') { … … 612 642 free(rpath); 613 643 #endif 614 struct stat st;615 644 if(!rej && stat(path, &st) == 0) { 616 645 if(!tw_permission_allowed(path, addr, req, vhost_entry)) { … … 618 647 } else if(S_ISDIR(st.st_mode)) { 619 648 if(req.path[strlen(req.path) - 1] != '/') { 649 char* headers[3] = {"Location", cm_strcat(req.path, "/"), NULL}; 620 650 cm_log("Server", "Accessing directory without the slash at the end"); 621 char* headers[3] = {"Location", cm_strcat(req.path, "/"), NULL};622 651 _tw_process_page(s, sock, tw_http_status(301), NULL, NULL, NULL, 0, headers, 0, 0); 623 652 free(headers[1]); … … 632 661 char* ext = NULL; 633 662 int j; 663 struct stat st; 664 char* mime; 634 665 for(j = strlen(p) - 1; j >= 0; j--) { 635 666 if(p[j] == '.') { … … 640 671 } 641 672 } 642 struct stat st;643 673 stat(p, &st); 644 char*mime = tw_get_mime(ext, vhost_entry);674 mime = tw_get_mime(ext, vhost_entry); 645 675 tw_process_page(s, sock, tw_http_status(200), mime, f, NULL, st.st_size, 0, 0); 646 676 fclose(f); … … 654 684 if(!found) { 655 685 char* str = malloc(1); 686 char** items; 687 int readme; 688 char** readmes; 689 int readme_count; 690 int hp; 656 691 str[0] = 0; 657 char**items = cm_scandir(path);692 items = cm_scandir(path); 658 693 addstring(&str, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"); 659 694 addstring(&str, "<html>\n"); … … 673 708 addstring(&str, " <th>Size</th>\n"); 674 709 addstring(&str, " </tr>\n"); 675 intreadme = -1;676 char**readmes = vhost_entry->readme_count == 0 ? config.root.readmes : vhost_entry->readmes;677 intreadme_count = vhost_entry->readme_count == 0 ? config.root.readme_count : vhost_entry->readme_count;710 readme = -1; 711 readmes = vhost_entry->readme_count == 0 ? config.root.readmes : vhost_entry->readmes; 712 readme_count = vhost_entry->readme_count == 0 ? config.root.readme_count : vhost_entry->readme_count; 678 713 if(items != NULL) { 679 714 int phase = 0; … … 681 716 for(i = 0; items[i] != NULL; i++) { 682 717 int j; 718 char* ext; 719 char* itm; 720 char* icon; 683 721 char* fpth = cm_strcat3(path, "/", items[i]); 684 722 struct stat s; 685 723 char size[512]; 724 char* showmime; 725 char* mime; 686 726 size[0] = 0; 687 727 stat(fpth, &s); … … 705 745 } 706 746 } 707 if(s.st_size < 1024ULL) {747 if(s.st_size < NUM1024) { 708 748 sprintf(size, "%d", (int)s.st_size); 709 } else if(s.st_size < 1024ULL* 1024) {749 } else if(s.st_size < NUM1024 * 1024) { 710 750 sprintf(size, "%.1fK", (double)s.st_size / 1024); 711 } else if(s.st_size < 1024ULL* 1024 * 1024) {751 } else if(s.st_size < NUM1024 * 1024 * 1024) { 712 752 sprintf(size, "%.1fM", (double)s.st_size / 1024 / 1024); 713 } else if(s.st_size < 1024ULL* 1024 * 1024 * 1024) {753 } else if(s.st_size < NUM1024 * 1024 * 1024 * 1024) { 714 754 sprintf(size, "%.1fG", (double)s.st_size / 1024 / 1024 / 1024); 715 } else if(s.st_size < 1024ULL* 1024 * 1024 * 1024 * 1024) {755 } else if(s.st_size < NUM1024 * 1024 * 1024 * 1024 * 1024) { 716 756 sprintf(size, "%.1fT", (double)s.st_size / 1024 / 1024 / 1024 / 1024); 717 757 } … … 719 759 free(fpth); 720 760 721 char*ext = NULL;761 ext = NULL; 722 762 for(j = strlen(items[i]) - 1; j >= 0; j--) { 723 763 if(items[i][j] == '.') { … … 728 768 } 729 769 } 730 char*showmime = "";731 char*mime = tw_get_mime(ext, vhost_entry);770 showmime = ""; 771 mime = tw_get_mime(ext, vhost_entry); 732 772 if(strcmp(items[i], "../") == 0) { 733 773 mime = "misc/parent"; … … 739 779 showmime = mime; 740 780 } 741 char*icon = tw_get_icon(mime, vhost_entry);781 icon = tw_get_icon(mime, vhost_entry); 742 782 if(ext != NULL) free(ext); 743 char*itm = cm_strdup(items[i]);783 itm = cm_strdup(items[i]); 744 784 if(strlen(itm) >= 32) { 745 785 if(itm[strlen(itm) - 1] == '/') { … … 771 811 addstring(&str, " </table>\n"); 772 812 if(readme != -1) { 813 struct stat s; 814 FILE* fr; 815 char* fpth; 773 816 addstring(&str, "<hr>\n"); 774 char* fpth = cm_strcat3(path, "/", readmes[readme]); 775 struct stat s; 817 fpth = cm_strcat3(path, "/", readmes[readme]); 776 818 stat(fpth, &s); 777 FILE*fr = fopen(fpth, "r");819 fr = fopen(fpth, "r"); 778 820 if(fr != NULL) { 779 821 char* rmbuf = malloc(s.st_size + 1); … … 787 829 } 788 830 addstring(&str, " <hr>\n"); 789 inthp = vhost_entry->hideport == -1 ? config.root.hideport : vhost_entry->hideport;831 hp = vhost_entry->hideport == -1 ? config.root.hideport : vhost_entry->hideport; 790 832 if(hp == 0) { 791 833 addstring(&str, " <address>%s Server at %s Port %d</address>\n", tw_server, name, port); … … 801 843 } else { 802 844 char* ext = NULL; 845 char* mime; 846 FILE* f; 803 847 for(i = strlen(req.path) - 1; i >= 0; i--) { 804 848 if(req.path[i] == '.') { … … 809 853 } 810 854 } 811 char*mime = tw_get_mime(ext, vhost_entry);855 mime = tw_get_mime(ext, vhost_entry); 812 856 if(ext != NULL) free(ext); 813 FILE*f = fopen(path, "rb");857 f = fopen(path, "rb"); 814 858 if(f == NULL) { 815 859 tw_http_error(s, sock, 403, name, port, vhost_entry); … … 841 885 #endif 842 886 close_socket(sock); 843 #if def __MINGW32__844 _endthread ex(0);887 #if defined(__MINGW32__) || defined(_MSC_VER) 888 _endthread(0); 845 889 #elif defined(__HAIKU__) 846 890 exit_thread(0); … … 854 898 #endif 855 899 856 #if defined(__MINGW32__) || defined(__HAIKU__) 900 #if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER) 857 901 struct thread_entry { 858 902 #ifdef __HAIKU__ … … 869 913 void tw_server_loop(void) { 870 914 int i; 871 #if defined(__MINGW32__) || defined(__HAIKU__) 915 #ifndef USE_POLL 916 fd_set fdset; 917 struct timeval tv; 918 #endif 919 #if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER) 872 920 struct thread_entry threads[2048]; 873 921 for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) { … … 881 929 pollfds[i].events = POLLIN | POLLPRI; 882 930 } 883 #else884 fd_set fdset;885 struct timeval tv;886 931 #endif 887 932 while(running) { 933 int ret; 888 934 #ifdef USE_POLL 889 intret = poll(pollfds, sockcount, 1000);935 ret = poll(pollfds, sockcount, 1000); 890 936 #else 891 937 FD_ZERO(&fdset); … … 896 942 tv.tv_usec = 0; 897 943 #ifdef __HAIKU__ 898 intret = select(32, &fdset, NULL, NULL, &tv);899 #else 900 intret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);944 ret = select(32, &fdset, NULL, NULL, &tv); 945 #else 946 ret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv); 901 947 #endif 902 948 #endif 903 949 if(ret == -1) { 904 #if ndef __MINGW32__950 #if !defined(__MINGW32__) && !defined(_MSC_VER) 905 951 cm_log("Server", "Select failure: %s", strerror(errno)); 906 952 #endif … … 926 972 socklen_t clen = sizeof(claddr); 927 973 int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen); 974 #if defined(__MINGW32__) || defined(__HAIKU__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER) 975 int j; 976 struct pass_entry* e = malloc(sizeof(*e)); 928 977 cm_log("Server", "New connection accepted"); 929 #if defined(__MINGW32__) || defined(__HAIKU__) || defined(_PSP) || defined(__PPU__)930 struct pass_entry* e = malloc(sizeof(*e));931 978 e->sock = sock; 932 e->ssl = config.ports[i] & (1ULL << 32); 979 #ifdef _MSC_VER 980 e->ssl = config.ports[i] & (1UL << 31); 981 #else 982 e->ssl = config.ports[i] & (1ULL << 31); 983 #endif 933 984 e->port = config.ports[i]; 934 985 e->addr = claddr; 935 986 #endif 936 #ifdef __MINGW32__ 937 int j; 938 for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) { 939 if(threads[j].used) { 940 DWORD ex; 941 GetExitCodeThread(threads[j].handle, &ex); 942 if(ex != STILL_ACTIVE) { 943 CloseHandle(threads[j].handle); 944 threads[j].used = false; 945 } 946 } 947 } 948 for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) { 949 if(!threads[j].used) { 950 threads[j].handle = (HANDLE)_beginthreadex(NULL, 0, tw_server_pass, e, 0, NULL); 951 threads[j].used = true; 952 break; 953 } 954 } 987 #if defined(__MINGW32__) || defined(_MSC_VER) 988 _beginthread(tw_server_pass, 0, e); 955 989 #elif defined(_PSP) || defined(__PPU__) 956 990 tw_server_pass(e); 957 991 #elif defined(__HAIKU__) 958 int j;959 992 for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) { 960 993 if(threads[j].used) { … … 983 1016 int j; 984 1017 for(j = 0; j < sockcount; j++) close_socket(sockets[j]); 985 tw_server_pass(sock, config.ports[i] & (1ULL << 3 2), config.ports[i], claddr);1018 tw_server_pass(sock, config.ports[i] & (1ULL << 31), config.ports[i], claddr); 986 1019 _exit(0); 987 1020 } else {
Note:
See TracChangeset
for help on using the changeset viewer.