Subversion Repositories Tewi

Rev

Rev 187 | Rev 191 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 nishi 1
/* $Id: main.c 189 2024-09-29 00:37:00Z nishi $ */
2
 
16 nishi 3
#define SOURCE
4
 
43 nishi 5
#include "../config.h"
6
 
189 nishi 7
#include <unistd.h>
3 nishi 8
#include <stdio.h>
9
#include <stdbool.h>
10
#include <string.h>
16 nishi 11
#include <signal.h>
116 nishi 12
#include <stdlib.h>
3 nishi 13
 
43 nishi 14
#ifndef NO_SSL
6 nishi 15
#include <openssl/opensslv.h>
43 nishi 16
#endif
6 nishi 17
 
3 nishi 18
#include <cm_log.h>
62 nishi 19
#include <cm_string.h>
3 nishi 20
 
4 nishi 21
#include "tw_config.h"
8 nishi 22
#include "tw_server.h"
3 nishi 23
#include "tw_version.h"
24
 
51 nishi 25
#ifdef __MINGW32__
26
#include <windows.h>
27
#endif
28
 
182 nishi 29
#ifdef _PSP
30
#include <pspkernel.h>
31
#include <pspdebug.h>
183 nishi 32
#include <pspsdk.h>
33
#include <psputility.h>
34
#include <pspctrl.h>
35
#include <pspnet_apctl.h>
36
#include <pspwlan.h>
182 nishi 37
 
38
PSP_MODULE_INFO("Tewi HTTPd", PSP_MODULE_USER, 1, 1);
39
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
40
 
41
#define printf(...) pspDebugScreenPrintf(__VA_ARGS__)
183 nishi 42
#define STDERR_LOG(...) pspDebugScreenPrintf(__VA_ARGS__)
189 nishi 43
#elif defined(__ps2sdk__)
44
#include <debug.h>
45
#include <sifrpc.h>
46
 
47
#define printf(...) scr_printf(__VA_ARGS__)
48
#define STDERR_LOG(...) scr_printf(__VA_ARGS__)
183 nishi 49
#else
50
#define STDERR_LOG(...) fprintf(stderr, __VA_ARGS__)
182 nishi 51
#endif
52
 
3 nishi 53
extern bool cm_do_log;
18 nishi 54
extern struct tw_config config;
62 nishi 55
extern FILE* logfile;
3 nishi 56
 
18 nishi 57
char tw_server[2048];
58
 
62 nishi 59
int startup(int argc, char** argv);
60
 
61
#ifdef SERVICE
62
SERVICE_STATUS status;
63
SERVICE_STATUS_HANDLE status_handle;
64
 
70 nishi 65
void WINAPI servhandler(DWORD control) {
66
	switch(control) {
67
	case SERVICE_CONTROL_STOP:
68
	case SERVICE_CONTROL_SHUTDOWN:
69
		status.dwCurrentState = SERVICE_STOP_PENDING;
70
		break;
62 nishi 71
	}
72
	SetServiceStatus(status_handle, &status);
73
}
74
 
70 nishi 75
void WINAPI servmain(DWORD argc, LPSTR* argv) {
62 nishi 76
	logfile = fopen(PREFIX "/logs/tewi.log", "a");
77
	if(logfile == NULL) logfile = stderr;
78
	status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
79
	status.dwCurrentState = SERVICE_START_PENDING;
80
	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
81
	status.dwWin32ExitCode = NO_ERROR;
82
	status.dwServiceSpecificExitCode = 0;
83
	status.dwCheckPoint = 0;
84
	status.dwWaitHint = 0;
85
	status_handle = RegisterServiceCtrlHandler("Tewi HTTPd", servhandler);
86
	if(status_handle == NULL) return;
87
	if(SetServiceStatus(status_handle, &status) == 0) return;
88
	int st = startup(argc, argv);
70 nishi 89
	if(st != -1) {
62 nishi 90
		status.dwWin32ExitCode = NO_ERROR;
91
		status.dwServiceSpecificExitCode = st;
92
		status.dwCurrentState = SERVICE_STOPPED;
93
		SetServiceStatus(status_handle, &status);
94
		return;
95
	}
96
	status.dwCurrentState = SERVICE_RUNNING;
97
	SetServiceStatus(status_handle, &status);
98
	tw_server_loop();
99
	status.dwCurrentState = SERVICE_STOPPED;
100
	SetServiceStatus(status_handle, &status);
101
}
102
#endif
103
 
183 nishi 104
int running = 1;
105
#ifdef _PSP
106
 
107
int psp_exit_callback(int arg1, int arg2, void* arg3) { running = 0; }
108
 
109
int psp_callback_thread(SceSize args, void* argp) {
110
	int cid;
111
	cid = sceKernelCreateCallback("Exit Call Back", psp_exit_callback, NULL);
112
	sceKernelRegisterExitCallback(cid);
113
	sceKernelSleepThreadCB();
114
	return 0;
115
}
116
#endif
117
 
