2
* Copyright 2005, Scott Balneaves <sbalneav@ltsp.org>
4
* Mainline handling for the Linux Terminal Server Project File Server Daemon.
11
#include <sys/socket.h>
13
#include <netinet/in.h>
14
#include <arpa/inet.h>
24
#include "ltspfsd_functions.h"
31
int debug; /* Debug level. 0 = no debug */
32
int readonly; /* If true, make filesystem "read only" */
33
int noauth; /* If true, skip authentication */
34
int syslogopen; /* If true, then log to syslog, else stderr */
35
char *mountpoint; /* Point we're "mounted" to */
36
int authenticated; /* Mountpoint length */
37
int mounted; /* Automounter status */
40
* Signal handler function for SIGCHLD
50
pid = wait(&stat); /* reap our child process */
56
* Signal handler function for SIGTERM
63
info("Recieved SIGTERM, shutting down\n");
77
int main(int argc, char *argv[])
80
int sockfd, newsockfd, childpid;
81
struct sockaddr_in cli_addr;
90
* We can begin to parse command line options.
93
debug = readonly = opterr = noauth = 0;
95
while ((c = getopt (argc, argv, "rad")) != -1) {
107
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
115
* Some initialization work. We call daemon(), which will chdir to /
116
* so that the daemon won't lock any filesystems. The daemon() call also
117
* closes STDIN, STDOUT, and STDERR, and forks. Then, set up our umask,
118
* and redirect the SIGCHLD and SIGTERM signals to handlers.
121
if (!debug) { /* if debug's false, then background */
123
signal(SIGCHLD, sig_chld);
124
signal(SIGTERM, sig_term);
135
openlog(argv[0], LOG_PID, LOG_USER);
143
sockfd = bindsocket(SERVER_PORT);
146
* Log informational message to indicate program starting
149
info("Program started\n");
152
* Calculate the length of the cli_addr structure (needed for the accept)
155
clilen = sizeof(cli_addr);
160
* Accept incoming connection
163
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
165
error_die("Can't accept connection");
167
if (!debug) /* In debug mode, don't fork */
173
error_die("fork error"); /* If fork fails, something's wrong */
174
else if (childpid == 0) {
175
close(sockfd); /* Child process, pass work off */
176
handle_connection(newsockfd);
177
exit(OK); /* exit child, SIGCHLD sent */
179
close(newsockfd); /* parent */
181
return OK; /* return 0 from main */
185
* handle_connection is where the "work" gets done. Anything you want to "do"
186
* as a network daemon should be done here.
188
* Dispatch ltspfs calls to ltspfs_dispatch.
191
void handle_connection(int sockfd)
196
char line[LTSP_MAXBUF];
198
fd_set set; /* For select */
199
struct timeval automount_timeout; /* Timeout */
206
FD_SET(sockfd, &set);
207
xdrmem_create(&in, line, LTSP_MAXBUF, XDR_DECODE);
211
* Sigh. I really hate to have to re-duplicate most of the readn
212
* functionality here, but it's simply cleaner to not butcher the _readn
213
* and _writen primitives just to handle automount timeouts. Soooo....
216
automount_timeout.tv_sec = AUTOMOUNT_TIMEOUT;
217
automount_timeout.tv_usec = 0;
218
r = select(FD_SETSIZE, &set, NULL, NULL, &automount_timeout);
220
error_die("handle_connection: select error\n");
223
am_umount(mountpoint); /* this will return */
224
continue; /* Back to the top of the for(;;) loop */
227
nleft = BYTES_PER_XDR_UNIT;
230
nread = read(sockfd, lineptr, nleft);
232
error_die("handle_connection: readline error\n");
234
return; /* EOF, connection closed */
242
info("Packet length: %d\n", i);
243
n = readn(sockfd, lineptr, (i - BYTES_PER_XDR_UNIT));
245
return; /* connection closed */
247
error_die("handle_connection: readline error\n");
250
* OK We've got our command line, pass this off to ltspfs_dispatch
254
info("Packet buffer: ");
255
for (q = 0; q < i; q++)
260
ltspfs_dispatch(sockfd, &in);
263
* Well, we're back. Reset our position to the beginning.