source: Main/trunk/Server/main.c@ 253

Last change on this file since 253 was 253, checked in by Nishi, on Oct 4, 2024 at 12:13:36 PM

fix stuff

  • Property svn:keywords set to Id
File size: 18.8 KB
Line 
1/* $Id: main.c 253 2024-10-04 03:13:36Z nishi $ */
2
3#define SOURCE
4
5#include "../config.h"
6
7#ifdef __BORLANDC__
8
9#pragma resource "tewi_bcc.res"
10
11#pragma resource "gui_bcc.res"
12
13#endif
14
15#if !defined(_MSC_VER) && !defined(__BORLANDC__)
16#include <unistd.h>
17#endif
18#include <stdio.h>
19#include <stdbool.h>
20#include <string.h>
21#include <signal.h>
22#include <stdlib.h>
23
24#ifndef NO_SSL
25#include <openssl/opensslv.h>
26#endif
27
28#include <cm_log.h>
29#include <cm_string.h>
30
31#include "tw_config.h"
32#include "tw_server.h"
33#include "tw_version.h"
34
35#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__)
36#include <windows.h>
37#endif
38
39#ifdef _PSP
40#include <pspkernel.h>
41#include <pspdebug.h>
42#include <pspsdk.h>
43#include <psputility.h>
44#include <pspctrl.h>
45#include <pspnet_apctl.h>
46#include <pspwlan.h>
47
48PSP_MODULE_INFO("Tewi HTTPd", PSP_MODULE_USER, 1, 1);
49PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
50
51#define printf(...) pspDebugScreenPrintf(__VA_ARGS__)
52#define STDERR_LOG(...) pspDebugScreenPrintf(__VA_ARGS__)
53#elif defined(__ps2sdk__)
54#include <debug.h>
55#include <iopcontrol.h>
56#include <sifrpc.h>
57#include <kernel.h>
58
59#define printf(...) scr_printf(__VA_ARGS__)
60#define STDERR_LOG(...) scr_printf(__VA_ARGS__)
61#elif defined(__PPU__)
62#include <rsx/gcm_sys.h>
63#include <rsx/rsx.h>
64#include <sysutil/video.h>
65#include <malloc.h>
66#include <sys/thread.h>
67#include <stdarg.h>
68#include <png.h>
69
70#define printf(...) tt_printf(__VA_ARGS__)
71#define STDERR_LOG(...) tt_printf(__VA_ARGS__)
72#elif defined(_MSC_VER) || defined(__BORLANDC__)
73void STDERR_LOG(const char* format, ...) {
74 va_list args;
75 va_start(args, format);
76 vfprintf(stderr, format, args);
77 va_end(args);
78}
79#else
80#define STDERR_LOG(...) fprintf(stderr, __VA_ARGS__)
81#endif
82
83extern bool cm_do_log;
84extern struct tw_config config;
85extern FILE* logfile;
86
87char tw_server[2048];
88
89int startup(int argc, char** argv);
90
91#if defined(__MINGW32__) || defined(_MSC_VER)
92char* get_registry(const char* main, const char* sub) {
93 DWORD bufsize = 512;
94 HKEY handle;
95 char* value = malloc(513);
96 int err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, main, 0, KEY_QUERY_VALUE, &handle);
97 if(err == ERROR_SUCCESS) {
98 err = RegQueryValueEx(handle, sub, NULL, NULL, value, &bufsize);
99 if(err != ERROR_SUCCESS) {
100 free(value);
101 RegCloseKey(handle);
102 return NULL;
103 }
104 RegCloseKey(handle);
105 return value;
106 } else {
107 free(value);
108 return NULL;
109 }
110}
111#endif
112
113#ifdef SERVICE
114SERVICE_STATUS status;
115SERVICE_STATUS_HANDLE status_handle;
116
117void WINAPI servhandler(DWORD control) {
118 switch(control) {
119 case SERVICE_CONTROL_STOP:
120 case SERVICE_CONTROL_SHUTDOWN:
121 status.dwCurrentState = SERVICE_STOP_PENDING;
122 break;
123 }
124 SetServiceStatus(status_handle, &status);
125}
126
127void WINAPI servmain(DWORD argc, LPSTR* argv) {
128 char* path = get_registry("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Tewi HTTPd", "InstallDir");
129 if(path != NULL) {
130 char* lpath = cm_strcat(path, "/logs/tewi.log");
131 logfile = fopen(lpath, "a");
132 free(lpath);
133 free(path);
134 } else {
135 logfile = fopen(PREFIX "/logs/tewi.log", "a");
136 }
137 if(logfile == NULL) logfile = stderr;
138 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
139 status.dwCurrentState = SERVICE_START_PENDING;
140 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
141 status.dwWin32ExitCode = NO_ERROR;
142 status.dwServiceSpecificExitCode = 0;
143 status.dwCheckPoint = 0;
144 status.dwWaitHint = 0;
145 status_handle = RegisterServiceCtrlHandler("Tewi HTTPd", servhandler);
146 if(status_handle == NULL) return;
147 if(SetServiceStatus(status_handle, &status) == 0) return;
148 int st = startup(argc, argv);
149 if(st != -1) {
150 status.dwWin32ExitCode = NO_ERROR;
151 status.dwServiceSpecificExitCode = st;
152 status.dwCurrentState = SERVICE_STOPPED;
153 SetServiceStatus(status_handle, &status);
154 return;
155 }
156 status.dwCurrentState = SERVICE_RUNNING;
157 SetServiceStatus(status_handle, &status);
158 tw_server_loop();
159 status.dwCurrentState = SERVICE_STOPPED;
160 SetServiceStatus(status_handle, &status);
161}
162#endif
163
164int running = 1;
165#ifdef _PSP
166
167int psp_exit_callback(int arg1, int arg2, void* arg3) { running = 0; }
168
169int psp_callback_thread(SceSize args, void* argp) {
170 int cid;
171 cid = sceKernelCreateCallback("Exit Call Back", psp_exit_callback, NULL);
172 sceKernelRegisterExitCallback(cid);
173 sceKernelSleepThreadCB();
174 return 0;
175}
176#endif
177
178#ifdef __PPU__
179uint32_t depth_pitch;
180uint32_t depth_offset;
181uint32_t* depth_buffer;
182
183#define CB_SIZE 0x100000
184#define HOST_SIZE (32 * 1024 * 1024)
185
186struct rsx_buffer {
187 int width, height, id;
188 uint32_t* ptr;
189 uint32_t offset;
190};
191
192void wait_rsx(gcmContextData* ctx, uint32_t label) {
193 rsxSetWriteBackendLabel(ctx, GCM_INDEX_TYPE_32B, label);
194
195 rsxFlushBuffer(ctx);
196
197 while(*(uint32_t*)gcmGetLabelAddress(GCM_INDEX_TYPE_32B) != label) usleep(50);
198
199 label++;
200}
201
202void wait_rsx_until_idle(gcmContextData* ctx) {
203 uint32_t label = 1;
204 rsxSetWriteBackendLabel(ctx, GCM_INDEX_TYPE_32B, label);
205 rsxSetWaitLabel(ctx, GCM_INDEX_TYPE_32B, label);
206 label++;
207 wait_rsx(ctx, label);
208}
209
210void get_resolution(int* width, int* height) {
211 videoState state;
212 videoResolution res;
213 if(videoGetState(0, 0, &state) != 0) {
214 return;
215 }
216
217 if(state.state != 0) {
218 return;
219 }
220
221 if(videoGetResolution(state.displayMode.resolution, &res) != 0) {
222 return;
223 }
224 *width = res.width;
225 *height = res.height;
226}
227
228void make_buffer(struct rsx_buffer* buffer, int id) {
229 int w, h;
230 get_resolution(&w, &h);
231
232 buffer->ptr = (uint32_t*)rsxMemalign(64, 4 * w * h);
233 if(buffer->ptr == NULL) return;
234
235 if(rsxAddressToOffset(buffer->ptr, &buffer->offset) != 0) return;
236
237 if(gcmSetDisplayBuffer(id, buffer->offset, 4 * w, w, h) != 0) return;
238 buffer->width = w;
239 buffer->height = h;
240 buffer->id = id;
241}
242
243gcmContextData* init_screen(void) {
244 void* host = memalign(1024 * 1024, HOST_SIZE);
245 gcmContextData* ctx = NULL;
246 videoState state;
247 videoConfiguration vconfig;
248 videoResolution res;
249 rsxInit(&ctx, CB_SIZE, HOST_SIZE, host);
250 if(ctx == NULL) {
251 free(host);
252 return NULL;
253 }
254
255 if(videoGetState(0, 0, &state) != 0) {
256 rsxFinish(ctx, 0);
257 free(host);
258 return NULL;
259 }
260
261 if(state.state != 0) {
262 rsxFinish(ctx, 0);
263 free(host);
264 return NULL;
265 }
266
267 if(videoGetResolution(state.displayMode.resolution, &res) != 0) {
268 rsxFinish(ctx, 0);
269 free(host);
270 return NULL;
271 }
272
273 memset(&vconfig, 0, sizeof(vconfig));
274 vconfig.resolution = state.displayMode.resolution;
275 vconfig.format = VIDEO_BUFFER_FORMAT_XRGB;
276 vconfig.pitch = res.width * 4;
277 vconfig.aspect = state.displayMode.aspect;
278
279 wait_rsx_until_idle(ctx);
280
281 if(videoConfigure(0, &vconfig, NULL, 0) != 0) {
282 rsxFinish(ctx, 0);
283 free(host);
284 return NULL;
285 }
286
287 if(videoGetState(0, 0, &state) != 0) {
288 rsxFinish(ctx, 0);
289 free(host);
290 return NULL;
291 }
292 gcmSetFlipMode(GCM_FLIP_VSYNC);
293
294 depth_pitch = res.width * 4;
295 depth_buffer = (uint32_t*)rsxMemalign(64, (res.height * depth_pitch) * 2);
296 rsxAddressToOffset(depth_buffer, &depth_offset);
297
298 gcmResetFlipStatus();
299
300 return ctx;
301}
302
303void set_render_target(gcmContextData* context, struct rsx_buffer* buffer) {
304 gcmSurface sf;
305
306 sf.colorFormat = GCM_SURFACE_X8R8G8B8;
307 sf.colorTarget = GCM_SURFACE_TARGET_0;
308 sf.colorLocation[0] = GCM_LOCATION_RSX;
309 sf.colorOffset[0] = buffer->offset;
310 sf.colorPitch[0] = depth_pitch;
311
312 sf.colorLocation[1] = GCM_LOCATION_RSX;
313 sf.colorLocation[2] = GCM_LOCATION_RSX;
314 sf.colorLocation[3] = GCM_LOCATION_RSX;
315 sf.colorOffset[1] = 0;
316 sf.colorOffset[2] = 0;
317 sf.colorOffset[3] = 0;
318 sf.colorPitch[1] = 64;
319 sf.colorPitch[2] = 64;
320 sf.colorPitch[3] = 64;
321
322 sf.depthFormat = GCM_SURFACE_ZETA_Z16;
323 sf.depthLocation = GCM_LOCATION_RSX;
324 sf.depthOffset = depth_offset;
325 sf.depthPitch = depth_pitch;
326
327 sf.type = GCM_TEXTURE_LINEAR;
328 sf.antiAlias = GCM_SURFACE_CENTER_1;
329
330 sf.width = buffer->width;
331 sf.height = buffer->height;
332 sf.x = 0;
333 sf.y = 0;
334
335 rsxSetSurface(context, &sf);
336}
337
338void wait_flip(void) {
339 while(gcmGetFlipStatus() != 0) usleep(200);
340 gcmResetFlipStatus();
341}
342
343void flip(gcmContextData* ctx, uint32_t buffer) {
344 if(gcmSetFlip(ctx, buffer) == 0) {
345 rsxFlushBuffer(ctx);
346 gcmSetWaitFlip(ctx);
347 }
348}
349
350uint8_t* tvram;
351
352extern uint8_t font[];
353
354int tt_x = 0;
355int tt_y = 0;
356int tt_width;
357int tt_height;
358
359void tt_putstr(const char* str) {
360 int i;
361 for(i = 0; str[i] != 0; i++) {
362 tvram[tt_y * tt_width + tt_x] = str[i];
363 if(str[i] == '\n') {
364 tt_x = 0;
365 tt_y++;
366 } else {
367 tt_x++;
368 if(tt_x == tt_width) {
369 tt_x = 0;
370 tt_y++;
371 }
372 }
373 if(tt_y == tt_height) {
374 tt_y--;
375 int x, y;
376 for(y = 0; y < tt_height - 1; y++) {
377 for(x = 0; x < tt_width; x++) {
378 tvram[y * tt_width + x] = tvram[(y + 1) * tt_width + x];
379 }
380 }
381 for(x = 0; x < tt_width; x++) {
382 tvram[(tt_height - 1) * tt_width + x] = 0x20;
383 }
384 }
385 }
386}
387
388void tt_putchar(struct rsx_buffer* buffer, int x, int y, uint8_t c) {
389 int i, j;
390 if(c == 0) return;
391 if(c < 0x20) c = 0x20;
392 if(c >= 0x7f) c = 0x20;
393 for(i = 0; i < 8; i++) {
394 uint8_t l = i == 7 ? 0 : font[(c - 0x20) * 8 + i];
395 for(j = 0; j < 6; j++) {
396 uint32_t col = 0;
397 if(l & (1 << 7)) {
398 col = 0xffffff;
399 }
400 l = l << 1;
401 buffer->ptr[(y * 8 + i) * buffer->width + x * 6 + j] = col;
402 }
403 }
404}
405
406void draw(struct rsx_buffer* buffer, int current) {
407 int i, j, c;
408 for(i = 0; i < buffer->height / 8; i++) {
409 for(j = 0; j < buffer->width / 6; j++) {
410 uint8_t c = tvram[i * (buffer->width / 6) + j];
411 tt_putchar(buffer, j, i, c);
412 }
413 }
414}
415
416#define BUFFERS 1
417gcmContextData* ctx;
418struct rsx_buffer buffers[BUFFERS];
419
420void text_thread(void* arg) {
421 int current = 0;
422 while(1) {
423 wait_flip();
424 draw(&buffers[current], current);
425 flip(ctx, buffers[current].id);
426 current++;
427 if(current >= BUFFERS) current = 0;
428 }
429}
430
431void tt_printf(const char* tmpl, ...) {
432 va_list va;
433 va_start(va, tmpl);
434 int i;
435 char cbuf[2];
436 cbuf[1] = 0;
437 char* log = cm_strdup("");
438 for(i = 0; tmpl[i] != 0; i++) {
439 if(tmpl[i] == '%') {
440 i++;
441 if(tmpl[i] == 's') {
442 char* tmp = log;
443 log = cm_strcat(tmp, va_arg(va, char*));
444 free(tmp);
445 } else if(tmpl[i] == 'd') {
446 char buf[513];
447 sprintf(buf, "%d", va_arg(va, int));
448 char* tmp = log;
449 log = cm_strcat(tmp, buf);
450 free(tmp);
451 } else if(tmpl[i] == '%') {
452 char* tmp = log;
453 log = cm_strcat(tmp, "%");
454 free(tmp);
455 }
456 } else {
457 cbuf[0] = tmpl[i];
458 char* tmp = log;
459 log = cm_strcat(tmp, cbuf);
460 free(tmp);
461 }
462 }
463 va_end(va);
464 tt_putstr(log);
465}
466
467void show_png(void) {
468 FILE* f = fopen(PREFIX "/pbtewi.png", "rb");
469 if(f == NULL) {
470 f = fopen(PREFIX "/../ICON0.PNG", "rb");
471 }
472 if(f == NULL) return;
473 png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
474 png_infop info = png_create_info_struct(png);
475 if(setjmp(png_jmpbuf(png))) {
476 png_destroy_read_struct(&png, &info, NULL);
477 fclose(f);
478 return;
479 }
480
481 png_init_io(png, f);
482 png_read_info(png, info);
483
484 int width = png_get_image_width(png, info);
485 int height = png_get_image_height(png, info);
486 int depth = png_get_bit_depth(png, info);
487 int type = png_get_color_type(png, info);
488
489 if(depth == 16) png_set_strip_16(png);
490 if(type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
491 if(type == PNG_COLOR_TYPE_GRAY && depth < 8) png_set_expand_gray_1_2_4_to_8(png);
492 if(png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
493 if(type == PNG_COLOR_TYPE_RGB || type == PNG_COLOR_TYPE_GRAY || type == PNG_COLOR_TYPE_PALETTE) png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
494 if(type == PNG_COLOR_TYPE_GRAY || type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png);
495 png_read_update_info(png, info);
496 png_bytep* rows = (png_bytep*)malloc(sizeof(*rows) * (height));
497
498 int i;
499
500 for(i = 0; i < height; i++) {
501 rows[i] = (png_byte*)malloc(png_get_rowbytes(png, info));
502 }
503
504 png_read_image(png, rows);
505
506 for(i = 0; i < height; i++) {
507 int j;
508 for(j = 0; j < width; j++) {
509 png_bytep byte = &(rows[i][j * 4]);
510 uint32_t col = (byte[0] << 16) | (byte[1] << 8) | (byte[2]);
511 int k;
512 for(k = 0; k < BUFFERS; k++) {
513 buffers[k].ptr[buffers[k].width * i - width + j] = col;
514 }
515 }
516 }
517
518 png_destroy_read_struct(&png, &info, NULL);
519 fclose(f);
520
521 for(i = 0; i < height; i++) {
522 free(rows[i]);
523 }
524 free(rows);
525}
526
527#endif
528
529#if !defined(BUILD_GUI_VALID)
530int main(int argc, char** argv) {
531 int st;
532 logfile = stderr;
533#ifdef SERVICE
534 SERVICE_TABLE_ENTRY table[] = {{"Tewi HTTPd", servmain}, {NULL, NULL}};
535 StartServiceCtrlDispatcher(table);
536#else
537#ifdef _PSP
538 pspDebugScreenInit();
539 pspDebugScreenSetXY(0, 0);
540 printf("PSP Bootstrap, Tewi/%s\n", tw_get_version());
541 int thid = sceKernelCreateThread("update_thread", psp_callback_thread, 0x11, 0xfa0, 0, NULL);
542 if(thid >= 0) {
543 sceKernelStartThread(thid, 0, NULL);
544 } else {
545 printf("Failed to start thread\n");
546 while(running) sceKernelDelayThread(50 * 1000);
547 sceKernelExitGame();
548 }
549 sceCtrlSetSamplingCycle(0);
550 sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
551 sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
552 sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
553 if(pspSdkInetInit()) {
554 printf("Could not init the network\n");
555 while(running) sceKernelDelayThread(50 * 1000);
556 sceKernelExitGame();
557 } else {
558 printf("Network initialization successful\n");
559 }
560 if(sceWlanGetSwitchState() != 1) {
561 printf("Turn the Wi-Fi switch on\n");
562 while(sceWlanGetSwitchState() != 1) {
563 sceKernelDelayThread(1000 * 1000);
564 }
565 } else {
566 printf("Wi-Fi is turned on\n");
567 }
568 int i;
569 int choice[100];
570 int incr = 0;
571 int last = 0;
572 int cur = 0;
573 for(i = 1; i < 100; i++) {
574 choice[i - 1] = 0;
575 netData name;
576 netData data;
577 if(sceUtilityCheckNetParam(i) != 0) continue;
578 choice[incr++] = i;
579 pspDebugScreenSetXY(0, 1 + 3 + incr - 1);
580 if(incr == 1) printf("> ");
581 pspDebugScreenSetXY(2, 1 + 3 + incr - 1);
582 sceUtilityGetNetParam(i, 0, &name);
583 sceUtilityGetNetParam(i, 1, &data);
584 printf("SSID=%s", data.asString);
585 sceUtilityGetNetParam(i, 4, &data);
586 if(data.asString[0]) {
587 sceUtilityGetNetParam(i, 5, &data);
588 printf(" IPADDR=%s\n", data.asString);
589 } else {
590 printf(" DHCP\n");
591 }
592 }
593 int press = 0;
594 while(1) {
595 if(!running) {
596 sceKernelExitGame();
597 }
598 SceCtrlData c;
599 sceCtrlReadBufferPositive(&c, 1);
600 press = 0;
601 if(c.Buttons & PSP_CTRL_DOWN) {
602 if(cur < incr - 1) {
603 cur++;
604 }
605 press = 1;
606 } else if(c.Buttons & PSP_CTRL_UP) {
607 if(cur > 0) {
608 cur--;
609 }
610 press = -1;
611 } else if(c.Buttons & PSP_CTRL_START) {
612 break;
613 }
614 if(last != cur) {
615 pspDebugScreenSetXY(0, 1 + 3 + last);
616 printf(" ");
617 pspDebugScreenSetXY(0, 1 + 3 + cur);
618 printf("> ");
619 last = cur;
620 }
621 if(press != 0) {
622 while(1) {
623 SceCtrlData c;
624 sceCtrlReadBufferPositive(&c, 1);
625 if(press == 1) {
626 if(!(c.Buttons & PSP_CTRL_DOWN)) break;
627 } else if(press == -1) {
628 if(!(c.Buttons & PSP_CTRL_UP)) break;
629 }
630 }
631 }
632 }
633 pspDebugScreenSetXY(0, 1 + 3 + incr + 1);
634 int err = sceNetApctlConnect(choice[cur]);
635 if(err != 0) {
636 printf("Apctl initialization failure\n");
637 while(running) sceKernelDelayThread(50 * 1000);
638 sceKernelExitGame();
639 } else {
640 printf("Apctl initialization successful\n");
641 }
642 printf("Apctl connecting\n");
643 while(1) {
644 int state;
645 err = sceNetApctlGetState(&state);
646 if(err != 0) {
647 printf("Apctl getting status failure\n");
648 while(running) sceKernelDelayThread(50 * 1000);
649 sceKernelExitGame();
650 }
651 if(state == 4) {
652 break;
653 }
654 sceKernelDelayThread(50 * 1000);
655 }
656 union SceNetApctlInfo info;
657 if(sceNetApctlGetInfo(8, &info) != 0) {
658 printf("Got an unknown IP\n");
659 while(running) sceKernelDelayThread(50 * 1000);
660 sceKernelExitGame();
661 }
662 printf("Connected, My IP is %s\n", info.ip);
663#elif defined(__PPU__)
664 int i;
665 ctx = init_screen();
666 int w, h;
667 get_resolution(&w, &h);
668 tt_width = w / 6;
669 tt_height = h / 8;
670 tvram = malloc((w / 6) * (h / 8));
671 for(i = 0; i < BUFFERS; i++) make_buffer(&buffers[i], i);
672 flip(ctx, BUFFERS - 1);
673 sys_ppu_thread_t id;
674 sysThreadCreate(&id, text_thread, NULL, 1500, 0x1000, THREAD_JOINABLE, "TextThread");
675 printf("PS3 Bootstrap, Tewi/%s\n", tw_get_version());
676 show_png();
677 netInitialize();
678#elif defined(__ps2sdk__)
679 SifInitRpc(0);
680 while(!SifIopReset("", 0))
681 ;
682 while(!SifIopSync())
683 ;
684 init_scr();
685 scr_printf("PS2 Bootstrap, Tewi/%s\n", tw_get_version());
686 SleepThread();
687#endif
688 st = startup(argc, argv);
689 if(st != -1) {
690#ifdef _PSP
691 printf("Error code %d\n", st);
692 while(running) sceKernelDelayThread(50 * 1000);
693 sceKernelExitGame();
694#else
695#ifdef __PPU__
696 printf("Error code %d\n", st);
697 while(1)
698 ;
699#endif
700 return st;
701#endif
702 }
703 tw_server_loop();
704#endif
705#ifdef _PSP
706 sceKernelExitGame();
707#endif
708 return 0;
709}
710#endif
711
712int startup(int argc, char** argv) {
713 int i;
714 char* r;
715#if defined(__MINGW32__) || defined(_MSC_VER)
716 char* confpath = cm_strdup(PREFIX "/etc/tewi.conf");
717 char* regpath = get_registry("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Tewi HTTPd", "InstallDir");
718 if(regpath != NULL) {
719 free(confpath);
720 confpath = cm_strcat(regpath, "/etc/tewi.conf");
721 free(regpath);
722 }
723#else
724 const char* confpath = PREFIX "/etc/tewi.conf";
725#endif
726 if(argv != NULL) {
727 for(i = 1; i < argc; i++) {
728 if(argv[i][0] == '-') {
729 if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
730 if(!cm_do_log) {
731 cm_do_log = true;
732#ifndef NO_SSL
733 cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
734#else
735 cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
736#endif
737 } else {
738 cm_do_log = true;
739 }
740 } else if(strcmp(argv[i], "--config") == 0 || strcmp(argv[i], "-C") == 0) {
741 i++;
742 if(argv[i] == NULL) {
743 STDERR_LOG("Missing argument\n");
744 return 1;
745 }
746 confpath = argv[i];
747#ifndef _PSP
748 } else if(strcmp(argv[i], "--logfile") == 0 || strcmp(argv[i], "-l") == 0) {
749 i++;
750 if(argv[i] == NULL) {
751 STDERR_LOG("Missing argument\n");
752 return 1;
753 }
754 if(logfile != NULL && logfile != stderr) {
755 fclose(logfile);
756 }
757 logfile = fopen(argv[i], "a");
758 if(logfile == NULL) {
759 STDERR_LOG("Failed to open logfile\n");
760 return 1;
761 }
762#endif
763 } else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
764 printf("Tewi HTTPd Tewi/%s\n", tw_get_version());
765 printf("Under public domain.\n");
766 printf("Original by 2024 Nishi\n");
767 printf("\n");
768 printf("Usage: %s [--config|-C config] [--verbose|-v] [--version|-V]\n", argv[0]);
769 printf("--config | -C config : Specify config\n");
770#ifndef _PSP
771 printf("--logfile | -l logfile : Specify logfile\n");
772#endif
773 printf("--verbose | -v : Verbose mode\n");
774 printf("--version | -V : Version information\n");
775 return 0;
776 } else {
777 STDERR_LOG("Unknown option: %s\n", argv[i]);
778 return 1;
779 }
780 }
781 }
782 }
783 tw_config_init();
784 if(tw_config_read(confpath) != 0) {
785 STDERR_LOG("Could not read the config\n");
786 return 1;
787 }
788 if(tw_server_init() != 0) {
789 STDERR_LOG("Could not initialize the server\n");
790 return 1;
791 }
792 sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
793 r = cm_strcat(tw_server, " running...");
794 cm_force_log(r);
795 free(r);
796#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
797 signal(SIGCHLD, SIG_IGN);
798 signal(SIGPIPE, SIG_IGN);
799#elif !defined(BUILD_GUI)
800 SetConsoleTitle(tw_server);
801#endif
802 return -1;
803}
Note: See TracBrowser for help on using the repository browser.