3 nishi 118
int main(int argc, char** argv) {
62 nishi 119
	logfile = stderr;
120
#ifdef SERVICE
121
	SERVICE_TABLE_ENTRY table[] = {{"Tewi HTTPd", servmain}, {NULL, NULL}};
122
	StartServiceCtrlDispatcher(table);
123
#else
182 nishi 124
#ifdef _PSP
125
	pspDebugScreenInit();
126
	pspDebugScreenSetXY(0, 0);
183 nishi 127
	printf("PSP Bootstrap, Tewi/%s\n", tw_get_version());
128
	int thid = sceKernelCreateThread("update_thread", psp_callback_thread, 0x11, 0xfa0, 0, NULL);
129
	if(thid >= 0) {
130
		sceKernelStartThread(thid, 0, NULL);
131
	} else {
132
		printf("Failed to start thread\n");
133
		while(running) sceKernelDelayThread(50 * 1000);
134
		sceKernelExitGame();
135
	}
136
	sceCtrlSetSamplingCycle(0);
137
	sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
138
	sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
139
	sceUtilityLoadNetModule(PSP_NET_MODULE_INET);
140
	if(pspSdkInetInit()) {
141
		printf("Could not init the network\n");
142
		while(running) sceKernelDelayThread(50 * 1000);
143
		sceKernelExitGame();
144
	} else {
145
		printf("Network initialization successful\n");
146
	}
147
	if(sceWlanGetSwitchState() != 1) {
148
		printf("Turn the Wi-Fi switch on\n");
149
		while(sceWlanGetSwitchState() != 1) {
150
			sceKernelDelayThread(1000 * 1000);
151
		}
152
	} else {
153
		printf("Wi-Fi is turned on\n");
154
	}
155
	int i;
156
	int choice[100];
157
	int incr = 0;
158
	int last = 0;
159
	int cur = 0;
160
	for(i = 1; i < 100; i++) {
161
		choice[i - 1] = 0;
162
		netData name;
163
		netData data;
164
		if(sceUtilityCheckNetParam(i) != 0) continue;
165
		choice[incr++] = i;
166
		pspDebugScreenSetXY(0, 1 + 3 + incr - 1);
167
		if(incr == 1) printf("> ");
168
		pspDebugScreenSetXY(2, 1 + 3 + incr - 1);
169
		sceUtilityGetNetParam(i, 0, &name);
170
		sceUtilityGetNetParam(i, 1, &data);
171
		printf("SSID=%s", data.asString);
172
		sceUtilityGetNetParam(i, 4, &data);
173
		if(data.asString[0]) {
174
			sceUtilityGetNetParam(i, 5, &data);
175
			printf(" IPADDR=%s\n", data.asString);
176
		} else {
177
			printf(" DHCP\n");
178
		}
179
	}
180
	int press = 0;
181
	while(1) {
182
		if(!running) {
183
			sceKernelExitGame();
184
		}
185
		SceCtrlData c;
186
		sceCtrlReadBufferPositive(&c, 1);
187
		press = 0;
188
		if(c.Buttons & PSP_CTRL_DOWN) {
189
			if(cur < incr - 1) {
190
				cur++;
191
			}
192
			press = 1;
193
		} else if(c.Buttons & PSP_CTRL_UP) {
194
			if(cur > 0) {
195
				cur--;
196
			}
197
			press = -1;
198
		} else if(c.Buttons & PSP_CTRL_START) {
199
			break;
200
		}
201
		if(last != cur) {
202
			pspDebugScreenSetXY(0, 1 + 3 + last);
203
			printf("  ");
204
			pspDebugScreenSetXY(0, 1 + 3 + cur);
205
			printf("> ");
206
			last = cur;
207
		}
208
		if(press != 0) {
209
			while(1) {
210
				SceCtrlData c;
211
				sceCtrlReadBufferPositive(&c, 1);
212
				if(press == 1) {
213
					if(!(c.Buttons & PSP_CTRL_DOWN)) break;
214
				} else if(press == -1) {
215
					if(!(c.Buttons & PSP_CTRL_UP)) break;
216
				}
217
			}
218
		}
219
	}
220
	pspDebugScreenSetXY(0, 1 + 3 + incr + 1);
221
	int err = sceNetApctlConnect(choice[cur]);
222
	if(err != 0) {
223
		printf("Apctl initialization failure\n");
224
		while(running) sceKernelDelayThread(50 * 1000);
225
		sceKernelExitGame();
226
	} else {
227
		printf("Apctl initialization successful\n");
228
	}
229
	printf("Apctl connecting\n");
230
	while(1) {
231
		int state;
232
		err = sceNetApctlGetState(&state);
233
		if(err != 0) {
234
			printf("Apctl getting status failure\n");
235
			while(running) sceKernelDelayThread(50 * 1000);
236
			sceKernelExitGame();
237
		}
238
		if(state == 4) {
239
			break;
240
		}
241
		sceKernelDelayThread(50 * 1000);
242
	}
243
	union SceNetApctlInfo info;
244
	if(sceNetApctlGetInfo(8, &info) != 0) {
245
		printf("Got an unknown IP\n");
246
		while(running) sceKernelDelayThread(50 * 1000);
247
		sceKernelExitGame();
248
	}
249
	printf("Connected, My IP is %s\n", info.ip);
187 nishi 250
#elif defined(__PPU__)
251
	printf("PS3 Bootstrap, Tewi/%s\n", tw_get_version());
252
	netInitialize();
189 nishi 253
#elif defined(__ps2sdk__)
254
	SifInitRpc(0);
255
	init_scr();
256
	scr_printf("PS2 Bootstrap, Tewi/%s\n", tw_get_version());
257
	while(1)
258
		;
182 nishi 259
#endif
62 nishi 260
	int st = startup(argc, argv);
183 nishi 261
	if(st != -1) {
262
#ifdef _PSP
263
		printf("Error code %d\n", st);
264
		while(running) sceKernelDelayThread(50 * 1000);
265
		sceKernelExitGame();
266
#else
267
		return st;
268
#endif
269
	}
62 nishi 270
	tw_server_loop();
271
#endif
183 nishi 272
#ifdef _PSP
273
	sceKernelExitGame();
274
#endif
168 nishi 275
	return 0;
62 nishi 276
}
277
 
