Subversion Repositories Tewi

Rev

Rev 182 | Rev 187 | 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 183 2024-09-27 16:15:15Z 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);
182 nishi 243
#endif
62 nishi 244
	int st = startup(argc, argv);
183 nishi 245
	if(st != -1) {
246
#ifdef _PSP
247
		printf("Error code %d\n", st);
248
		while(running) sceKernelDelayThread(50 * 1000);
249
		sceKernelExitGame();
250
#else
251
		return st;
252
#endif
253
	}
62 nishi 254
	tw_server_loop();
255
#endif
183 nishi 256
#ifdef _PSP
257
	sceKernelExitGame();
258
#endif
168 nishi 259
	return 0;
62 nishi 260
}
261
 
70 nishi 262
int startup(int argc, char** argv) {
3 nishi 263
	int i;
18 nishi 264
	const char* confpath = PREFIX "/etc/tewi.conf";
70 nishi 265
	if(argv != NULL) {
62 nishi 266
		for(i = 1; i < argc; i++) {
267
			if(argv[i][0] == '-') {
268
				if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
269
					if(!cm_do_log) {
270
						cm_do_log = true;
70 nishi 271
#ifndef NO_SSL
62 nishi 272
						cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
70 nishi 273
#else
62 nishi 274
						cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
70 nishi 275
#endif
62 nishi 276
					} else {
277
						cm_do_log = true;
278
					}
279
				} else if(strcmp(argv[i], "--config") == 0 || strcmp(argv[i], "-C") == 0) {
280
					i++;
281
					if(argv[i] == NULL) {
183 nishi 282
						STDERR_LOG("Missing argument\n");
62 nishi 283
						return 1;
284
					}
285
					confpath = argv[i];
182 nishi 286
#ifndef _PSP
117 nishi 287
				} else if(strcmp(argv[i], "--logfile") == 0 || strcmp(argv[i], "-l") == 0) {
288
					i++;
289
					if(argv[i] == NULL) {
183 nishi 290
						STDERR_LOG("Missing argument\n");
117 nishi 291
						return 1;
292
					}
293
					if(logfile != NULL && logfile != stderr) {
294
						fclose(logfile);
295
					}
296
					logfile = fopen(argv[i], "a");
297
					if(logfile == NULL) {
183 nishi 298
						STDERR_LOG("Failed to open logfile\n");
117 nishi 299
						return 1;
300
					}
182 nishi 301
#endif
62 nishi 302
				} else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0) {
303
					printf("Tewi HTTPd Tewi/%s\n", tw_get_version());
304
					printf("Under public domain.\n");
305
					printf("Original by 2024 Nishi\n");
306
					printf("\n");
307
					printf("Usage: %s [--config|-C config] [--verbose|-v] [--version|-V]\n", argv[0]);
119 nishi 308
					printf("--config  | -C config      : Specify config\n");
182 nishi 309
#ifndef _PSP
119 nishi 310
					printf("--logfile | -l logfile     : Specify logfile\n");
182 nishi 311
#endif
119 nishi 312
					printf("--verbose | -v             : Verbose mode\n");
313
					printf("--version | -V             : Version information\n");
62 nishi 314
					return 0;
3 nishi 315
				} else {
183 nishi 316
					STDERR_LOG("Unknown option: %s\n", argv[i]);
4 nishi 317
					return 1;
318
				}
3 nishi 319
			}
320
		}
321
	}
6 nishi 322
	tw_config_init();
18 nishi 323
	if(tw_config_read(confpath) != 0) {
183 nishi 324
		STDERR_LOG("Could not read the config\n");
4 nishi 325
		return 1;
326
	}
8 nishi 327
	if(tw_server_init() != 0) {
183 nishi 328
		STDERR_LOG("Could not initialize the server\n");
8 nishi 329
		return 1;
330
	}
18 nishi 331
	sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
62 nishi 332
	char* r = cm_strcat(tw_server, " running...");
333
	cm_force_log(r);
334
	free(r);
16 nishi 335
#ifndef __MINGW32__
336
	signal(SIGCHLD, SIG_IGN);
90 nishi 337
	signal(SIGPIPE, SIG_IGN);
50 nishi 338
#else
339
	SetConsoleTitle(tw_server);
16 nishi 340
#endif
62 nishi 341
	return -1;
3 nishi 342
}