Subversion Repositories Tewi

Rev

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