70 nishi 278
int startup(int argc, char** argv) {
3 nishi 279
	int i;
18 nishi 280
	const char* confpath = PREFIX "/etc/tewi.conf";
70 nishi 281
	if(argv != NULL) {
62 nishi 282
		for(i = 1; i < argc; i++) {
283
			if(argv[i][0] == '-') {
284
				if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
285
					if(!cm_do_log) {
286
						cm_do_log = true;
70 nishi 287
#ifndef NO_SSL
62 nishi 288
						cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
70 nishi 289
#else
62 nishi 290
						cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
70 nishi 291
#endif
62 nishi 292
					} else {
293
						cm_do_log = true;
294
					}
295
				} else if(strcmp(argv[i], "--config") == 0 || strcmp(argv[i], "-C") == 0) {
296
					i++;
297
					if(argv[i] == NULL) {
183 nishi 298
						STDERR_LOG("Missing argument\n");
62 nishi 299
						return 1;
300
					}
301
					confpath = argv[i];
182 nishi 302
#ifndef _PSP
117 nishi 303
				} else if(strcmp(argv[i], "--logfile") == 0 || strcmp(argv[i], "-l") == 0) {
304
					i++;
305
					if(argv[i] == NULL) {
183 nishi 306
						STDERR_LOG("Missing argument\n");
117 nishi 307
						return 1;
308
					}
309
					if(logfile != NULL && logfile != stderr) {
310
						fclose(logfile);
311
					}
312
					logfile = fopen(argv[i], "a");
313
					if(logfile == NULL) {
183 nishi 314
						STDERR_LOG("Failed to open logfile\n");
117 nishi 315
						return 1;
316
					}
182 nishi 317
#endif
62 nishi 318
				} else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
319
					printf("Tewi HTTPd Tewi/%s\n", tw_get_version());
320
					printf("Under public domain.\n");
321
					printf("Original by 2024 Nishi\n");
322
					printf("\n");
323
					printf("Usage: %s [--config|-C config] [--verbose|-v] [--version|-V]\n", argv[0]);
119 nishi 324
					printf("--config  | -C config      : Specify config\n");
182 nishi 325
#ifndef _PSP
119 nishi 326
					printf("--logfile | -l logfile     : Specify logfile\n");
182 nishi 327
#endif
119 nishi 328
					printf("--verbose | -v             : Verbose mode\n");
329
					printf("--version | -V             : Version information\n");
62 nishi 330
					return 0;
3 nishi 331
				} else {
183 nishi 332
					STDERR_LOG("Unknown option: %s\n", argv[i]);
4 nishi 333
					return 1;
334
				}
3 nishi 335
			}
336
		}
337
	}
6 nishi 338
	tw_config_init();
18 nishi 339
	if(tw_config_read(confpath) != 0) {
183 nishi 340
		STDERR_LOG("Could not read the config\n");
4 nishi 341
		return 1;
342
	}
8 nishi 343
	if(tw_server_init() != 0) {
183 nishi 344
		STDERR_LOG("Could not initialize the server\n");
8 nishi 345
		return 1;
346
	}
18 nishi 347
	sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
62 nishi 348
	char* r = cm_strcat(tw_server, " running...");
349
	cm_force_log(r);
350
	free(r);
16 nishi 351
#ifndef __MINGW32__
352
	signal(SIGCHLD, SIG_IGN);
90 nishi 353
	signal(SIGPIPE, SIG_IGN);
50 nishi 354
#else
355
	SetConsoleTitle(tw_server);
16 nishi 356
#endif
62 nishi 357
	return -1;
3 nishi 358
}