+static int rsync_module(int fd, int i)
+{
+ int argc=0;
+ char *argv[MAX_ARGS];
+ char **argp;
+ char line[1024];
+
+ module_id = i;
+
+ if (lp_read_only(i))
+ read_only = 1;
+
+ rprintf(FERROR,"rsyncd starting\n");
+
+ if (chroot(lp_path(i))) {
+ io_printf(fd,"ERROR: chroot failed\n");
+ return -1;
+ }
+
+ if (chdir("/")) {
+ io_printf(fd,"ERROR: chdir failed\n");
+ return -1;
+ }
+
+ if (setgid(lp_gid(i))) {
+ io_printf(fd,"ERROR: setgid failed\n");
+ return -1;
+ }
+
+ if (setuid(lp_uid(i))) {
+ io_printf(fd,"ERROR: setuid failed\n");
+ return -1;
+ }
+
+ io_printf(fd,"RSYNCD: OK\n");
+
+ argv[argc++] = "rsyncd";
+
+ while (1) {
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+
+ if (!*line) break;
+
+ argv[argc] = strdup(line);
+ if (!argv[argc]) {
+ return -1;
+ }
+
+ argc++;
+ if (argc == MAX_ARGS) {
+ return -1;
+ }
+ }
+
+ parse_arguments(argc, argv);
+
+ /* don't allow the logs to be flooded too fast */
+ if (verbose > 1) verbose = 1;
+
+ argc -= optind;
+ argp = argv + optind;
+ optind = 0;
+
+ start_server(fd, fd, argc, argp);
+
+ return 0;
+}
+
+static void send_listing(int fd)
+{
+ int n = lp_numservices();
+ int i;
+
+ for (i=0;i<n;i++)
+ if (lp_list(i))
+ io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
+}
+
+/* this is called when a socket connection is established to a client
+ and we want to start talking. The setup of the system is done from
+ here */
+static int start_daemon(int fd)
+{
+ char line[1024];
+ char *motd;
+
+ set_socket_options(fd,"SO_KEEPALIVE");
+
+ io_printf(fd,"RSYNCD %d\n", PROTOCOL_VERSION);
+
+ motd = lp_motd_file();
+ if (*motd) {
+ FILE *f = fopen(motd,"r");
+ while (f && !feof(f)) {
+ int len = fread(line, 1, sizeof(line)-1, f);
+ if (len > 0) {
+ line[len] = 0;
+ io_printf(fd,"%s", line);
+ }
+ }
+ if (f) fclose(f);
+ io_printf(fd,"\n");
+ }
+
+ /* read a single line indicating the resource that is wanted */
+ while (1) {
+ int i;
+
+ line[0] = 0;
+ if (!read_line(fd, line, sizeof(line)-1)) {
+ return -1;
+ }
+
+ if (!*line || strcmp(line,"#list")==0) {
+ send_listing(fd);
+ return -1;
+ }
+
+ if (*line == '#') {
+ /* it's some sort of command that I don't understand */
+ io_printf(fd,"ERROR: Unknown command '%s'\n", line);
+ return -1;
+ }
+
+ i = lp_number(line);
+ if (i == -1) {
+ io_printf(fd,"ERROR: Unknown module '%s'\n", line);
+ return -1;
+ }
+
+ return rsync_module(fd, i);
+ }
+
+ return 0;
+}
+
+
+static int daemon_main(void)
+{
+ if (!lp_load(RSYNCD_CONF)) {
+ exit_cleanup(1);
+ }
+
+ if (is_a_socket(STDIN_FILENO)) {
+ /* we are running via inetd */
+ return start_daemon(STDIN_FILENO);
+ }
+
+ become_daemon();
+
+ return start_accept_loop(port, start_daemon);
+}
+