Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <windows.h>
2
#include <stdio.h>
3
 
4
#pragma comment(lib, "wsock32.lib")
5
#pragma comment(lib, "shell32.lib")
6
 
7
char	*argv0 = "winplumb";
8
char errbuf[256];
9
unsigned long parseip(char*, char*);
10
typedef unsigned long ulong;
11
void oserror(void);
12
 
13
void
14
hnputl(void *p, unsigned long v)
15
{
16
	unsigned char *a;
17
 
18
	a = p;
19
	a[0] = v>>24;
20
	a[1] = v>>16;
21
	a[2] = v>>8;
22
	a[3] = v;
23
}
24
 
25
void
26
hnputs(void *p, unsigned short v)
27
{
28
	unsigned char *a;
29
 
30
	a = p;
31
	a[0] = v>>8;
32
	a[1] = v;
33
}
34
 
35
unsigned long
36
nhgetl(void *p)
37
{
38
	unsigned char *a;
39
	a = p;
40
	return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0);
41
}
42
 
43
unsigned short
44
nhgets(void *p)
45
{
46
	unsigned char *a;
47
	a = p;
48
	return (a[0]<<8)|(a[1]<<0);
49
}
50
 
51
 
52
int
53
main(int argc, char **argv)
54
{
55
	char *addr, *p, *q, to[4];
56
	char buf[2048];
57
	int port, fd, nfd, one, len, n, tot;
58
	ulong ip;
59
	struct sockaddr_in sin;
60
	WSADATA wasdat;
61
 
62
	if(argc != 1 && argc != 2){
63
	usage:
64
		fprintf(stderr, "usage: winplumb [tcp!ipaddr!port]\n");
65
		ExitThread(1);
66
	}
67
 
68
	if(argc == 1)
69
		addr = "tcp!*!17890";
70
	else
71
		addr = argv[1];
72
 
73
	strcpy(buf, addr);
74
	p = strchr(buf, '!');
75
	if(p == 0)
76
		goto usage;
77
	q = strchr(p+1, '!');
78
	if(q == 0)
79
		goto usage;
80
	*p++ = 0;
81
	*q++ = 0;
82
 
83
	if(strcmp(buf, "tcp") != 0)
84
		goto usage;
85
 
86
	port = atoi(q);
87
	if(strcmp(p, "*") == 0)
88
		ip = 0;
89
	else
90
		ip = parseip(to, p);
91
 
92
	WSAStartup(MAKEWORD(1, 1), &wasdat);
93
 
94
 
95
	fd = socket(AF_INET, SOCK_STREAM, 0);
96
	if(fd < 0){
97
		oserror();
98
		fprintf(stderr, "socket: %s\n", errbuf);
99
		ExitThread(1);
100
	}
101
 
102
	one = 1;
103
	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one) != 0){
104
		oserror();
105
		fprintf(stderr, "setsockopt nodelay: %s\n", errbuf);
106
	}
107
 
108
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof one) != 0){
109
		oserror();
110
		fprintf(stderr, "setsockopt reuse: %s\n", errbuf);
111
	}
112
	memset(&sin, 0, sizeof sin);
113
	sin.sin_family = AF_INET;
114
	hnputs(&sin.sin_port, port);
115
	hnputl(&sin.sin_addr, ip);
116
	if(bind(fd, (struct sockaddr*)&sin, sizeof sin) < 0){
117
		oserror();
118
		fprintf(stderr, "bind: %s\n", errbuf);
119
		ExitThread(1);
120
	}
121
 
122
	if(listen(fd, 5) < 0){
123
		oserror();
124
		fprintf(stderr, "listen: %s\n", errbuf);
125
		ExitThread(1);
126
	}
127
 
128
	for(;;){
129
		len = sizeof sin;
130
		nfd = accept(fd, (struct sockaddr*)&sin, &len);
131
		if(nfd < 0){
132
			oserror();
133
			fprintf(stderr, "accept: %s\n", errbuf);
134
			continue;
135
		}
136
		tot = 0;
137
		while(tot == 0 || buf[tot-1] != '\n'){
138
			n = recv(nfd, buf+tot, sizeof buf-tot, 0);
139
			if(n < 0)
140
				break;
141
			tot += n;
142
		}
143
		if(buf[tot-1] == '\n'){
144
			buf[tot-1] = 0;
145
			p = strchr(buf, ' ');
146
			if(p)
147
				*p++ = 0;
148
			ShellExecute(0, 0, buf, p, 0, SW_SHOWNORMAL);
149
		}
150
		closesocket(nfd);
151
	}
