aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/lp/ipcopen.c
blob: a07858a8d8d6daefe0519fc0c997be6699a65fdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <u.h>
#include <libc.h>

int ppid;

/*
 * predefined
 */
void pass(int from, int to);


/*
 *  Connect to given datakit port
 */
main(int argc, char *argv[])
{
	int fd0, fd1;
	int cpid;
	char c;
	char *cp, *devdir, *buf;

	if (argc != 4) {
		fprint(2, "usage: %s destination network service\n", argv[0]);
		exits("incorrect number of arguments");
	}
	if(!(cp = malloc((long)(strlen(argv[1])+strlen(argv[2])+strlen(argv[3])+8)))) {
		perror("malloc");
		exits("malloc failed");
	}
	sprint(cp, "%s!%s!%s", argv[2], argv[1], argv[3]);
	if (dial(cp, &devdir, 0) < 0) {
		fprint(2, "dialing %s\n", cp);
		perror("dial");
		exits("can't dial");
	}

	/*
	 * Initialize the input fd, and copy bytes.
	 */

	if(!(buf = malloc((long)(strlen(devdir)+6)))) {
		perror("malloc");
		exits("malloc failed");
	}
	sprint(buf, "%s/data", devdir);
	fd0=open(buf, OREAD);
	fd1=open(buf, OWRITE);
	if(fd0<0 || fd1<0) {
		print("can't open", buf);
		exits("can't open port");
	}
	ppid = getpid();
	switch(cpid = fork()){
	case -1:
		perror("fork failed");
		exits("fork failed");
	case 0:
		close(0);
		close(fd1);
		pass(fd0, 1);	/* from remote */
		hangup(fd0);
		close(1);
		close(fd0);
		exits("");
	default:
		close(1);
		close(fd0);
		pass(0, fd1);	/* to remote */
		hangup(fd1);
		close(0);
		close(fd1);
		exits("");
	}
}

void
pass(int from, int to)
{
	char buf[1024];
	int ppid, cpid;
	int n, tot = 0;

	while ((n=read(from, buf, sizeof(buf))) > 0) {
		if (n==1 && tot==0 && *buf=='\0')
			break;
		tot += n;
		if (write(to, buf, n)!=n) {
			perror("pass write error");
			exits("pass write error");
		}
	}
}