Main Page   File List   Globals  

server.c

Go to the documentation of this file.
00001 /*
00002  * FER - LSS - PPMPS
00003  * Fakultet elektrotehnike i računarstva (http://www.fer.hr/)
00004  * Unska 3, 10000 Zagreb, Hrvatska
00005  * 
00006  * (c) 2001 FER, Zagreb. Sva prava pridržana.
00007  * (c) 2001 LSS. Sva prava pridržana.
00008  */
00009 
00017 
00018 /* test mode is default mode upon server startup */
00019 #define TEST_MODE
00020 
00021 #ifndef __SERVER
00022 #include <server.h>
00023 #endif
00024 
00025 /* help message */
00026 const char *help =
00027 "ADC-ZESOI server v" VERSION ".\n"
00028 "Usage:\n"
00029 " server [options]\n"
00030 "Options are:\n"
00031 " -h --help      Prints this help message.\n"
00032 #ifdef TEST_MODE
00033 " -t --test      Test mode - server creates random data (default).\n"
00034 "    --notest    Test mode disabled. Can't be used together with -t.\n"
00035 #else
00036 " -t --test      Test mode - server creates random data.\n"
00037 "    --notest    Test mode disabled (default). Can't be used together with -t.\n"
00038 #endif
00039 " -p <port>, --port=<port>   Sets port to <port>. If ommited default port\n"
00040 "                for ADC-ZESOI protocol (port 7777) is used.\n"
00041 " -a --auth      Requires authentification. Default is no\n"
00042 "                authentfication required (option -n).\n"
00043 " -n --noauth    Disable authentification (default). Can't be\n"
00044 "                used together with -a.\n"
00045 "    --nullok    Allow access for passwordless accounts.\n"
00046 "    --maxretries=<retries>   Sets maximum number of login attempts to\n"
00047 "                given number. Default value is 3 login attempts.\n"
00048 " -v --version   Show version number.\n";
00049 
00050 int main(int argc, char *argv[])
00051 {
00052   char *buffer; /* temporary buffer */
00053   char *hostname; /* hostname (automaticaly determined) */
00054   int sockfd; /* socket handle */
00055   int new_fd; /* connection handle */
00056   int argno; /* used for argument processing */
00057   char *p1, *p2; /* used for argument processing */
00058   unsigned long int port_param; /* used for argument processing */
00059   unsigned long int retries_param; /* used for argument processing */
00060   short authorisation; /* authorisation flag */
00061   short test_mode; /* test mode flag */
00062   unsigned short int port; /* default port */
00063   struct sockaddr_in my_addr;
00064   struct sockaddr_in their_addr;
00065   struct hostent *hostdata;
00066   socklen_t sin_size, kpl_size;
00067   int kpl_value;
00068   pid_t pid; /* process ID number */
00069   command_t status; /* current server status */
00070   command_t command; /* status change caused by current command */
00071 
00072   /* open socket */
00073   sockfd = socket(AF_INET, SOCK_STREAM, 0);
00074   if (-1 == sockfd)
00075     {
00076       perror("ADC-ZESOI: Socket");
00077       exit(EXIT_FAILURE);
00078     }
00079 
00080   /* set defaults */
00081   port = PORT;
00082   global_max_login_no = MAX_LOGIN;
00083   global_null_ok = FALSE;
00084   authorisation = AUTHNOTPROCESSED;
00085   test_mode = MODENOTPROCESSED;
00086   global_stream_pid = -1;
00087   kpl_value = 1;
00088   kpl_size = sizeof(int);
00089 
00090   /* set signal handlers */
00091   signal(SIGCHLD, cleanallchildren);
00092 
00093   /* parse parameters */
00094   for(argno=1; argno<argc; argno++)
00095     {
00096       if ('-' == argv[argno][0])
00097         {
00098           /* process argument */
00099           if ('-' == argv[argno][1])
00100             {
00101               /**** long command argument ************************************/
00102               if (0 == strcmp(argv[argno]+2, "test"))
00103                 {
00104                   if (MODENOTPROCESSED != test_mode)
00105                     {
00106                       goto conflicting_parameter;
00107                     }
00108                   test_mode = MODEPROCESSED;
00109                   global_test_mode = TRUE;
00110                 }
00111               else if (0 == strcmp(argv[argno]+2, "notest"))
00112                 {
00113                   if (MODENOTPROCESSED != test_mode)
00114                     {
00115                       goto conflicting_parameter;
00116                     }
00117                   test_mode = MODEPROCESSED;
00118                   global_test_mode = FALSE;
00119                 }
00120               else if (0 == strcmp(argv[argno]+2, "help"))
00121                 {
00122                   fprintf(stdout, "%s", help);
00123                   exit(EXIT_SUCCESS);
00124                 }
00125               else if (0 == strcmp(argv[argno]+2, "auth"))
00126                 {
00127                   if (AUTHNOTPROCESSED != authorisation)
00128                     {
00129                       goto conflicting_parameter;
00130                     }
00131                   authorisation = AUTH;
00132                 }
00133               else if (0 == strcmp(argv[argno]+2, "noauth"))
00134                 {
00135                   if (AUTHNOTPROCESSED != authorisation)
00136                     {
00137                       goto conflicting_parameter;
00138                     }
00139                   authorisation = NOAUTH;
00140                 }
00141               else if (0 == strcmp(argv[argno]+2, "nullok"))
00142                 {
00143                   global_null_ok = TRUE;
00144                 }
00145               else if (0 == strcmp(argv[argno]+2, "version"))
00146                 {
00147                   fprintf(stdout, "ADC-ZESOI server version: " VERSION "\n");
00148                   exit(EXIT_SUCCESS);
00149                 }
00150               else if( (strlen(argv[argno]+2) > 10) &&
00151                        (0 == strncmp(argv[argno]+2, "maxretries=", 11)) )
00152                 {
00153                   errno = 0;
00154                   p1 = argv[argno] + 13;
00155                   retries_param = strtoul(p1, &p2, 0);
00156                   if ( (ERANGE == errno) ||
00157                        (p2 == p1) ||
00158                        (UINT_MAX < retries_param) ||
00159                        (0 == retries_param) )
00160                     {
00161                       fprintf(stderr, "Invalid number of retries, using default value (3).\n");
00162                     }
00163                   else
00164                     {
00165                       global_max_login_no = (unsigned int)retries_param;
00166                     }
00167                 }
00168               else if ( (strlen(argv[argno]+2) > 4) &&
00169                         (0 == strncmp(argv[argno]+2, "port=", 5)) )
00170                 {
00171                   errno = 0;
00172                   p1 = argv[argno] + 7;
00173                   port_param = strtoul(p1, &p2, 0);
00174                   if ( (ERANGE == errno) ||
00175                        (p2 == p1) ||
00176                        (USHRT_MAX < port_param) )
00177                     {
00178                       fprintf(stderr, "Invalid port number, using default value (port 7777).\n");
00179                     }
00180                   else
00181                     {
00182                       port = (unsigned short int)port_param;
00183                     }
00184                 }
00185               else
00186                 {
00187                   /* unkonwn parameter */
00188                   goto invalid_parameter;
00189                 }
00190             }
00191           else if('\0' != argv[argno][1])
00192             {
00193               /**** short command argument ***********************************/
00194               if ('\0' != argv[argno][2])
00195                 {
00196                   /* more than one letter */
00197                   goto invalid_parameter;
00198                 }
00199               switch (argv[argno][1])
00200                 {
00201                 case 't':
00202                   if (MODENOTPROCESSED != test_mode)
00203                     {
00204                       goto conflicting_parameter;
00205                     }
00206                   test_mode = MODEPROCESSED;
00207                   global_test_mode = TRUE;
00208                   break;
00209 
00210                 case 'p':
00211                   if (argno+1 == argc)
00212                     {
00213                       goto invalid_parameter;
00214                     }
00215                   argno += 1;
00216                   errno = 0;
00217                   p1 = argv[argno];
00218                   port_param = strtol(p1, &p2, 0);
00219                   if ( (ERANGE == errno) ||
00220                        (p2 == p1) ||
00221                        (USHRT_MAX < port_param) )
00222                     {
00223                       fprintf(stderr, "Invalid port number, using default value (port 7777).\n");
00224                     }
00225                   else
00226                     {
00227                       port = (unsigned short int)port_param;
00228                     }
00229                   break;
00230 
00231                 case 'a':
00232                   if (AUTHNOTPROCESSED != authorisation)
00233                     {
00234                       goto conflicting_parameter;
00235                     }
00236                   authorisation = AUTH;
00237                   break;
00238 
00239                 case 'n':
00240                   if (AUTHNOTPROCESSED != authorisation)
00241                     {
00242                       goto conflicting_parameter;
00243                     }
00244                   authorisation = NOAUTH;
00245                   break;
00246 
00247                 case 'v':
00248                   fprintf(stdout, "ADC-ZESOI server version: " VERSION "\n");
00249                   exit(EXIT_SUCCESS);
00250                   break;
00251 
00252                 case 'h':
00253                   fprintf(stdout, "%s", help);
00254                   exit(EXIT_SUCCESS);
00255                   break;
00256 
00257                 default:
00258                 invalid_parameter:
00259                   fprintf(stderr, "Invalid option %s.\n%s", argv[argno], help);
00260                   exit(EXIT_FAILURE);
00261                 conflicting_parameter:
00262                   fprintf(stderr, "Conflicting option %s.\n%s", argv[argno], help);
00263                   exit(EXIT_FAILURE);
00264                 }
00265               /* switch */
00266             }
00267           else
00268             {
00269               /* only - without command letter */
00270               goto invalid_parameter;
00271             }
00272         }
00273       else
00274         {
00275           /* error - invalid parameter */
00276           goto invalid_parameter;
00277         }
00278     }
00279   /* for */
00280 
00281   /* set defaults */
00282   if (AUTHNOTPROCESSED == authorisation)
00283     {
00284       authorisation = NOAUTH;
00285     }
00286   my_addr.sin_family = AF_INET;
00287   my_addr.sin_port = htons(port);
00288   my_addr.sin_addr.s_addr = INADDR_ANY;
00289   bzero(&(my_addr.sin_zero), 8);
00290 #ifdef DEBUG
00291   fprintf(stderr, "ADC-ZESOI: Port set to %hd.\n", port);
00292 #endif
00293 
00294   /* check UID */
00295   if (ROOT_UID != geteuid())
00296     {
00297       /* can't preform authentification - force test mode */
00298       authorisation = NOAUTH;
00299       global_test_mode = TRUE;
00300       fprintf(stderr, "Server is not setuid root.\n"
00301               "Test mode is forced and authentification disabled.\n");
00302     }
00303 
00304   /* bind socket and start listening */
00305   if (-1 == bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)))
00306     {
00307       perror("ADC-ZESOI: Bind");
00308       exit(EXIT_FAILURE);
00309     }
00310   if (-1 == listen(sockfd, BACKLOG))
00311     {
00312       perror("ADC-ZESOI: Listen");
00313       exit(EXIT_FAILURE);
00314     }
00315 
00316   /* determine host name */
00317   hostdata = gethostbyname("localhost");
00318   if (NULL == hostdata)
00319     {
00320       hostname = (char *)malloc(10*sizeof(char));
00321       strcpy(hostname, "localhost");
00322     }
00323   else
00324     {
00325       hostname = hostdata->h_name;
00326     }
00327 #ifdef DEBUG
00328   fprintf(stderr, "ADC-ZESOI: Hostname set to %s.\n", hostname);
00329 #endif
00330 
00331   /* main loop */
00332   while (TRUE)
00333     {
00334       /* wait for connection */
00335       sin_size = sizeof(struct sockaddr_in);
00336       new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
00337       if (-1 == new_fd)
00338         {
00339           perror("ADC-ZESOI: Accept");
00340           continue;
00341         }
00342 #ifdef DEBUG
00343       fprintf(stderr, "ADC-ZESOI: Got connection from %s.\n", inet_ntoa(their_addr.sin_addr));
00344 #endif
00345 
00346       /* set signal handlers */
00347       global_fd = new_fd;
00348       signal(SIGPIPE, lostconnection);
00349 
00350       /* fork */
00351       pid = fork();
00352       global_pid = pid;
00353       if (0 == pid)
00354         {
00355           /* this is the child process */
00356 
00357           /* print welcome message */
00358           buffer = (void *)malloc( ( strlen(ok_message[MN_WELCOME])
00359                                      + strlen(hostname) + 2 )
00360                                    * sizeof(char) );
00361           if (NULL == buffer)
00362             {
00363               close(new_fd);
00364               exit(EXIT_FAILURE);
00365             }
00366           sprintf(buffer, ok_message[MN_WELCOME], hostname);
00367           if (-1 == send(new_fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
00368           free(buffer);
00369 
00370           /* set defaults */
00371           status.command_no = CN_NO_COMMAND;
00372           status.error_code = EC_NO_ERROR;
00373           status.help_code = CN_NO_COMMAND;
00374           status.no_of_samples = DEFAULT_NO_SAMPLES;
00375           status.channel = DEFAULT_CHANNEL;
00376           status.resolution = DEFAULT_RESOLUTION;
00377           status.authorised = authorisation;
00378           status.stream = FALSE;
00379           status.exit = FALSE;
00380           status.username[0] = '\0';
00381           status.password[0] = '\0';
00382 
00383           /* command loop */
00384           while (FALSE == status.exit)
00385             {
00386               /* read command */
00387               buffer = readcommand(new_fd);
00388               if (NULL == buffer) break;
00389 #ifdef DEBUG
00390               fprintf(stderr, "ADC-ZESOI: Received %d bytes.\n", strlen(buffer));
00391 #endif
00392 
00393               /* parse command */
00394               command = parsecommand(buffer, status);
00395 #ifdef DEBUG
00396               fprintf(stderr, "ADC-ZESOI: Command number: %d Error code: %d\n",
00397                       command.command_no, command.error_code);
00398 #endif
00399 
00400               /* execute command */
00401               status = executecommand(command, status, new_fd);
00402 
00403               /* clean up */
00404               free(buffer);
00405             }
00406 
00407           /* print goodbye message */
00408           buffer = (void *)malloc( ( strlen(ok_message[MN_GOODBYE])
00409                                      + strlen(hostname) + 2 )
00410                                    * sizeof(char) );
00411           if (NULL == buffer)
00412             {
00413               close(new_fd);
00414               exit(EXIT_FAILURE);
00415             }
00416           sprintf(buffer, ok_message[MN_GOODBYE], hostname);
00417           if (-1 == send(new_fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
00418           free(buffer);
00419           close(new_fd);
00420           exit(EXIT_SUCCESS);
00421         }
00422       else if (-1 == pid)
00423         {
00424           perror("ADC-ZESOI: Fork");
00425         }
00426       else
00427         {
00428           /* this is the parent process */
00429 #ifdef DEBUG
00430           fprintf(stderr, "ADC-ZESOI: Started child process %d.\n", pid);
00431 #endif
00432         }
00433       close(new_fd);
00434     }
00435 }
00436 /* main */
00437 
00438 
00439 
00440 
00442 
00450 char*
00451 readcommand(int fd)
00452 {
00453   char *buffer, *new_buffer;
00454   size_t m;
00455   ssize_t n;
00456 
00457   m = 1;
00458   new_buffer = buffer = (char *)malloc((m*BUFFER_SIZE + 1)*sizeof(char));
00459   if (NULL == buffer) return buffer;
00460   while( (n = read(fd, (void *)new_buffer, BUFFER_SIZE)) )
00461     {
00462       if (-1 == n)
00463         {
00464           free(buffer);
00465 #ifdef DEBUG
00466           perror("ADC-ZESOI: Read");
00467 #endif
00468           return NULL;
00469         }
00470       else if (n < BUFFER_SIZE)
00471         {
00472           break;
00473         }
00474       else
00475         {
00476           m += 1;
00477           new_buffer = (char *)realloc((void *)buffer, (m*BUFFER_SIZE+1)*sizeof(char));
00478           if (NULL == new_buffer) break;
00479           buffer = new_buffer;
00480           new_buffer = buffer + ((m - 1) * BUFFER_SIZE);
00481         }
00482     }
00483   buffer[(m - 1) * BUFFER_SIZE + n] = 0;
00484 
00485   return buffer;
00486 }
00487 /* readcommand */
00488 
00489 
00490 
00491 
00493 
00502 command_t
00503 parsecommand (const char *input, command_t status)
00504 {
00505   command_t c;
00506   char *i, *j;
00507   char *temp;
00508   int n;
00509   int command_no, channel, no_of_samples;
00510 
00511   /* copy status to new command */
00512   c.command_no = CN_ERROR;
00513   c.error_code = EC_PARSE_FAILURE;
00514   c.help_code = CN_NO_COMMAND;
00515   c.no_of_samples = status.no_of_samples;
00516   c.channel = status.channel;
00517   c.authorised = status.authorised;
00518   c.stream = FALSE;
00519   c.exit = FALSE;
00520   c.resolution = status.resolution;
00521   strcpy(c.username, status.username);
00522   strcpy(c.password, status.password);
00523 
00524   /* preprocess input data */
00525   temp = (char *)malloc((strlen(input) + 1)*sizeof(char));
00526   if ((NULL == temp)) return c;
00527   n = 0;
00528   while(0 != *(input + n)) *(temp + n++) = toupper( *(input + n) );
00529   *(temp + n) = 0;
00530 
00531   /* tokenize input data - find first token */
00532   i = strtok(temp, DELIMITERS);
00533 #ifdef DEBUG
00534   fprintf(stderr, "ADC-ZESOI: First token is: %s.\n", i);
00535 #endif
00536 
00537 
00538   /* identify command */
00539   if (NULL == i)
00540     {
00541       command_no = MAX_CN_NO;
00542     }
00543   else
00544     {
00545       for (command_no=0; command_no<MAX_CN_NO; command_no++)
00546         {
00547           if(0 == strcmp(command[command_no],i)) break;
00548         }
00549     }
00550 
00551   /* parse if identified */
00552   j = strtok(NULL, DELIMITERS);
00553   switch (command_no)
00554     {
00555 
00556     case CN_USER:
00557       /**** command USER *********************************************/
00558       c.command_no = command_no;
00559       if (NOAUTH == c.authorised)
00560         {
00561           c.error_code = EC_USER_NO_AUTHORISATION_REQUIRED;
00562           break;
00563         }
00564       if (NULL == j)
00565         {
00566           c.error_code = EC_USER_NO_NAME;
00567           break;
00568         }
00569       i = strtok(NULL, DELIMITERS);
00570       if(NULL != i)
00571         {
00572           c.error_code = EC_USER_ERROR; 
00573         }
00574       else if(strlen(j) > MAX_LENGTH)
00575         {
00576           c.error_code = EC_USER_OVERRUN;
00577         }
00578       else
00579         {
00580           strcpy(temp, input);
00581           j = strtok(temp, DELIMITERS);
00582           j = strtok(NULL, DELIMITERS);
00583           strcpy(c.username, j);
00584           c.error_code = EC_NO_ERROR;
00585         }
00586       break;
00587 
00588     case CN_PASS:
00589       /**** command PASS *********************************************/
00590       c.command_no = command_no;
00591       if (NOAUTH == c.authorised)
00592         {
00593           c.error_code = EC_PASS_NO_AUTHORISATION_REQUIRED;
00594           break;
00595         }
00596       else if (AUTHORISED == c.authorised)
00597         {
00598           c.error_code = EC_PASS_ALREADY_AUTHORISED;
00599           break;
00600         }
00601       if (NULL == j)
00602         {
00603           if (FALSE == global_null_ok)
00604             {
00605               c.error_code = EC_PASS_NO_PASS;
00606               break;
00607             }
00608           c.error_code = EC_NO_ERROR;
00609           c.password[0] = '\0';
00610           break;
00611         }
00612       i = strtok(NULL, DELIMITERS);
00613       if(NULL != i)
00614         {
00615           c.error_code = EC_PASS_ERROR;
00616         }
00617       else if(strlen(j) > MAX_LENGTH)
00618         {
00619           c.error_code = EC_PASS_OVERRUN;
00620         }
00621       else if(strlen(c.username) == 0)
00622         {
00623           c.error_code = EC_PASS_NO_USER_NAME;
00624         }
00625       else
00626         {
00627           strcpy(temp, input);
00628           j = strtok(temp, DELIMITERS);
00629           j = strtok(NULL, DELIMITERS);
00630           strcpy(c.password, j);
00631           c.error_code = EC_NO_ERROR;
00632         }
00633       break;
00634 
00635     case CN_SET:
00636       /**** command SET **********************************************/
00637       c.command_no = command_no;
00638       if ( (NOTAUTHORISED == c.authorised) ||
00639            (AUTH == c.authorised) )
00640         {
00641           c.error_code = EC_SET_UNAUTHORISED;
00642           break;
00643         }
00644       if (NULL == j)
00645         {
00646           c.error_code = EC_SET_NO_CHANNEL; 
00647           break;
00648         }
00649       i = strtok(NULL, DELIMITERS);
00650       if(NULL != i)
00651         {
00652           c.error_code = EC_SET_ERROR;
00653           break;
00654         }
00655       channel = atoi(j);
00656       if ((channel < MIN_CHANNEL) || (channel > MAX_CHANNEL))
00657         {
00658           c.error_code = EC_SET_INVALID;
00659           break;
00660         }
00661       c.channel = channel;
00662       c.error_code = EC_NO_ERROR;
00663       break;
00664 
00665     case CN_GET:
00666       /**** command GET **********************************************/
00667       c.command_no = command_no;
00668       if ( (NOTAUTHORISED == c.authorised) ||
00669            (AUTH == c.authorised) )
00670         {
00671           c.error_code = EC_GET_UNAUTHORISED;
00672           break;
00673         }
00674       if (NULL == j)
00675         {
00676           c.error_code = EC_GET_NO_ARGUMENT; 
00677           break;
00678         }
00679       i = strtok(NULL, DELIMITERS);
00680       if(NULL != i)
00681         {
00682           c.error_code = EC_GET_ERROR;
00683           break;
00684         }
00685       if (0 == strcmp(j, GET_STREAM_ARGUMENT))
00686         {
00687           c.no_of_samples = DATA_STREAM;
00688         }
00689       else
00690         {
00691           no_of_samples = atoi(j);
00692           if (no_of_samples <= 0)
00693             {
00694               c.error_code = EC_GET_INVALID_NO_OF_SAMPLES;
00695               break;
00696             }
00697           c.no_of_samples = no_of_samples;
00698         }
00699       c.error_code = EC_NO_ERROR;
00700       break;
00701 
00702     case CN_RESOLUTION:
00703       /**** command RESOLUTION ***************************************/
00704       c.command_no = command_no;
00705       if ( (NOTAUTHORISED == c.authorised) ||
00706            (AUTH == c.authorised) )
00707         {
00708           c.error_code = EC_RESOLUTION_UNAUTHORISED;
00709           break;
00710         }
00711       if (NULL == j)
00712         {
00713           c.error_code = EC_RESOLUTION_NO_ARGUMENT;
00714           break;
00715         }
00716       i = strtok(NULL, DELIMITERS);
00717       if(NULL != i)
00718         {
00719           c.error_code = EC_RESOLUTION_ERROR;
00720           break;
00721         }
00722       if ( (0 == strcmp(j, RESOLUTION_HIGH)) ||
00723            (0 == strcmp(j, RESOLUTION_H)) )
00724         {
00725           c.resolution = 'H';
00726         }
00727       else if ( (0 == strcmp(j, RESOLUTION_MEDIUM)) ||
00728                 (0 == strcmp(j, RESOLUTION_M)) )
00729         {
00730           c.resolution = 'M';
00731         }
00732       else if ( (0 == strcmp(j, RESOLUTION_LOW)) ||
00733                 (0 == strcmp(j, RESOLUTION_L)) )
00734         {
00735           c.resolution = 'L';
00736         }
00737       else
00738         {
00739           c.error_code = EC_RESOLUTION_INVALID;
00740           break;
00741         }
00742       c.error_code = EC_NO_ERROR;
00743       break;
00744 
00745     case CN_START:
00746       /**** command START ********************************************/
00747       c.command_no = command_no;
00748       if ( (NOTAUTHORISED == c.authorised) ||
00749            (AUTH == c.authorised) )
00750         {
00751           c.error_code = EC_START_UNAUTHORISED;
00752         }
00753       else
00754         {
00755           c.error_code = EC_NO_ERROR;
00756         }
00757       break;
00758 
00759     case CN_STOP:
00760       /**** command STOP *********************************************/
00761       c.command_no = command_no;
00762       if (DATA_STREAM != c.no_of_samples)
00763         {
00764           c.error_code = EC_STOP_NO_STREAM;
00765         }
00766       else if ( (NOTAUTHORISED == c.authorised) ||
00767                 (AUTH == c.authorised) )
00768         {
00769           c.error_code = EC_STOP_UNAUTHORISED;
00770         }
00771       else
00772         {
00773           c.error_code = EC_NO_ERROR;
00774         }
00775       break;
00776 
00777     case CN_HELP:
00778       /**** command HELP *********************************************/
00779       c.command_no = command_no;
00780       if (NULL == j)
00781         {
00782           c.error_code = EC_NO_ERROR;
00783           c.help_code = MAX_CN_NO;
00784           break;
00785         }
00786       i = strtok(NULL, DELIMITERS);
00787       if(NULL != i)
00788         {
00789           c.error_code = EC_HELP_INVALID_COMMAND;
00790           c.help_code = CN_NO_COMMAND;
00791           break;
00792         }
00793       for (command_no=0; command_no<MAX_CN_NO; command_no++)
00794         {
00795           if(0 == strcmp(command[command_no],j)) break;
00796         }
00797       if (command_no == MAX_CN_NO)
00798         {
00799           c.error_code = EC_HELP_INVALID_COMMAND;
00800           c.help_code = CN_NO_COMMAND;
00801           break;
00802         }
00803       c.error_code = EC_NO_ERROR;
00804       c.help_code = command_no;
00805       break;
00806 
00807     case CN_BYE:
00808     case CN_EXIT:
00809     case CN_QUIT:
00810       /**** commands BYE, EXIT, QUIT *********************************/
00811       c.command_no = command_no;
00812       c.error_code = EC_NO_ERROR;
00813       c.exit = TRUE;
00814       break;
00815 
00816     case MAX_CN_NO:
00817     default:
00818       /**** unknown command ******************************************/
00819       c.command_no = CN_ERROR;
00820       c.error_code = EC_UNKNOWN_COMMAND;
00821     }
00822 
00823   /* cleanup */
00824   free(temp);
00825 
00826   return c;
00827 }
00828 /* parsecommand */
00829 
00830 
00831 
00832 
00834 
00842 command_t
00843 executecommand (command_t c, command_t status, int fd)
00844 {
00845   static unsigned int login_counter; /* login attempt counter */
00846   char *hostname; /* hostname (automaticaly determined) */
00847   struct hostent *hostdata;
00848   char *buffer, *p1, *p2, *p3; /* buffers and pointers */
00849   long size; /* size of password file */
00850   FILE *passwd; /* password file */
00851   size_t length; /* username length */
00852   int acquire_status; /* result of data acquisition */
00853   int i;
00854   pid_t pid;
00855 
00856   if ( (TRUE == status.stream) &&
00857        (CN_STOP != c.command_no) )
00858     {
00859       /* stream is active (server is sending samples) */
00860       /* and command is not STOP */
00861 
00862       /*******************************************************/
00863       /* SIMPLY IGNORE THIS SITUATION - User has requested a */
00864       /* data stream and has issued  an invalid command or a */
00865       /* command different than STOP. As data stream can not */
00866       /* be interrupted, simply do nothing.                  */
00867       /*******************************************************/
00868 #ifdef DEBUG
00869       fprintf(stderr, "ADC-ZESOI: WARNING: Stream is acitve and command isn't STOP.\n");
00870 #endif
00871 
00872     }
00873   else if (c.error_code >= 0)
00874     {
00875       /* parse error - print error message */
00876       if (-1 == send(fd, error_message[c.error_code],
00877                      strlen(error_message[c.error_code]), 0))
00878         {
00879           perror("ADC-ZESOI: Send");
00880         }
00881     }
00882   else
00883     {
00884       /* execute command */
00885       switch (c.command_no)
00886         {
00887           
00888         case CN_USER:
00889           /**** command USER *********************************************/
00890           strcpy(status.username, c.username);
00891 
00892           /* reset status */
00893           status.authorised = NOTAUTHORISED;
00894           login_counter = 0;
00895 
00896           /* print OK message */
00897           buffer = (void *)malloc( ( strlen(ok_message[MN_USER])
00898                                      + strlen(c.username) + 2 )
00899                                    * sizeof(char) );
00900           if (NULL == buffer)
00901             {
00902               exit(EXIT_FAILURE);
00903             }
00904           sprintf(buffer, ok_message[MN_USER], c.username);
00905           if (-1 == send(fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
00906           free(buffer);
00907           break;
00908           
00909         case CN_PASS:
00910           /**** command PASS *********************************************/
00911           strcpy(status.password, c.password);
00912 
00913           /* assume passwords are shadowed */
00914           passwd = fopen("/etc/shadow","rt");
00915           if (NULL == passwd)
00916             {
00917               perror("ADC-ZESOI: /etc/shadow");
00918               /* passwords aren't shadowed */
00919               passwd = fopen("/etc/passwd","rt");
00920               if (NULL == passwd)
00921                 {
00922                   perror("ADC-ZESOI: /etc/passwd");
00923                   break;
00924                 }
00925             }
00926 #ifdef DEBUG
00927           fprintf(stderr, "ADC-ZESOI: Password file opened.\n");
00928 #endif
00929 
00930           /* load passwords into temporary buffer */
00931           fseek(passwd, 0, SEEK_END);
00932           size = ftell(passwd);
00933           rewind(passwd);
00934           buffer = (char *)malloc( (size+1)*sizeof(char) );
00935           if (NULL == buffer)
00936             {
00937               perror("ADC-ZESOI: Authentification failed");
00938               fclose(passwd);
00939               break;
00940             }
00941           fread(buffer, size, sizeof(char), passwd);
00942           buffer[size] = '\0';
00943           fclose(passwd);
00944 
00945           /* locate user */
00946           length = strlen(status.username);
00947           p1 = strtok(buffer, "\n\x0A\x0D");
00948           do
00949             {
00950               if (0 == strncmp(p1, status.username, length))
00951                 {
00952                   /* user found */
00953                   /* extract password field delimited with : */
00954                   p2 = strstr(p1, ":") + 1;
00955                   p3 = strstr(p2, ":");
00956                   p3[0] = '\0';
00957 
00958                   /* check for paswordless accounts */
00959                   if (('\0' == p2[0]) && (FALSE == global_null_ok))
00960                     {
00961                       if (-1 == send(fd, error_message[EC_PASS_PASSWORDLESS],
00962                                      strlen(error_message[EC_PASS_PASSWORDLESS]), 0) )
00963                         {
00964                           perror("ADC-ZESOI: Send");
00965                         }
00966 
00967                       /* clean up */
00968                       memset(buffer, 0, size*sizeof(char));
00969                       free(buffer);
00970                       break;
00971                     }
00972 
00973                   /* account locked */
00974                   if (0 == strncmp(p2, "!", 1))
00975                     {
00976                       /* clean up */
00977                       memset(buffer, 0, size*sizeof(char));
00978                       free(buffer);
00979 
00980                       if (-1 == send(fd, error_message[EC_PASS_LOCKED],
00981                                      strlen(error_message[EC_PASS_LOCKED]), 0) )
00982                         {
00983                           perror("ADC-ZESOI: Send");
00984                         }
00985 
00986                       break;
00987                     }
00988 
00989                   /* special account - deny access */
00990                   if (0 == strncmp(p2, "*", 1))
00991                     {
00992                       /* clean up */
00993                       memset(buffer, 0, size*sizeof(char));
00994                       free(buffer);
00995 
00996                       /* print error message */
00997                       buffer = (void *)malloc( (strlen(error_message[EC_PASS_DENIED]) +
00998                                                 strlen(status.username) + 1) * sizeof(char) );
00999                       if (NULL == buffer)
01000                         {
01001                           exit(EXIT_FAILURE);
01002                         }
01003                       sprintf(buffer, error_message[EC_PASS_DENIED], status.username);
01004                       if (-1 == send(fd, buffer, strlen(buffer), 0)) 
01005                         {
01006                           perror("ADC-ZESOI: Send");
01007                         }
01008                       free(buffer);
01009                       break;
01010                     }
01011 
01012                   if (0 == strcmp(p2, crypt(status.password, p2)))
01013                     {
01014                       /* authorisation successful */
01015                       status.authorised = AUTHORISED;
01016 
01017                       /* clean up */
01018                       memset(status.password, 0, strlen(status.password));
01019                       memset(buffer, 0, size*sizeof(char));
01020                       free(buffer);
01021 
01022                       /* print OK message */
01023                       buffer = (void *)malloc( (strlen(ok_message[MN_PASS]) +
01024                                                 strlen(status.username) + 1) * sizeof(char) );
01025                       if (NULL == buffer)
01026                         {
01027                           exit(EXIT_FAILURE);
01028                         }
01029                       sprintf(buffer, ok_message[MN_PASS], status.username);
01030                       if (-1 == send(fd, buffer, strlen(buffer), 0)) 
01031                         {
01032                           perror("ADC-ZESOI: Send");
01033                         }
01034                       free(buffer);
01035                       break;
01036                     }
01037                   else
01038                     {
01039                       /* authorisation failed */
01040                       /* increase login attempt counter and sleep for some time */
01041                       login_counter += 1;
01042                       sleep(LOGIN_SLEEP_TIME);
01043 
01044                       if (-1 == send(fd, error_message[EC_PASS_INCORRECT],
01045                                      strlen(error_message[EC_PASS_INCORRECT]), 0) )
01046                         {
01047                           perror("ADC-ZESOI: Send");
01048                         }
01049 
01050                       /* terminate connection if maximum login count is reached */
01051                       if (login_counter >= global_max_login_no)
01052                         {
01053                           if (-1 == send(fd, error_message[EC_PASS_DISCONNECTED],
01054                                          strlen(error_message[EC_PASS_DISCONNECTED]), 0) )
01055                             {
01056                               perror("ADC-ZESOI: Send");
01057                             }
01058 
01059                           /* print goodbye message */
01060                           hostdata = gethostbyname("localhost");
01061                           if (NULL == hostdata)
01062                             {
01063                               hostname = (char *)malloc(10*sizeof(char));
01064                               strcpy(hostname, "localhost");
01065                             }
01066                           else
01067                             {
01068                               hostname = hostdata->h_name;
01069                             }
01070                           buffer = (void *)malloc( ( strlen(ok_message[MN_GOODBYE])
01071                                                      + strlen(hostname) + 2 )
01072                                                    * sizeof(char) );
01073                           if (NULL == buffer)
01074                             {
01075                               close(fd);
01076                               exit(EXIT_FAILURE);
01077                             }
01078                           sprintf(buffer, ok_message[MN_GOODBYE], hostname);
01079                           if (-1 == send(fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
01080                           free(buffer);
01081 #ifdef DEBUG
01082                           fprintf(stderr, "ADC-ZESOI: Terminating connection - maximum number of login attempts.\n");
01083 #endif
01084                           exit(EXIT_SUCCESS);
01085                         }
01086 
01087                       /* clean up */
01088                       memset(buffer, 0, size*sizeof(char));
01089                       free(buffer);
01090 
01091                       break;
01092                     }
01093                 }
01094               p1 = strtok(NULL, "\n\x0A\x0D");
01095             }
01096           while (p1 != NULL);
01097 
01098           if (NULL == p1)
01099             {
01100               /* user not found */
01101               if (-1 == send(fd, error_message[EC_USER_UNKNOWN],
01102                              strlen(error_message[EC_USER_UNKNOWN]), 0) )
01103                 {
01104                   perror("ADC-ZESOI: Send");
01105                 }
01106 
01107               /* cleanup */
01108               memset(buffer, 0, size*sizeof(char));
01109               free(buffer);
01110             }
01111           break;
01112           
01113         case CN_SET:
01114           /**** command SET **********************************************/
01115           status.channel = c.channel;
01116           buffer = (void *)malloc( ( strlen(ok_message[MN_SET])
01117                                      + 10 )
01118                                    * sizeof(char) );
01119           if (NULL == buffer)
01120             {
01121               exit(EXIT_FAILURE);
01122             }
01123           sprintf(buffer, ok_message[MN_SET], c.channel);
01124           if (-1 == send(fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
01125           free(buffer);
01126           break;
01127 
01128         case CN_GET:
01129           /**** command GET **********************************************/
01130           if (DATA_STREAM == c.no_of_samples)
01131             {
01132               status.no_of_samples = DATA_STREAM;
01133               if (-1 == send(fd, ok_message[MN_GET_STREAM],
01134                              strlen(ok_message[MN_GET_STREAM]), 0) )
01135                 {
01136                   perror("ADC-ZESOI: Send");
01137                 }
01138             }
01139           else
01140             {
01141               status.no_of_samples = c.no_of_samples;
01142               buffer = (void *)malloc( ( strlen(ok_message[MN_GET_SAMPLES])
01143                                          + 25 )
01144                                        * sizeof(char) );
01145               if (NULL == buffer)
01146                 {
01147                   exit(EXIT_FAILURE);
01148                 }
01149               sprintf(buffer, ok_message[MN_GET_SAMPLES], c.no_of_samples);
01150               if (-1 == send(fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
01151               free(buffer);
01152             }
01153           break;
01154 
01155         case CN_RESOLUTION:
01156           /**** command RESOLUTION ***************************************/
01157           status.resolution = c.resolution;
01158           buffer = (void *)malloc( ( strlen(ok_message[MN_RESOLUTION])
01159                                      + 2 )
01160                                    * sizeof(char) );
01161           if (NULL == buffer)
01162             {
01163               exit(EXIT_FAILURE);
01164             }
01165           sprintf(buffer, ok_message[MN_RESOLUTION], c.resolution);
01166           if (-1 == send(fd, buffer, strlen(buffer), 0)) perror("ADC-ZESOI: Send");
01167           free(buffer);
01168           break;
01169 
01170         case CN_START:
01171           /**** command START ********************************************/
01172           if (DATA_STREAM == status.no_of_samples)
01173             {
01174               /* sending data stream */
01175               status.stream = TRUE;
01176 
01177               /* set signal handler */
01178               signal(SIGTERM, stopstream);
01179 
01180               /* fork */
01181               pid = fork();
01182               global_stream_pid = pid;
01183               if (0 == pid)
01184                 {
01185                   /* this is a child process */
01186                   if (-1 == send(fd, ok_message[MN_START_STREAM],
01187                                  strlen(ok_message[MN_START_STREAM]), 0) )
01188                     {
01189                       perror("ADC-ZESOI: Send stream");
01190                     }
01191 
01192                   /* print stream information data */
01193                   /* test mode information */
01194                   if (TRUE == global_test_mode)
01195                     {
01196                       if (-1 == send(fd, ok_message[MN_START_TEST_STREAM],
01197                                      strlen(ok_message[MN_START_TEST_STREAM]), 0))
01198                         {
01199                           perror("ADC-ZESOI: Send stream");
01200                         }
01201                     }
01202                   /* stream resolution */
01203                   buffer = (void *)malloc( ( strlen(ok_message[MN_START_RESOLUTION])
01204                                              + 2 )
01205                                            * sizeof(char) );
01206                   if (NULL == buffer)
01207                     {
01208                       exit(EXIT_FAILURE);
01209                     }
01210                   sprintf(buffer, ok_message[MN_START_RESOLUTION], status.resolution);
01211                   if (-1 == send(fd, buffer, strlen(buffer), 0))
01212                     {
01213                       perror("ADC-ZESOI: Send stream");
01214                     }
01215                   free(buffer);
01216 
01217                   /* allocate buffer for sending */
01218                   if (TRUE == global_test_mode)
01219                     {
01220                       buffer = (void *)malloc(80 * sizeof(char));
01221                       if (NULL == buffer)
01222                         {
01223                           exit(EXIT_FAILURE);
01224                         }
01225                     }
01226                   /* send until SIGTERM is received */
01227                   while (TRUE)
01228                     {
01229                       if (TRUE == global_test_mode)
01230                         {
01231                           /* sending random data values for testing purposes */
01232                           sprintf(buffer, "%f\n", (double)rand()/RAND_MAX);
01233                           if (-1 == send(fd, buffer, strlen(buffer), 0))
01234                             {
01235                               perror("ADC-ZESOI: Send stream");
01236                             }
01237 #ifdef SLEEP
01238                           sleep(1);
01239 #endif
01240                         }
01241                       else
01242                         {
01243                           /* send STREAM_CHUNK samples at the time */
01244                           acquire_status = acquireandsendsamples(fd, STREAM_CHUNK,
01245                                                                  status.channel, status.resolution);
01246                           if (ACQUIRE_FAILURE == acquire_status)
01247                             {
01248                               fprintf(stderr, "ADC-ZESOI: Data acquisition error.\n");
01249                             }
01250                         }
01251                     }
01252                 }
01253               else if (-1 == pid)
01254                 {
01255                   perror("ADC-ZESOI: Fork:");
01256                 }
01257             }
01258           else
01259             {
01260               /* sending samples */
01261               buffer = (void *)malloc( ( strlen(ok_message[MN_START_SAMPLES])
01262                                          + 20 )
01263                                        * sizeof(char) );
01264               if (NULL==buffer)
01265                 {
01266                   exit(EXIT_FAILURE);
01267                 }
01268               sprintf(buffer, ok_message[MN_START_SAMPLES], status.no_of_samples);
01269               if (-1 == send(fd, buffer, strlen(buffer), 0))
01270                 {
01271                   perror("ADC-ZESOI: Send samples");
01272                 }
01273               free(buffer);
01274 
01275               /* print stream information data */
01276               /* test mode information */
01277               if (TRUE == global_test_mode)
01278                 {
01279                   buffer = (void *)malloc( ( strlen(ok_message[MN_START_TEST_SAMPLES])
01280                                              + 20 )
01281                                            * sizeof(char) );
01282                   if (NULL == buffer)
01283                     {
01284                       exit(EXIT_FAILURE);
01285                     }
01286                   sprintf(buffer, ok_message[MN_START_TEST_SAMPLES],status.no_of_samples);
01287                   if (-1 == send(fd, buffer, strlen(buffer), 0))
01288                     {
01289                       perror("ADC-ZESOI: Send samples");
01290                     }
01291                 }
01292               /* samples resolution */
01293               buffer = (void *)malloc( ( strlen(ok_message[MN_START_RESOLUTION])
01294                                          + 2 )
01295                                        * sizeof(char) );
01296               if (NULL == buffer)
01297                 {
01298                   exit(EXIT_FAILURE);
01299                 }
01300               sprintf(buffer, ok_message[MN_START_RESOLUTION], status.resolution);
01301               if (-1 == send(fd, buffer, strlen(buffer), 0))
01302                 {
01303                   perror("ADC-ZESOI: Send stream");
01304                 }
01305               free(buffer);
01306 
01307               /* send samples */
01308               if (TRUE == global_test_mode)
01309                 {
01310                   /* allocate buffer for sending */
01311                   buffer = (void *)malloc(80 * sizeof(char));
01312                   if (NULL == buffer)
01313                     {
01314                       exit(EXIT_FAILURE);
01315                     }
01316                   /* sending random data values for testing purposes */
01317                   for (i=0; i<status.no_of_samples; i++)
01318                     {
01319                       sprintf(buffer, "%f\n", (double)rand()/RAND_MAX);
01320                       if (-1 == send(fd, buffer, strlen(buffer), 0))
01321                         {
01322                           perror("ADC-ZESOI: Send samples");
01323                         }
01324 #ifdef SLEEP
01325                       sleep(1);
01326 #endif
01327                     }
01328                   free(buffer);
01329                 }
01330               else
01331                 {
01332                   /* sending samples */
01333                   acquire_status = acquireandsendsamples(fd, status.no_of_samples,
01334                                                           status.channel, status.resolution);
01335                   if (ACQUIRE_FAILURE == acquire_status)
01336                     {
01337                       fprintf(stderr, "ADC-ZESOI: Data acquisition error.\n");
01338                     }
01339                 }
01340 
01341               /* transfer completed */
01342               if (-1 == send(fd, ok_message[MN_TRANSFER_COMPLETED],
01343                              strlen(ok_message[MN_TRANSFER_COMPLETED]), 0))
01344                 {
01345                   perror("ADC-ZESOI: Start");
01346                 }
01347             }
01348           break;
01349 
01350         case CN_STOP:
01351           /**** command STOP *********************************************/
01352           status.stream = FALSE;
01353           if (0 < global_stream_pid)
01354             {
01355               if (-1 == kill(global_stream_pid, SIGTERM)) perror("ADC-ZESOI: Stop stream");
01356               global_stream_pid = -1;
01357             }
01358           if (-1 == send(fd, ok_message[MN_TRANSFER_COMPLETED],
01359                          strlen(ok_message[MN_TRANSFER_COMPLETED]), 0))
01360             {
01361               perror("ADC-ZESOI: Stop");
01362             }
01363           if (-1 == send(fd, ok_message[MN_STOP],
01364                          strlen(ok_message[MN_STOP]), 0))
01365             {
01366               perror("ADC-ZESOI: Stop");
01367             }
01368           break;
01369 
01370         case CN_HELP:
01371           /**** command HELP *********************************************/
01372           if (-1 == send(fd, help_message[c.help_code],
01373                          strlen(help_message[c.help_code]), 0))
01374             {
01375               perror("ADC-ZESOI: Send");
01376             }
01377           break;
01378 
01379         case CN_BYE:
01380         case CN_EXIT:
01381         case CN_QUIT:
01382           /**** commands BYE, EXIT, QUIT *********************************/
01383           status.exit = c.exit;
01384           break;
01385 
01386         case MAX_CN_NO:
01387         default:
01388           /**** unknown command ******************************************/
01389         }
01390     }
01391 
01392   return status;
01393 }
01394 /* executecommand */
01395 
01396 
01397 
01399 
01406 void lostconnection (int sig)
01407 {
01408   if (0 == global_pid)
01409     {
01410       /* this is a chils process */
01411       close(global_fd);
01412 #ifdef DEBUG
01413       fprintf(stderr, "ADC-ZESOI: WARNING: Client has terminated connection.\n");
01414 #endif
01415       exit(EXIT_SUCCESS);
01416     }
01417 }
01418 /* lostconnection */
01419 
01420 
01421 
01423 
01435 int
01436 acquireandsendsamples (int fd, int no_of_samples, int channel, char resolution)
01437 {
01438   FILE *input; /* input channel */
01439   float *data; /* temporary data storage */
01440   char buffer[80+1]; /* sending buffer */
01441   int step;
01442   int i;
01443 
01444   /* set skip and no_of_samples */
01445   if (0 >= no_of_samples)
01446     {
01447       return ACQUIRE_FAILURE;
01448     }
01449   switch (resolution)
01450     {
01451     case RESOLUTION_MC:
01452       step = MEDIUM_RESOLUTION_STEP;
01453       break;
01454     case RESOLUTION_LC:
01455       step = LOW_RESOLUTION_STEP;
01456       break;
01457     default:
01458       step = HIGH_RESOLUTION_STEP;
01459       break;
01460     }
01461   no_of_samples *= step;
01462 
01463   /* open requested channel */
01464   switch (channel)
01465     {
01466     case 2:
01467       input = fopen("/dev/AD_ulaz_2", "rb");
01468       break;
01469     case 3:
01470       input = fopen("/dev/AD_ulaz_3", "rb");
01471       break;
01472     case 4:
01473       input = fopen("/dev/AD_ulaz_4", "rb");
01474       break;
01475     case 5:
01476       input = fopen("/dev/AD_ulaz_5", "rb");
01477       break;
01478     case 6:
01479       input = fopen("/dev/AD_ulaz_6", "rb");
01480       break;
01481     case 7:
01482       input = fopen("/dev/AD_ulaz_7", "rb");
01483       break;
01484     case 8:
01485       input = fopen("/dev/AD_ulaz_8", "rb");
01486       break;
01487     default:
01488       input = fopen("/dev/AD_ulaz_1", "rb");
01489       break;
01490     }
01491   if (NULL == input)
01492     {
01493       return ACQUIRE_FAILURE;
01494     }
01495   data = (float *)malloc(no_of_samples*sizeof(float));
01496   if (NULL == data)
01497     {
01498       fclose(input);
01499       return ACQUIRE_FAILURE;
01500     }
01501   fread(data, no_of_samples, sizeof(float), input);
01502   fclose(input);
01503 
01504   /* send samples */
01505   for (i=0; i<no_of_samples; i+=step)
01506     {
01507       sprintf(buffer, "%f\n", (double)data[i]);
01508       if (-1 == send(fd, buffer, strlen(buffer), 0))
01509         {
01510           perror("ADC-ZESOI: Sending samples form acquire");
01511         }
01512     }
01513 
01514   /* clean up */
01515   free(data);
01516 
01517   return ACQUIRE_SUCCESS;
01518 }
01519 /* acquireandsendsamples */
01520 
01521 
01522 
01524 
01530 void
01531 stopstream (int sig)
01532 {
01533   if (0 == global_stream_pid)
01534     {
01535       /* this is a child process */
01536       close(global_fd);
01537 #ifdef DEBUG
01538       fprintf(stderr, "ADC-ZESOI: Stopping data stream.\n");
01539 #endif
01540       exit(EXIT_SUCCESS);
01541     }
01542   else
01543     {
01544       /* parent has received SIGTERM */
01545       if (0 < global_stream_pid)
01546         {
01547           /* child is still sending - kill it */
01548           if (-1 == kill(global_stream_pid, SIGTERM)) perror("ADC-ZESOI: Stop stream");
01549           global_stream_pid = -1;
01550         }
01551     }
01552 }
01553 /* stopstream */
01554 
01555 
01556 
01558 
01563 void
01564 cleanallchildren (int sig)
01565 {
01566   /* clean up all child processes */
01567   while(waitpid(-1, NULL, WNOHANG) > 0);
01568 }
01569 /* cleanallchildren */

Generated at Wed Feb 6 16:45:11 2002 for ADC-ZESOI Server by doxygen1.2.7 written by Dimitri van Heesch, © 1997-2001