152
}
153
 
154
 
155
#define CLASS(p) ((*(unsigned char*)(p))>>6)
156
 
157
 
158
unsigned long
159
parseip(char *to, char *from)
160
{
161
	int i;
162
	char *p;
163
 
164
	p = from;
165
	memset(to, 0, 4);
166
	for(i = 0; i < 4 && *p; i++){
167
		to[i] = strtoul(p, &p, 0);
168
		if(*p == '.')
169
			p++;
170
	}
171
	switch(CLASS(to)){
172
	case 0:	/* class A - 1 byte net */
173
	case 1:
174
		if(i == 3){
175
			to[3] = to[2];
176
			to[2] = to[1];
177
			to[1] = 0;
178
		} else if (i == 2){
179
			to[3] = to[1];
180
			to[1] = 0;
181
		}
182
		break;
183
	case 2:	/* class B - 2 byte net */
184
		if(i == 3){
185
			to[3] = to[2];
186
			to[2] = 0;
187
		}
188
		break;
189
	}
190
	return nhgetl(to);
191
}
192
 
193
void
194
oserror(void)
195
{
196
	int e, r, i;
197
	char buf[200];
198
 
199
	e = GetLastError();
200
 
201
	r = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
202
		0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
203
		buf, sizeof(buf), 0);
204
 
205
	if(r == 0)
206
		sprintf(buf, "windows error %d", e);
207
 
208
 
209
	for(i = strlen(buf)-1; i>=0 && buf[i] == '\n' || buf[i] == '\r'; i--)
210
		buf[i] = 0;
211
 
212
	strcpy(errbuf, buf);
213
}
214
 
215
extern int	main(int, char*[]);
216
static int	args(char *argv[], int n, char *p);
217
 
218
int PASCAL
219
WinMain(HANDLE hInst, HANDLE hPrev, LPSTR arg, int nshow)
220
{
221
	int argc, n;
222
	char *p, **argv;
223
 
224
	/* conservative guess at the number of args */
225
	for(argc=5,p=arg; *p; p++)
226
		if(*p == ' ' || *p == '\t')
227
			argc++;
228
 
229
	argv = malloc(argc*sizeof(char*));
230
	argc = args(argv+1, argc, arg);
231
	argc++;
232
	argv[0] = argv0;
233
	main(argc, argv);
234
	ExitThread(0);
235
	return 0;
236
}
237
 
238
/*
239
 * Break the command line into arguments
240
 * The rules for this are not documented but appear to be the following
241
 * according to the source for the microsoft C library.
242
 * Words are seperated by space or tab
243
 * Words containing a space or tab can be quoted using "
244
 * 2N backslashes + " ==> N backslashes and end quote
245
 * 2N+1 backslashes + " ==> N backslashes + literal "
246
 * N backslashes not followed by " ==> N backslashes
247
 */
248
static int
249
args(char *argv[], int n, char *p)
250
{
251
	char *p2;
252
	int i, j, quote, nbs;
253
 
254
	for(i=0; *p && i<n-1; i++) {
255
		while(*p == ' ' || *p == '\t')
256
			p++;
257
		quote = 0;
258
		argv[i] = p2 = p;
259
		for(;*p; p++) {
260
			if(!quote && (*p == ' ' || *p == '\t'))
261
				break;
262
			for(nbs=0; *p == '\\'; p++,nbs++)
263
				;
264
			if(*p == '"') {
265
				for(j=0; j<(nbs>>1); j++)
266
					*p2++ = '\\';
267
				if(nbs&1)
268
					*p2++ = *p;
269
				else
270
					quote = !quote;
271
			} else {
272
				for(j=0; j<nbs; j++)
273
					*p2++ = '\\';
274
				*p2++ = *p;
275
			}
276
		}
277
		/* move p up one to avoid pointing to null at end of p2 */
278
		if(*p)
279
			p++;
280
		*p2 = 0;	
281
	}
282
	argv[i] = 0;
283
 
284
	return i;
285
}
286