/* * main.c - central part of the DNBD server application * Copyright (C) 2006 Thorsten Zitterell */ #include #include #include #include #include /* network includes */ #include #include #include #include #define DNBD_USERSPACE 1 #include "../common/dnbd-cliserv.h" #include "server.h" #include "query.h" #include "net.h" #include "filer.h" static int verbose = 0; static int running = 1; /* * function: handle_signal(): set global variable running to 0 if signal arrives */ void handle_signal(int signum) { running = 0; } void server_help(void) { fprintf(stderr, "dnbd-server, version %s\n", DNBD_VERSION); fprintf(stderr, "Usage: dnbd-server -m
-d -i \n"); fprintf(stderr, "\n"); fprintf(stderr, "description:\n"); fprintf(stderr, " -m|--mcast \n"); fprintf(stderr, " -d|--device \n"); fprintf(stderr, " -i|--id \n"); fprintf(stderr, " -t|--threads \n"); } /* * function: server_init(): parse command lines */ server_info_t *server_init(int argc, char **argv) { /* cmd * -1: error * 0: not defined * 1: serve */ int cmd = 0; server_info_t *server_info = NULL; server_info = (server_info_t *) malloc(sizeof(server_info_t)); if (!server_info) return NULL; memset(server_info, 0, sizeof(server_info_t)); server_info->threads = 1; /* return value for getopt */ int c; while (1) { static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"mcast", required_argument, 0, 'm'}, {"device", required_argument, 0, 'd'}, {"threads", required_argument, 0, 't'}, {"id", required_argument, 0, 'i'}, {0, 0, 0, 0} }; /* option index for getopt_long */ int option_index = 0; c = getopt_long(argc, argv, "vm:d:i:t:", long_options, &option_index); /* at end of options? */ if (c == -1) break; /* cmd = (cmd ? -1 : xx) is used to set cmd when it was unset (0) before. Otherwise save error value */ switch (c) { case 'v': verbose++; break; case 'm': server_info->mnet = optarg; /* multicast address */ break; case 'd': cmd = (cmd ? -1 : 2); /* device/file */ server_info->filename = optarg; break; case 'i': if (sscanf(optarg, "%u",&server_info->id) != 1) { fprintf(stderr,"ERROR: Id not a 16bit-integer (>0)\n"); cmd = -1; } break; case 't': if (sscanf(optarg, "%u",&server_info->threads) != 1) { fprintf(stderr,"ERROR: Number of threads is wrong (>0)\n"); cmd = -1; } break; default: cmd = -1; } if (cmd < 0) break; } /* no/wrong command given? */ if (cmd <= 0) { server_help(); goto out_free; } if (!server_info->mnet) { fprintf(stderr, "ERROR: multicast group was not set!\n"); goto out_free; } if (!(server_info->id > 0)) { fprintf(stderr, "ERROR: unique id not set or not valid!\n"); goto out_free; } if (!(server_info->threads > 0)) { fprintf(stderr, "ERROR: number of threads is not valid!\n"); goto out_free; } /* call function for command */ goto out; out_free: if (server_info) free(server_info); server_info = NULL; out: return server_info; } /* * function: main(): server startup */ int main(int argc, char **argv) { server_info_t *server_info; signal(SIGINT, handle_signal); /* parse and verify command line options */ if (!(server_info = server_init(argc, argv))) { fprintf(stderr, "ERROR: Parsing arguments!\n"); goto out_server; } /* initialize network configuration and start listener thread */ if (!(server_info->net_info = net_init(server_info->mnet))) { fprintf(stderr, "ERROR: Initializing net!\n"); goto out_net; } if (!(server_info->filer_info = filer_init(server_info->filename))) { fprintf(stderr, "ERROR: Initializing filer!\n"); goto out_filer; } /* initialize threads to handle requests */ if (! (server_info->query_info = query_init(server_info->net_info, server_info->filer_info, server_info->id, server_info->threads))) { fprintf(stderr, "ERROR: Initializing query!\n"); goto out_query; } while (running) pause(); fprintf(stdout, "cleaning up...\n"); out_query: if (server_info->filer_info) free(server_info->filer_info); out_filer: if (server_info->net_info) free(server_info->net_info); out_net: if (server_info) { free(server_info); } out_server: return 0; }