1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1990-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                                                                      *
19 ***********************************************************************/
20 /*
21  * File: server.c
22  */
23 
24 static char id[] = "\n@(#)$Id: vcs+ifs (AT&T Research) 1996-02-29 $\0\n";
25 
26 #include "ifs_agent.h"
27 #include "ifs_errno.h"
28 #include <cs.h>
29 #include <error.h>
30 #include <fs3d.h>
31 
32 #define	CST	( (State_t *) handle )
33 
34 /*
35  *	replies
36  *		I ... 	information
37  *		W ...	warning message
38  *		E ...	error message
39  */
40 
41 typedef struct
42 {
43     time_t	uptime;
44     char*	where;
45     int		out_static;
46     int		dormant;
47     int		who;
48     int		userid[ FD_SETSIZE ];
49     Sfio_t*	logfd;
50     char*	logfile;
51 } State_t;
52 
53 int	cserrno;
54 char	csusrmsg[ STRLEN ];
55 
56 char command_help[] = "\
57 help;	kill;	quit;	version;			\t\t\t\
58  record [logfile];					\t\t\t\
59  out pathname [version [pathname]]			\t\t\t\
60  instances pathname					\t\t\t\
61  mount url(pro:/usr:pw@host:pt/path) lpath time		\t\t\t\
62  connect protocol server user-info;			\t\t\t\
63  disconnect protocol server;				\t\t\t\
64  listdents local-path 					\t\t\t\
65  getfile   local-path					\t\t\t\
66  putfile   [source] local-path				\t\t\t\
67  userdef protocol arguments\n";
68 
69 void*
svc_init(handle,fdmax)70 svc_init( handle, fdmax )
71 void*	handle;
72 int	fdmax;
73 {
74     char	pidfile[ 80 ];
75     char	pid[ 80 ];
76 
77     (void) fs3d(FS3D_OP_OFF);
78     (void) memset( CST, 0, sizeof(State_t) );
79     CST->uptime = cs.time;
80     CST->who = getuid();
81     sfsprintf( pid, sizeof(pid), "%d", getpid() );
82     GetUserFile( pidfile, "vcs.pid" );
83     unlink( pidfile );
84     symlink( pid, pidfile );
85     IfsInitial();
86     return( handle );
87 }
88 
89 static int
svc_connect(handle,fd,id,clone,args)90 svc_connect( handle, fd, id, clone, args )
91 void*	handle;
92 int	fd;
93 Cs_id_t* id;
94 int	clone;
95 char**	args;
96 {
97     if ( CST->logfd ) {
98 	sfprintf( CST->logfd,
99 		"\n-- connect( fd=%d hid=%s pid=%d uid=%d gid=%d )\n",
100 		fd, csntoa(id->hid), id->pid, id->uid, id->gid );
101 	sfsync( CST->logfd );
102     }
103     if( fd < FD_SETSIZE )
104 	CST->userid[ fd ] = id->uid;
105     return (0);
106 }
107 
108 static int
svc_done(handle,sig)109 svc_done( handle, sig )
110 void*	handle;
111 int	sig;
112 {
113     if ( CST->logfd ) {
114 	sfprintf( CST->logfd, "-- svc_done( %d )\n", sig );
115 	sfsync( CST->logfd );
116     }
117     return (0);
118 }
119 
120 static int
version_info(buf,size,uid,own,uptm)121 version_info( buf, size, uid, own, uptm )
122 char	*buf;
123 int	size;
124 int	uid;
125 int	own;
126 time_t	uptm;
127 {
128     return sfsprintf( buf, size, "I Hi! %s, vcs[%d] by %s@%s at %s [%s]\n",
129 		fmtuid(uid), getpid(), fmtuid(own), csname(0), fmttime(NiL, uptm), id + 10 );
130 }
131 
132 static int
svc_read(handle,fd)133 svc_read( handle, fd )
134 void*	handle;
135 int	fd;
136 {
137     char	msgbuf[ 4 * PATH_MAX ];
138     char	ret[ 4 * PATH_MAX ];
139     char	*msg = msgbuf;
140     char	*argv[16], *ptr;
141     int		uid, n, argc;
142 
143     (void) fs3d(FS3D_OP_OFF);
144     csusrmsg[0] = '\0';
145     uid = CST->userid[fd];
146     if( (n = csread( fd, msg, sizeof(msgbuf), CS_LINE )) <= 0 )
147 	return -1;
148     msg[ n - 1 ] = '\0';
149     if( CST->logfd ) {
150 	time_t	t;
151 
152 	t = cs.time;
153 	(void) tmform(ret, "%i", &t);
154 	sfprintf( CST->logfd, "[%s]\n%s\n", ret, msg );
155     }
156     while ((argc = tokscan( msg, &msg, " %v ", argv, elementsof(argv))) > 0) {
157 	n = sizeof(ret);
158 	switch ( argv[0][0] ) {
159 	    case 'c':
160 		n = IfsConnect( ret, n, uid, argc, argv );
161 		break;
162 	    case 'd':
163 		n = IfsDisconnect( ret, n, uid, argc, argv );
164 		break;
165 	    case 'g':
166 		n = IfsGetFile( ret, n, uid, argc, argv );
167 		break;
168 	    case 'h':
169 		n = sfsprintf(ret, n, command_help );
170 		break;
171 	    case 'i':
172 		n = rscs_instances( argc, argv, ret, &n );
173 		break;
174 	    case 'k':
175 		exit( 1 );
176 		break;
177 	    case 'l':
178 		n = IfsListDEnts( ret, n, uid, argc, argv );
179 		break;
180 	    case 'm':
181 		n = IfsMount( ret, n, uid, argc, argv );
182 		break;
183 	    case 'o':
184 		switch (argv[0][1]) {
185 		case 'p':
186 		    n = IfsReal(ret, n, uid, argc, argv);
187 		    break;
188 		default:
189 		    n = rscs_out( argc, argv, ret, &n );
190 		    break;
191 		}
192 		break;
193 	    case 'p':
194 		n = IfsPutFile( ret, n, uid, argc, argv );
195 		break;
196 	    case 'q':
197 		n = sfsprintf(ret, n, "I bye\n");
198 		break;
199 	    case 'r':
200 		ptr = (argc < 2 ? "/tmp/jvcs.log" : argv[1]);
201 		if ( CST->logfd ) {
202 		    sfclose( CST->logfd );
203 		    n = sfsprintf(ret, n, "I stop log %s (%d)\n",
204 			CST->logfile, CST->logfd );
205 		    CST->logfd = 0;
206 		} else if( (CST->logfd = sfopen(NULL,ptr,"a")) == NULL ) {
207 		    n = sfsprintf(ret, n, "E cannot open %s\n", ptr );
208 	 	} else {
209 		    CST->logfile = strdup( ptr );
210 		    sfprintf( CST->logfd, "\n" );
211 		    n = sfsprintf(ret, n, "I record %s\n", ptr );
212 		}
213 		break;
214 	    case 's':
215 		n = IfsReal(ret, n, uid, argc, argv);
216 		break;
217 	    case 'v':
218 		n = version_info( ret, sizeof(ret), uid, CST->who, CST->uptime );
219 		break;
220 	    case 'u':
221 		n = IfsUserDef( ret, n, uid, argc, argv );
222 		break;
223 	    case 'D':
224 		error_info.trace = -(int)strtol(argv[1], (char**)0, 0);
225 		n = sfsprintf(ret, n, "I debug level %d\n", -error_info.trace );
226 		break;
227 	    default:
228 		n = sfsprintf(ret, n, "E invalid command %s\n", argv[0] );
229 		break;
230 	}
231 	if (write(fd, ret, n) != n || *argv[0] == 'q')
232 	    return -1;
233     }
234     if ( CST->logfd ) {
235 	if( ret[n-1] == '\n' )
236 	    ret[n-1] = '\0';
237 	sfprintf( CST->logfd, "\t%s\n", ret );
238 	sfsync( CST->logfd );
239     }
240     return (0);
241 }
242 
243 static int
svc_timeout(handle)244 svc_timeout( handle )
245 void*	handle;
246 {
247     return (0);
248 }
249 
250 int
main(argc,argv)251 main( argc, argv )
252 int	argc;
253 char**	argv;
254 {
255     static State_t	state;
256 
257     NoP(argc);
258     csserve( &state, argv[1], svc_init, svc_done, svc_connect,
259 		svc_read, NULL, svc_timeout);
260     exit(1);
261 }
262 
263