00001
00002
00003
00004
00005
00006
00007
00008
00009
00017
00018
00019 #define TEST_MODE
00020
00021 #ifndef __SERVER
00022 #include <server.h>
00023 #endif
00024
00025
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;
00053 char *hostname;
00054 int sockfd;
00055 int new_fd;
00056 int argno;
00057 char *p1, *p2;
00058 unsigned long int port_param;
00059 unsigned long int retries_param;
00060 short authorisation;
00061 short test_mode;
00062 unsigned short int 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;
00069 command_t status;
00070 command_t command;
00071
00072
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
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
00091 signal(SIGCHLD, cleanallchildren);
00092
00093
00094 for(argno=1; argno<argc; argno++)
00095 {
00096 if ('-' == argv[argno][0])
00097 {
00098
00099 if ('-' == argv[argno][1])
00100 {
00101
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
00188 goto invalid_parameter;
00189 }
00190 }
00191 else if('\0' != argv[argno][1])
00192 {
00193
00194 if ('\0' != argv[argno][2])
00195 {
00196
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
00266 }
00267 else
00268 {
00269
00270 goto invalid_parameter;
00271 }
00272 }
00273 else
00274 {
00275
00276 goto invalid_parameter;
00277 }
00278 }
00279
00280
00281
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
00295 if (ROOT_UID != geteuid())
00296 {
00297
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
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
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
00332 while (TRUE)
00333 {
00334
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
00347 global_fd = new_fd;
00348 signal(SIGPIPE, lostconnection);
00349
00350
00351 pid = fork();
00352 global_pid = pid;
00353 if (0 == pid)
00354 {
00355
00356
00357
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
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
00384 while (FALSE == status.exit)
00385 {
00386
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
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
00401 status = executecommand(command, status, new_fd);
00402
00403
00404 free(buffer);
00405 }
00406
00407
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
00429 #ifdef DEBUG
00430 fprintf(stderr, "ADC-ZESOI: Started child process %d.\n", pid);
00431 #endif
00432 }
00433 close(new_fd);
00434 }
00435 }
00436
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
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
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
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
00532 i = strtok(temp, DELIMITERS);
00533 #ifdef DEBUG
00534 fprintf(stderr, "ADC-ZESOI: First token is: %s.\n", i);
00535 #endif
00536
00537
00538
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
00552 j = strtok(NULL, DELIMITERS);
00553 switch (command_no)
00554 {
00555
00556 case CN_USER:
00557
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
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
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
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
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
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
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
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
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
00819 c.command_no = CN_ERROR;
00820 c.error_code = EC_UNKNOWN_COMMAND;
00821 }
00822
00823
00824 free(temp);
00825
00826 return c;
00827 }
00828
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;
00846 char *hostname;
00847 struct hostent *hostdata;
00848 char *buffer, *p1, *p2, *p3;
00849 long size;
00850 FILE *passwd;
00851 size_t length;
00852 int acquire_status;
00853 int i;
00854 pid_t pid;
00855
00856 if ( (TRUE == status.stream) &&
00857 (CN_STOP != c.command_no) )
00858 {
00859
00860
00861
00862
00863
00864
00865
00866
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
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
00885 switch (c.command_no)
00886 {
00887
00888 case CN_USER:
00889
00890 strcpy(status.username, c.username);
00891
00892
00893 status.authorised = NOTAUTHORISED;
00894 login_counter = 0;
00895
00896
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
00911 strcpy(status.password, c.password);
00912
00913
00914 passwd = fopen("/etc/shadow","rt");
00915 if (NULL == passwd)
00916 {
00917 perror("ADC-ZESOI: /etc/shadow");
00918
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
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
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
00953
00954 p2 = strstr(p1, ":") + 1;
00955 p3 = strstr(p2, ":");
00956 p3[0] = '\0';
00957
00958
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
00968 memset(buffer, 0, size*sizeof(char));
00969 free(buffer);
00970 break;
00971 }
00972
00973
00974 if (0 == strncmp(p2, "!", 1))
00975 {
00976
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
00990 if (0 == strncmp(p2, "*", 1))
00991 {
00992
00993 memset(buffer, 0, size*sizeof(char));
00994 free(buffer);
00995
00996
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
01015 status.authorised = AUTHORISED;
01016
01017
01018 memset(status.password, 0, strlen(status.password));
01019 memset(buffer, 0, size*sizeof(char));
01020 free(buffer);
01021
01022
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
01040
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
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
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
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
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
01108 memset(buffer, 0, size*sizeof(char));
01109 free(buffer);
01110 }
01111 break;
01112
01113 case CN_SET:
01114
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
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
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
01172 if (DATA_STREAM == status.no_of_samples)
01173 {
01174
01175 status.stream = TRUE;
01176
01177
01178 signal(SIGTERM, stopstream);
01179
01180
01181 pid = fork();
01182 global_stream_pid = pid;
01183 if (0 == pid)
01184 {
01185
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
01193
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
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
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
01227 while (TRUE)
01228 {
01229 if (TRUE == global_test_mode)
01230 {
01231
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
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
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
01276
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
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
01308 if (TRUE == global_test_mode)
01309 {
01310
01311 buffer = (void *)malloc(80 * sizeof(char));
01312 if (NULL == buffer)
01313 {
01314 exit(EXIT_FAILURE);
01315 }
01316
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
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
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
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
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
01383 status.exit = c.exit;
01384 break;
01385
01386 case MAX_CN_NO:
01387 default:
01388
01389 }
01390 }
01391
01392 return status;
01393 }
01394
01395
01396
01397
01399
01406 void lostconnection (int sig)
01407 {
01408 if (0 == global_pid)
01409 {
01410
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
01419
01420
01421
01423
01435 int
01436 acquireandsendsamples (int fd, int no_of_samples, int channel, char resolution)
01437 {
01438 FILE *input;
01439 float *data;
01440 char buffer[80+1];
01441 int step;
01442 int i;
01443
01444
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
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
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
01515 free(data);
01516
01517 return ACQUIRE_SUCCESS;
01518 }
01519
01520
01521
01522
01524
01530 void
01531 stopstream (int sig)
01532 {
01533 if (0 == global_stream_pid)
01534 {
01535
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
01545 if (0 < global_stream_pid)
01546 {
01547
01548 if (-1 == kill(global_stream_pid, SIGTERM)) perror("ADC-ZESOI: Stop stream");
01549 global_stream_pid = -1;
01550 }
01551 }
01552 }
01553
01554
01555
01556
01558
01563 void
01564 cleanallchildren (int sig)
01565 {
01566
01567 while(waitpid(-1, NULL, WNOHANG) > 0);
01568 }
01569