From: hadaq Date: Mon, 5 Apr 2010 20:23:56 +0000 (+0000) Subject: update of tcp-mode X-Git-Tag: v6.0~284 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=e92dd7f9f2e69b8b90907a38739463b0f2a8fa2e;p=trbnettools.git update of tcp-mode --- diff --git a/libtrbnet/trbcmd.c b/libtrbnet/trbcmd.c index e480cdc..fd21391 100644 --- a/libtrbnet/trbcmd.c +++ b/libtrbnet/trbcmd.c @@ -1,18 +1,20 @@ /* -* Changes by Boris and Jan: -* -* 1. Original code is in a sub-routine called start() -* 2. main() can enter a tcp loop (if called with attribute \"tcp\") or just call start() (otherwise) -* -* -*/ - + * Changes by Boris and Jan: + * + * 1. Original code is in a sub-routine called start() + * 2. main() can enter a tcp loop (if called with attribute \"tcp\") or + * just call start() (otherwise) + * + * + */ #define _GNU_SOURCE #include #include #include #include +#include +#include #include #include @@ -20,36 +22,31 @@ #include #include -#ifndef HEXMODE -#define HEXMODE 0 -#endif - - -// Monitoring libraries -//********************* #include #include #include #include +#include #include -// Configuration -//************** -#define MYPORT 55555 -#define BACKLOG 10 -#define READ_MEM_SIZE 1048576 -#define tcp_debug 1 // turn to 0 to suppress TCP/IP output - -static FILE * STDOUT; -static FILE * STDERR; +#ifndef HEXMODE +#define HEXMODE 0 +#endif static int hexMode = HEXMODE; -static const char trbcmd_version[] = "$Revision: 2.43 $"; +static const char trbcmd_version[] = "$Revision: 2.44 $"; + +#define BACKLOG 10 +static uint16_t tcp_port = 55555; +static int tcp_debug = 0; /* turn to 0 to suppress TCP/IP output */ + +static FILE* STDOUT = NULL; +static FILE* STDERR = NULL; /* ---- User Buffer Size ----------------------------------------------- */ -static size_t NUM_ENDPOINTS = 1024; /* Maximum of 16KByte */ +static size_t NUM_ENDPOINTS = 1024; /* Maximum of 16KByte */ static size_t USER_BUFFER_SIZE = 0; /* ------ MAIN ---------------------------------------------------------- */ @@ -57,62 +54,82 @@ static size_t USER_BUFFER_SIZE = 0; void usage(const char *progName) { fprintf(STDOUT, "Usage: %s [-h] [-f script-file] [-n number] [-d level] " - "[-H] [-V] \n", progName); - fprintf(STDOUT, " tcp start in TCP/IP-server mode (!)\n"); + "[-H] [-V] \n", progName); fprintf(STDOUT, "Options:\n"); fprintf(STDOUT, " -h give this help\n"); fprintf(STDOUT, " -f execute commands given in script-file\n"); fprintf(STDOUT, " -n repeat COMMAND number times, -1 = endless loop\n"); - fprintf(STDOUT, " -M turn on HighMemoryMode (maximum usage is 20MByte, default: " - "3MByte)\n"); + fprintf(STDOUT, + " -M turn on HighMemoryMode (maximum usage is 20MByte, default: " + "3MByte)\n"); fprintf(STDOUT, " -d turn on Debugging Information\n"); - fprintf(STDOUT, " level 1: TRB_Package debugging\n"); - fprintf(STDOUT, " level 2: +FIFO debugging\n"); + fprintf(STDOUT, " level 1: TRB_Package debugging\n"); + fprintf(STDOUT, " level 2: +FIFO debugging\n"); fprintf(STDOUT, " -D FIFO DMA-Mode\n"); - fprintf(STDOUT, " -l lazy-mode: skip most consistency-checks of packages\n"); - fprintf(STDOUT, " -H hex-mode: all arguments will be interpreted " - "as hexadecimal-numbers\n"); - fprintf(STDOUT, " -V Version number\n"); + fprintf(STDOUT, + " -l lazy-mode: skip most consistency-checks of packages\n"); + fprintf(STDOUT, + " -H hex-mode: all arguments will be interpreted " + "as hexadecimal-numbers\n"); + fprintf(STDOUT, " -V version number\n"); fprintf(STDOUT, "\nCommands:\n"); fprintf(STDOUT, " r -> " - "read register\n"); + "read register\n"); fprintf(STDOUT, " w -> " - "write register\n"); + "write register\n"); fprintf(STDOUT, " rm -> " - "read register-memory\n"); + "read register-memory\n"); fprintf(STDOUT, " wm -> " - "write to register-memory from ASCII-file ('-' = stdin)\n"); + "write to register-memory\n" + " " + "from ASCII-file\n" + " " + "('-' = stdin)\n"); fprintf(STDOUT, " i -> " - "read unique ID\n"); + "read unique ID\n"); fprintf(STDOUT, " s -> " - "set trb-address\n"); + "set trb-address\n"); fprintf(STDOUT, " T -> " - "send trigger\n", '%'); + "send trigger\n", '%'); fprintf(STDOUT, " TR -> " - "send trigger to RICH only\n", '%'); + "send trigger to RICH only\n", '%'); fprintf(STDOUT, " I -> " - "read IPU data\n", '%'); + "read IPU data\n", '%'); fprintf(STDOUT, " reload -> " - "reload FPGA\n"); + "reload FPGA\n"); fprintf(STDOUT, " reset -> " - "reset TRBNetwork\n"); + "reset TRBNetwork\n"); fprintf(STDOUT, " comreset -> " - "reset Etrax-FIFO Logic\n"); + "reset Etrax-FIFO Logic\n"); fprintf(STDOUT, " f -> " - "flush FIFO of channel\n"); + "flush FIFO of channel\n"); fprintf(STDOUT, " R -> " - "read register of the FPGA\n"); - + "read register of the FPGA\n"); fprintf(STDOUT, " W -> " - "write to register of the FPGA\n"); - + "write to register of the\n" + " " + "FPGA\n"); + fprintf(STDOUT, " exit/quit -> " + "disconnect from server\n" + " " + "(tcp-server mode only)\n\n"); + + fprintf(STDOUT, "Start as TCP/IP-Server:\n"); + fprintf(STDOUT, "Usage: %s [-h] [-d] [-p portnumber] [-b] [-V] tcp\n", + progName); + fprintf(STDOUT, "Options:\n"); + fprintf(STDOUT, " -h give this help\n"); + fprintf(STDOUT, " -p tcp port number (default: 55555)\n"); + fprintf(STDOUT, " -b run in background as daemon\n"); + fprintf(STDOUT, " -d turn on debugging informations (default: off)\n"); + fprintf(STDOUT, " -V version number\n"); } #define CMD_SIZE 256 #define CMD_MAX_NUM 10 - -int start(int argc, char ** argv, char* command){ +int start(int argc, char **argv) +{ FILE *scriptFile = NULL; char scriptFileName[256] = ""; char cmd[CMD_MAX_NUM][CMD_SIZE]; @@ -120,31 +137,33 @@ int start(int argc, char ** argv, char* command){ size_t cmdLineLen = 0; unsigned int cmdLen = 0; uint16_t trb_address = 0; - uint16_t reg_address = 0; + uint16_t reg_address = 0; int loop = 1; int loopCtr = 0; - uint16_t trgCtr = 0; /* counter for the %ctr option */ + uint16_t trgCtr = 0; /* counter for the %ctr option */ int opt; int i; - for(i = 0; i < CMD_MAX_NUM; i++) { + for (i = 0; i < CMD_MAX_NUM; i++) { cmd[i][0] = 0; } + /* LowMem Settings, i.e. 3 MBye maximum */ - USER_BUFFER_SIZE = 786432; /* 0xc000 * 4 Byte*/ - + USER_BUFFER_SIZE = 786432; /* 0xc000 * 4 Byte */ + trb_debug = 0; trb_lazy = 0; - + /* Parse Arguments */ + optind = 1; while ((opt = getopt(argc, argv, "+hf:n:d:DlHMV")) != -1) { switch (opt) { case '?': usage(basename(argv[0])); - return (EXIT_FAILURE); + return -1; case 'h': usage(basename(argv[0])); - return (EXIT_SUCCESS); + return 0; case 'f': strncpy(scriptFileName, optarg, 256); break; @@ -166,17 +185,17 @@ int start(int argc, char ** argv, char* command){ case 'V': printf("%s %s, using libtrbnet %s\n", basename(argv[0]), trbcmd_version, trbnet_version); - return (EXIT_SUCCESS); + return 0; break; case 'M': - /* HighMem Setting, i.e. 20 MByte maximum 0x500000 * 4*/ + /* HighMem Setting, i.e. 20 MByte maximum 0x500000 * 4 */ USER_BUFFER_SIZE = 5242880; break; default: break; } } - + /* Open scriptFile if requested */ if (strlen(scriptFileName) > 0) { if (strncmp(scriptFileName, "-", 256) == 0) { @@ -187,59 +206,50 @@ int start(int argc, char ** argv, char* command){ if (scriptFile == NULL) { fprintf(STDERR, "Error opening ScriptFile '%s': %s\n", scriptFileName, strerror(errno)); - return (EXIT_FAILURE); + return -1; } } } - - /* Open ports */ - init_ports(); /* Start repeat-loop */ while ((loop == -1) || (loopCtr++ < loop)) { unsigned int lineCtr = 0; ssize_t scriptStatus = 0; - + /* Start script-file-loop */ - while (scriptStatus != -1) { - if (scriptFile == NULL && command == NULL) { + while (scriptStatus != -1) { + if (scriptFile == NULL) { /* Get command from function-call */ unsigned int i; cmdLen = argc - optind; for (i = 0; (i < cmdLen) && (i < CMD_MAX_NUM); i++) { - strncpy(cmd[i], argv[optind + i], CMD_SIZE); + strncpy(cmd[i], argv[optind + i], CMD_SIZE); } scriptStatus = -1; } else { char *c = NULL; unsigned int i; + + /* Get next command from file */ + lineCtr++; + /* Initialize */ + for (i = 0; i < CMD_MAX_NUM; i++) { + cmd[i][0] = '\0'; + } - if (scriptFile != NULL) { - /* Get next command from file */ - - lineCtr++; - /* Initialize */ - for (i = 0; i < CMD_MAX_NUM; i++) { - cmd[i][0] = '\0'; - } - - if ((scriptStatus = - getline(&cmdLine, &cmdLineLen, scriptFile)) == -1) { - if (feof(scriptFile) != 0) { - /* EOF reached */ - rewind(scriptFile); - continue; - } else { - /* Error reading line */ - fprintf(STDERR, "Error reading script-file\n"); - return (EXIT_FAILURE); - } + if ((scriptStatus = + getline(&cmdLine, &cmdLineLen, scriptFile)) == -1) { + if (feof(scriptFile) != 0) { + /* EOF reached */ + rewind(scriptFile); + continue; + } else { + /* Error reading line */ + fprintf(STDERR, "Error reading script-file\n"); + return -1; } - } - else { - cmdLine = command; - scriptStatus = -1; } + /* Remove newline and comments */ if ((c = strchr(cmdLine, '\n')) != NULL) { *c = '\0'; @@ -247,66 +257,66 @@ int start(int argc, char ** argv, char* command){ if ((c = strchr(cmdLine, '#')) != NULL) { *c = '\0'; } - + /* Split up cmdLine */ - sscanf(cmdLine, "%s %s %s %s %s %s %s %s %s %s", + sscanf(cmdLine, "%s %s %s %s %s %s %s %s %s %s", cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]); - + for (i = 0, cmdLen = 0; i < CMD_MAX_NUM; i++, cmdLen++) { - if (cmd[i][0] == '\0') break; + if (cmd[i][0] == '\0') + break; } if (cmdLen == 0) { - /* Empty Line */ + /* Empty Line */ continue; } - if(scriptFile != NULL) { + if (scriptFile != NULL) { fprintf(STDOUT, "#Line %d: %s\n", lineCtr, cmdLine); } } - + if (strncmp(cmd[0], "w", CMD_SIZE) == 0) { - + /*******************************************/ /* Register Write */ /*******************************************/ - + uint32_t value = 0; - - if (cmdLen != 4) { + + if (cmdLen != 4) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); reg_address = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); value = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: WRITE: trb_address: 0x%04x, reg_address: 0x%04x, " - "value: 0x%08x\n", - trb_address, reg_address, value); + "value: 0x%08x\n", trb_address, reg_address, value); } - + if (trb_register_write(trb_address, reg_address, value) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("write_register failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -315,7 +325,7 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + } else if (strncmp(cmd[0], "r", CMD_SIZE) == 0) { /*******************************************/ @@ -325,31 +335,31 @@ int start(int argc, char ** argv, char* command){ int status = 0; uint32_t *data = NULL; int i; - + if (cmdLen != 3) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); reg_address = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: READ: trb_address: 0x%04x, " - "reg_address: 0x%04x\n", - trb_address, reg_address); + "reg_address: 0x%04x\n", trb_address, reg_address); } - - data = (uint32_t*) malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 2); - if (data == NULL) abort(); - - status = trb_register_read(trb_address, reg_address, + + data = (uint32_t *) malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 2); + if (data == NULL) + abort(); + + status = trb_register_read(trb_address, reg_address, data, NUM_ENDPOINTS * 2); if (status == -1) { if (scriptFile != NULL) { @@ -357,16 +367,15 @@ int start(int argc, char ** argv, char* command){ } trb_error("read_register failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { for (i = 0; i < status; i += 2) { - fprintf(STDOUT, "0x%04x 0x%08x\n", - data[i], data[i + 1]); + fprintf(STDOUT, "0x%04x 0x%08x\n", data[i], data[i + 1]); } - + /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -378,49 +387,49 @@ int start(int argc, char ** argv, char* command){ free(data); } else if (strncmp(cmd[0], "rm", CMD_SIZE) == 0) { - + /*******************************************/ /* Register Read Memory */ /*******************************************/ - + uint32_t *data = NULL; uint16_t size = 0; uint8_t option = 0; int status; - const uint32_t* p; - const uint32_t* end = NULL; + const uint32_t *p; + const uint32_t *end = NULL; unsigned int len; unsigned int i; - + if (cmdLen != 5) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); reg_address = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); size = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); option = strtoul(cmd[4], NULL, hexMode == 1 ? 16 : 0); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: READ_MEM: " "trb_address: 0x%04x, " "reg_address: 0x%04x, " "size: 0x%04x, " - "option: %d\n", - trb_address, reg_address, size, option); + "option: %d\n", trb_address, reg_address, size, option); } - - data = (uint32_t*)malloc(sizeof(uint32_t) * USER_BUFFER_SIZE); - if (data == NULL) abort(); - - status = trb_register_read_mem(trb_address, reg_address, option, + + data = (uint32_t *) malloc(sizeof(uint32_t) * USER_BUFFER_SIZE); + if (data == NULL) + abort(); + + status = trb_register_read_mem(trb_address, reg_address, option, size, data, USER_BUFFER_SIZE); if (status == -1) { if (scriptFile != NULL) { @@ -428,7 +437,7 @@ int start(int argc, char ** argv, char* command){ } trb_error("read_register_mem failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Print data-buffer */ @@ -436,14 +445,13 @@ int start(int argc, char ** argv, char* command){ end = p + status; while (p < end) { len = (*p >> 16) & 0xffff; - fprintf(STDOUT, "0x%04x 0x%04x\n", (*p++) & 0xffff, len); - for (i = 0; (i < len) && (p < end); i++) { - fprintf(STDOUT, "0x%04x 0x%08x\n", - reg_address + i, *p++); + fprintf(STDOUT, "H: 0x%04x 0x%04x\n", (*p++) & 0xffff, len); + for (i = 0; (i < len) && (p < end); i++) { + fprintf(STDOUT, "0x%04x 0x%08x\n", reg_address + i, *p++); } } /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -455,14 +463,14 @@ int start(int argc, char ** argv, char* command){ free(data); } else if (strncmp(cmd[0], "wm", CMD_SIZE) == 0) { - + /*******************************************/ /* Register Write Memory */ /*******************************************/ - + FILE *file = NULL; uint32_t *data = NULL; - unsigned int dataSize = 64; + unsigned int dataSize = 64; char *line = NULL; size_t len = 0; char *fileName = NULL; @@ -476,14 +484,14 @@ int start(int argc, char ** argv, char* command){ } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); reg_address = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); option = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); fileName = cmd[4]; - + /* Open inputFile and read Data into buffer */ if (strncmp(fileName, "-", CMD_SIZE) == 0) { file = stdin; @@ -492,26 +500,28 @@ int start(int argc, char ** argv, char* command){ if (file == NULL) { fprintf(STDERR, "Error opening file '%s': %s\n", fileName, strerror(errno)); - return (EXIT_FAILURE); + return -1; } } - - data = (uint32_t*)malloc(sizeof(uint32_t) * dataSize); - if (data == NULL) abort(); - + + data = (uint32_t *) malloc(sizeof(uint32_t) * dataSize); + if (data == NULL) + abort(); + while (getline(&line, &len, file) != -1) { if (size >= dataSize) { dataSize += 64; - data = (uint32_t*)realloc(data, sizeof(uint32_t) * dataSize); - if (data == NULL) abort(); + data = (uint32_t *) realloc(data, sizeof(uint32_t) * dataSize); + if (data == NULL) + abort(); } data[size++] = strtoul(line, NULL, hexMode == 1 ? 16 : 0); } free(line); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: WRITE_MEM: trb_address: 0x%04x, " "reg_address: 0x%04x, " "option: %d, " @@ -519,8 +529,8 @@ int start(int argc, char ** argv, char* command){ "size: 0x%04x\n", trb_address, reg_address, option, fileName, size); } - - status = trb_register_write_mem(trb_address, reg_address, option, + + status = trb_register_write_mem(trb_address, reg_address, option, data, size); if (status == -1) { if (scriptFile != NULL) { @@ -528,11 +538,11 @@ int start(int argc, char ** argv, char* command){ } trb_error("write_register_memory failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -541,40 +551,40 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + free(data); - + } else if (strncmp(cmd[0], "i", CMD_SIZE) == 0) { /*******************************************/ /* ReadUId */ /*******************************************/ - + uint32_t *uidBuffer = NULL; int status; int i; - + if (cmdLen != 2) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, - "Command: READ_UID: trb_address: 0x%04x\n", - trb_address); + fprintf(STDERR, + "Command: READ_UID: trb_address: 0x%04x\n", trb_address); } - - uidBuffer = (uint32_t*)malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 4); - if (uidBuffer == NULL) abort(); - + + uidBuffer = (uint32_t *) malloc(sizeof(uint32_t) * NUM_ENDPOINTS * 4); + if (uidBuffer == NULL) + abort(); + status = trb_read_uid(trb_address, uidBuffer, NUM_ENDPOINTS * 4); if (status == -1) { if (scriptFile != NULL) { @@ -582,18 +592,16 @@ int start(int argc, char ** argv, char* command){ } trb_error("read_uid failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { - for (i = 0; (i < status) && (i < NUM_ENDPOINTS * 4); i += 4) { + for (i = 0; (i < status) && (i < 128); i += 4) { fprintf(STDOUT, "0x%04x 0x%08x%08x 0x%02x\n", uidBuffer[i + 3], - uidBuffer[i], - uidBuffer[i + 1], - uidBuffer[i + 2]); + uidBuffer[i], uidBuffer[i + 1], uidBuffer[i + 2]); } /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -604,51 +612,50 @@ int start(int argc, char ** argv, char* command){ } free(uidBuffer); - + } else if (strncmp(cmd[0], "s", CMD_SIZE) == 0) { - + /*******************************************/ /* SetAddress */ /*******************************************/ - + uint64_t uid = 0; uint8_t endpoint = 0; uint16_t trb_address = 0; - + if (cmdLen != 4) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + uid = strtoull(cmd[1], NULL, hexMode == 1 ? 16 : 0); endpoint = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); trb_address = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: SET_ADDRESS: " "uid: 0x%016llx, " "endpoint: 0x%02x, " - "trb_address: 0x%04x\n", - uid, endpoint, trb_address); + "trb_address: 0x%04x\n", uid, endpoint, trb_address); } - + if (trb_set_address(uid, endpoint, trb_address) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("set_address failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -657,62 +664,61 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + } else if (strncmp(cmd[0], "T", CMD_SIZE) == 0) { - + /*******************************************/ /* Send Trigger */ /*******************************************/ - + uint8_t type; uint8_t random = 0; uint32_t info = 0; uint16_t number = 0; - + if (cmdLen != 5) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + type = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0) & 0x0f; random = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); info = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); if (strncmp(cmd[4], "%ctr", CMD_SIZE) == 0) { if (scriptFile == NULL) { usage(basename(argv[0])); - return (EXIT_FAILURE); + return -1; } number = trgCtr; } else { number = strtoul(cmd[4], NULL, hexMode == 1 ? 16 : 0); } - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: SEND_TRIGGER: " "type: 0x%01x, " "random: 0x%02x, " "info: 0x%06x, " - "number: 0x%04x\n", - type, random, info, number); + "number: 0x%04x\n", type, random, info, number); } - + if (trb_send_trigger(type, info, random, number) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("send_trigger failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -721,98 +727,98 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + } else if (strncmp(cmd[0], "reset", CMD_SIZE) == 0) { - + /*******************************************/ /* TRBNet Reset */ /*******************************************/ - - if (cmdLen != 1) { + + if (cmdLen != 1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + /* DEBUG Info */ if (trb_debug > 0) { fprintf(STDERR, "Command: RESET:\n"); } - + if (network_reset() == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("TRBNet RESET failed"); - return (EXIT_FAILURE); + return -1; } - + } else if (strncmp(cmd[0], "comreset", CMD_SIZE) == 0) { - + /*******************************************/ /* Etrax-FIFO Reset */ /*******************************************/ - - if (cmdLen != 1) { + + if (cmdLen != 1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + /* DEBUG Info */ if (trb_debug > 0) { fprintf(STDERR, "Command: COMRESET:\n"); } - + if (com_reset() == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("Etrax RESET failed"); - return (EXIT_FAILURE); + return -1; } - + } else if (strncmp(cmd[0], "reload", CMD_SIZE) == 0) { - + /*********************************************/ /* FPGA Reload */ - /*********************************************/ - - if (cmdLen != 2) { + /*********************************************/ + + if (cmdLen != 2) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + trb_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: RELOAD: trb_address: 0x%04x\n", trb_address); } - + if (trb_register_write(trb_address, 0x0020, 0x8000) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("FPGA reload failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || - (trb_term.status_channel != 0)) { + if ((trb_term.status_common != 0x01) || + (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } @@ -820,66 +826,65 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + } else if (strncmp(cmd[0], "TR", CMD_SIZE) == 0) { - + /*********************************************/ /* Send Fake trigger function to RICH Subnet */ /*********************************************/ - + uint8_t input = 0; uint8_t type = 0; uint8_t random = 0; uint32_t info = 0; uint16_t number = 0; - + if (cmdLen != 6) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + input = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0) & 0x03; type = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0) & 0x0f; random = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); info = strtoul(cmd[4], NULL, hexMode == 1 ? 16 : 0); - + if (strncmp(cmd[5], "%ctr", CMD_SIZE) == 0) { if (scriptFile == NULL) { usage(basename(argv[0])); - return (EXIT_FAILURE); + return -1; } number = trgCtr; } else { number = strtoul(cmd[5], NULL, hexMode == 1 ? 16 : 0); } - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: SEND_TRIGGER: " "input: 0x%01x, " "type: 0x%01x, " "random: 0x%02x, " "info: 0x%06x, " - "number: 0x%04x\n", - input, type, random, info, number); + "number: 0x%04x\n", input, type, random, info, number); } - + if (trb_send_trigger_rich(input, type, info, random, number) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("send_trigger failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -888,13 +893,13 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + } else if (strncmp(cmd[0], "I", CMD_SIZE) == 0) { - + /*******************************************/ /* IPU channel readout */ /*******************************************/ - + uint32_t *buffer = NULL; uint8_t type = 0; uint8_t random = 0; @@ -902,42 +907,42 @@ int start(int argc, char ** argv, char* command){ uint16_t number = 0; int status = 0; int i; - + if (cmdLen != 5) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + type = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0) & 0x0f; random = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); info = strtoul(cmd[3], NULL, hexMode == 1 ? 16 : 0); if (strncmp(cmd[4], "%ctr", CMD_SIZE) == 0) { if (scriptFile == NULL) { usage(basename(argv[0])); - return (EXIT_FAILURE); + return -1; } number = trgCtr; } else { number = strtoul(cmd[4], NULL, hexMode == 1 ? 16 : 0); } - + /* DEBUG Info */ if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: READ_IPU_DATA: " "type: 0x%01x, " "random: 0x%02x, " "info: 0x%02x, " - "number: 0x%04x\n", - type, random, info, number); + "number: 0x%04x\n", type, random, info, number); } - - buffer = (uint32_t*)malloc(sizeof(uint32_t) * USER_BUFFER_SIZE); - if (buffer == NULL) abort(); + + buffer = (uint32_t *) malloc(sizeof(uint32_t) * USER_BUFFER_SIZE); + if (buffer == NULL) + abort(); status = trb_ipu_data_read(type, info, random, number, buffer, USER_BUFFER_SIZE); @@ -947,15 +952,15 @@ int start(int argc, char ** argv, char* command){ } trb_error("read_ipu_data failed"); if (trb_errno != TRB_ENDPOINT_NOT_REACHED) { - return (EXIT_FAILURE); + return -1; } } else { for (i = 0; i < status; i++) { fprintf(STDOUT, "0x%08x\n", buffer[i]); } - + /* Check Status-Bits */ - if ((trb_term.status_common != 0x01) || + if ((trb_term.status_common != 0x01) || (trb_term.status_channel != 0)) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); @@ -964,259 +969,381 @@ int start(int argc, char ** argv, char* command){ trb_strterm(trb_term)); } } - + free(buffer); - + } else if (strncmp(cmd[0], "f", CMD_SIZE) == 0) { - + /*******************************************/ /* Flush FIFO Channel */ /*******************************************/ - + uint8_t channel = 0; - + if (cmdLen != 2) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + channel = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); if (trb_debug > 0) { fprintf(STDERR, "Command: FIFO_FLUSH_CHANNEL #%d\n", channel); } - + if (trb_fifo_flush(channel) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("trb_fifo_flush failed"); - return (EXIT_FAILURE); + return -1; } - + } else if (strncmp(cmd[0], "R", CMD_SIZE) == 0) { - + /*******************************************/ /* Read FIFO Register */ /*******************************************/ - + uint32_t value = 0; uint16_t reg_address = 0; - + if (cmdLen != 2) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } reg_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: READ_FIFO_REGISTER:" - "reg_address: 0x%04x\n", - reg_address); + "reg_address: 0x%04x\n", reg_address); } - + if (fpga_register_read(reg_address, &value) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("fpga_register_read failed"); - return (EXIT_FAILURE); + return -1; } else { fprintf(STDOUT, "0x%04x 0x%08x\n", reg_address, value); } - + } else if (strncmp(cmd[0], "W", CMD_SIZE) == 0) { - + /*******************************************/ /* Write FIFO Register */ /*******************************************/ - + uint32_t value = 0; uint16_t reg_address = 0; - + if (cmdLen != 3) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - + reg_address = strtoul(cmd[1], NULL, hexMode == 1 ? 16 : 0); value = strtoul(cmd[2], NULL, hexMode == 1 ? 16 : 0); if (trb_debug > 0) { - fprintf(STDERR, + fprintf(STDERR, "Command: WRITE_FIFO_REGISTER:" "reg_address: 0x%04x, " - "value: 0x%08x\n", - reg_address, value); + "value: 0x%08x\n", reg_address, value); } - + if (fpga_register_write(reg_address, value) == -1) { if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: ", lineCtr); } trb_error("fpga_register_write failed"); - return (EXIT_FAILURE); + return -1; } - + } else { - + /*******************************************/ - /* Not a valid command */ + /* Not a valid command */ /*******************************************/ - + if (scriptFile != NULL) { fprintf(STDERR, "Line #%d: Invalid command\n", lineCtr); } else { usage(basename(argv[0])); } - return (EXIT_FAILURE); + return -1; } - } /* End script-file-loop */ + } /* End script-file-loop */ - trgCtr++; - } /* End repeat-loop */ + trgCtr++; + } /* End repeat-loop */ /* Cleanup */ - - if (scriptFile != NULL) { fclose(scriptFile); free(cmdLine); } - return (EXIT_SUCCESS); - -} - + return 0; +} + +static int sockfd = -1; +static pid_t myPid = -1; +static int myFd = -1; + +static void atexit0(void) +{ + if (tcp_debug == 1) { + fprintf(stderr, "%d: exit called\n", myPid); + } + shutdown(myFd, SHUT_RDWR); + if (close(myFd) == -1) perror("close"); +} +static void sigHandler(int sig) +{ + if (sig == SIGCHLD) { + pid_t pid = -1; + while ((pid = waitpid(WAIT_ANY, NULL, WNOHANG)) > 0) { + if (tcp_debug == 1) { + fprintf(stderr, "caught SIGCHLD, pid: %d has terminated\n", pid); + } + } + } +} -int main(int argc, char ** argv) +int main(int argc, char **argv) { + unsigned int i; + STDOUT = stdout; STDERR = stderr; - - // MONITORING - s t a r t - - //************************* - - - - if (argc == 2 && strcmp(argv[1], "tcp") == 0){ - - - // TCP/IP SERVER INIT - //******************* - - int sockfd, new_fd; - struct sockaddr_in my_addr; - struct sockaddr_in their_addr; - int sin_size; - int yes = 1; - - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if(sockfd == -1){ - perror("socket() error!"); - return (1); - } - else - printf("\nsocket() OK...\n"); - - my_addr.sin_family = AF_INET; - my_addr.sin_port = htons(MYPORT); - my_addr.sin_addr.s_addr = INADDR_ANY; - memset(&(my_addr.sin_zero), 0, 8); - - if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 ) { - perror("setsockopt() error!"); - return (1); - } - else printf("setsockopt() OK...\n"); - - if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1){ - perror("bind() error!"); - return (1); - } - else printf("bind() OK...\n"); - - if(listen(sockfd, BACKLOG) == -1){ - perror("listen() error!"); - return (1); - } - else printf("listen() OK...\n\n* server initialized [OK]\n\n"); - - sin_size = sizeof(struct sockaddr_in); - - - // Init values and memory - //*********************** - int mainStatus = 1; - char command[256]; - int bytes_got; - int status = 1; - - // Enter an infinite loop - // to acquire instructions - //************************ - while (mainStatus != 0){ // main loop, mainstatus can break the loop to close the server - - printf("\n\nlisten...\n\n"); - new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); - if(new_fd == -1) perror("accept() error!"); - else if (tcp_debug>0) printf("accept() OK...\n"); - write(new_fd,"\n",1); - FILE *clientout = fdopen(new_fd, "a"); - - STDOUT = clientout; - STDERR = clientout; - while (status!= 0){ // the status can break the loop... - do { - bytes_got = recv(new_fd, (void *)command, 256, 0); - } while(bytes_got == -1); // receive the instruction - command[bytes_got-2] = 0; - if (tcp_debug > 0) { - printf("received: %i\n",bytes_got); - if (bytes_got>0) fprintf(stdout,"command: %s\n",command); - else { - fprintf(stdout,"\nclient terminated\n"); - break; - } - } - - if (command[0] == '#'){ // aendern - // Monitoring commands - } else { - //trbcmd - start(argc, argv, command); - fprintf(clientout,"\n----------------------------\n\n"); - fflush(clientout); - } - - - - } - fclose(clientout); - } - - - - //********************* - // MONITORING - e n d - - } -//Run normal TRBCMD - else - start(argc, argv, NULL); - return 0; -} // end main + if (strcmp(argv[argc - 1], "tcp") != 0) { + /* Run normal TRBCMD */ + init_ports(); + if (start(argc, argv) == 0) { + exit(EXIT_SUCCESS); + } + exit(EXIT_FAILURE); + } else { + /* Run TCP/IP server */ + struct sockaddr_in my_addr; + struct sockaddr_in their_addr; + int yes = 1; + int daemonMode = 0; + int opt; + + /* Parse Arguments */ + optind = 1; + while ((opt = getopt(argc, argv, "+hdVbp:")) != -1) { + switch (opt) { + case '?': + usage(basename(argv[0])); + exit(EXIT_FAILURE); + case 'h': + usage(basename(argv[0])); + exit(EXIT_SUCCESS); + case 'V': + printf("%s %s, using libtrbnet %s\n", + basename(argv[0]), trbcmd_version, trbnet_version); + exit(EXIT_SUCCESS); + break; + case 'p': + tcp_port = strtol(optarg, NULL, 0); + break; + case 'd': + tcp_debug = 1; + break; + case 'b': + daemonMode = 1; + break; + default: + break; + } + } + + if (daemonMode == 1) { + /* fork the first time */ + if ((myPid = fork()) == -1) { /* Error fork, Mother exit, no child */ + perror(argv[0]); + exit(EXIT_FAILURE); + } + if (myPid > 0) { + exit(EXIT_SUCCESS); /* Mother exit */ + } + /* fork the second time */ + setsid(); + if ((myPid = fork()) == -1) { /* Error fork, Mother exit, no child */ + perror(argv[0]); + exit(EXIT_FAILURE); + } + if (myPid > 0) { + exit(EXIT_SUCCESS); /* Mother exit */ + } + /* close stdin, stdout, stderr, change dir */ + chdir("/"); + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "a", stdout); + freopen("/dev/console", "a", stderr); + tcp_debug = 0; + } + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + perror("socket() error!"); + exit(EXIT_FAILURE); + } else if (tcp_debug > 0) { + fprintf(stderr, "\nsocket() OK...\n"); + } + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(tcp_port); + my_addr.sin_addr.s_addr = INADDR_ANY; + memset(&(my_addr.sin_zero), 0, 8); + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) + == -1) { + perror("setsockopt() error!"); + exit(EXIT_FAILURE); + } else if (tcp_debug > 0) { + fprintf(stderr, "setsockopt() OK...\n"); + } + + if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == + -1) { + perror("bind() error!"); + exit(EXIT_FAILURE); + } else if (tcp_debug > 0) { + fprintf(stderr, "bind() OK...\n"); + } + + signal(SIGCHLD, sigHandler); + + if (listen(sockfd, BACKLOG) == -1) { + perror("listen() error!"); + exit(EXIT_FAILURE); + } else if (tcp_debug > 0) { + fprintf(stderr, + "listen() OK...\n\n* server initialized" + " to port %d [OK]\n\n", + tcp_port); + } + + /* Enter an infinite loop to accept clients */ + while (1) { + socklen_t sin_size = sizeof(struct sockaddr_in); + ssize_t msgLen = 0; + char command[256]; + + if (tcp_debug > 0) { + fprintf(stderr, "\n\nlisten...\n\n"); + } + myFd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); + if (myFd == -1) { + perror("accept() error!"); + } else if (tcp_debug > 0) { + fprintf(stderr, "accept() OK...\n"); + } + if ((myPid = fork()) == -1) { /* Error fork, Mother exit, no child */ + perror(argv[0]); + exit(EXIT_FAILURE); + } + if (myPid > 0) { + /* Mother process: continue accepting connections */ + continue; + } else { + /* Child process */ + FILE* clientout = NULL; + myPid = getpid(); + write(myFd, "\n", 1); + atexit(atexit0); + init_ports(); + clientout = fdopen(myFd, "a"); + STDOUT = clientout; + STDERR = clientout; + trb_stderr = clientout; + + while (1) { + msgLen = recv(myFd, (void *)command, 256, 0); + if (msgLen == -1) { + perror("Error recv"); + exit(EXIT_FAILURE); + } + if (msgLen == 0) { + if (tcp_debug > 0) { + fprintf(stderr, "Client disconnected\n"); + } + exit(EXIT_SUCCESS); + } + if ((tcp_debug > 0) && (msgLen <= 2)) { + fprintf(stderr, "%d: empty package\n", myPid); + continue; + } + msgLen -= 2; + command[msgLen] = '\0'; + + int start_argc = 0; + char *start_argv[256]; + int start_arg = 0; + start_argv[start_argc++] = argv[0]; + for (i = 0; i < msgLen; i++) { + if (isspace((int)command[i]) != 0) { + command[i] = '\0'; + } + if (command[i] != '\0') { + if (start_arg == 0) { + start_argv[start_argc++] = &command[i]; + start_arg = 1; + } else { + continue; + } + } else { + command[i] = '\0'; + start_arg = 0; + } + } + + if (tcp_debug > 0) { + fprintf(stderr, "%d: received: %i\n", myPid, msgLen); + if (msgLen > 0) { + fprintf(stderr, "%d: command: ", myPid); + for (i = 1; i < start_argc; i++) { + fprintf(stderr, "%s ", start_argv[i]); + } + fprintf(stderr, "\n"); + } + } + + /* Execute command */ + if (start_argc == 1) continue; + if ((strcmp(start_argv[1], "exit") == 0) || + (strcmp(start_argv[1], "quit") == 0)) { + if (tcp_debug > 0) { + fprintf(stderr, "%d: client disconnected\n", myPid); + } + exit(EXIT_SUCCESS); + } + + start(start_argc, start_argv); + fprintf(clientout, "\n----------------------------\n\n"); + fflush(clientout); + } + } + } + } +}