add -fPIC option to the C compiler, required in f31
[vsys.git] / vsyssh / vsyssh.c
1 /* gcc -Wall -O2 -g vsyssh.c -o vsyssh */
2 #define _XOPEN_SOURCE
3 #define _XOPEN_SOURCE_EXTENDED
4 #define _SVID_SOURCE
5 #define _GNU_SOURCE
6 #include <stdio.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/syscall.h>
14 #include <sys/wait.h>
15 #include <sys/time.h>
16 #include <sys/select.h>
17 #include <sys/resource.h>
18 #include <sys/mount.h>
19 #include <sys/vfs.h>
20 #include <sys/types.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <sched.h>
24 #include <stdarg.h>
25 #include <dirent.h>
26
27 void pipe_handler (int sig) {
28   printf("SIGPIPE");
29 }
30
31 #define FILELEN 256
32
33 int main(int argc, char **argv, char **envp) {
34
35   if ( (argc<2) || (strcmp(argv[1],"--help")==0) ) {
36     printf("Usage: vsyssh <vsys entry> [cmd]\n");
37     exit(1);
38   }
39
40   {
41     uid_t uid=getuid();
42     if (uid!=0) {
43       printf ("%s requires root privileges, please run under sudo\n",argv[0]);
44       exit(1);
45     }
46   }
47
48   {
49     int vfd0,vfd1;
50     char inf[FILELEN], outf[FILELEN];
51     int fatal=0;
52
53     signal(SIGPIPE,pipe_handler);
54     
55     sprintf(inf,"/vsys/%s.in",argv[1]);
56     sprintf(outf,"/vsys/%s.out",argv[1]);
57     vfd0 = open(outf,O_RDONLY|O_NONBLOCK);
58     if (vfd0<0) {
59       printf("Error opening vsys channel %s (%m)\n",outf);
60       fatal=1;
61     }
62     vfd1 = open(inf,O_WRONLY);
63     if (vfd1<0) {
64       printf("Error opening vsys channel %s (%m)\n",inf);
65       fatal=1;
66     }
67
68     if (fcntl(vfd0, F_SETFL, O_RDONLY) == -1) {
69       printf("Error making pipe blocking: %m\n");
70       fatal=1;
71     }
72
73     if (fatal) { exit(1);}
74
75     if (argc<3) {
76       /* interactive mode */
77       fd_set set;
78       char do_input = 1, do_output = 1;
79
80       while (1) {
81           int ret;
82           printf("vsys>");fflush(stdout);
83           FD_ZERO(&set);
84           if (do_input)
85             FD_SET(0, &set);
86           if (do_output)
87             FD_SET(vfd0, &set);
88           ret = select(vfd0+1, &set, NULL, NULL, NULL);
89           if (FD_ISSET(0,&set)) {
90             char lineread[2048];
91             int ret;
92             ret=read(0,lineread,2048);
93             /*printf ("read=%d\n",ret);*/
94             if (ret == 0)
95               do_input = 0;
96             lineread[ret]='\0';
97             printf ("writing %s\n",lineread);
98             write(vfd1,lineread,ret);
99           }
100           if (FD_ISSET(vfd0,&set)) {
101             char lineread[2048];
102             int ret;
103             ret = read(vfd0,lineread,2048);
104             if (ret == 0)
105               break;
106             write(1,lineread,ret);
107           }
108         }
109
110     } else {
111       /* line mode */
112       close(0);
113       close(1);
114
115       dup2(vfd0,0);
116       dup2(vfd1,1);
117       execve(argv[2],argv+2,envp);
118     }
119   }
120
121   return -1;
122
123 }