struct pidfile* pidfile_create_(const char *path, enum pidfile_mode mode, int dbglev) { struct pidfile* pidfile = malloc(sizeof(*pidfile)); int retval = 0; assert(pidfile); memset(pidfile, 0, sizeof(*pidfile)); pidfile->path = strdup(path); pidfile->mode = mode; pidfile->dbglev = dbglev; if((retval = pidfile_open(pidfile))!=0){ pidfile_delete(pidfile); return NULL; } return pidfile; }
/* Exit and cleanup */ static void exit_client(int retval) { pidfile_delete(client_config.pidfile); CLOSE_LOG(); exit(retval); }
int main( int argc, char *argv[] ) { int c; int option_index = 0; int received; int mq_id; struct sIPCMsg mymsg; char *ttydev = DEFAULT_TTY; char *parity_s = DEFAULT_PAR; int parity; int baud = DEFAULT_BAUD; USHORT result[255] = {0,}; int result_int = 0; USHORT usLen; eMBErrorCode err = MB_ENOERR; int reg_start = DEFAULT_REGISTER_START; int address = DEFAULT_ADDRESS; int regt = -1; int reg_action = -1; int reg_action_param = -1; int no_reg = -1; int run_forground = 0; int errorcount = 0; struct pidfile *pidfile = NULL; UCHAR *pucFrame; eMBException eException; UCHAR ucFuncType; /* Parse cmd-line options */ while ( (c = getopt_long (argc, argv, "hVd:s:p:r:t:c:a:f", long_options, &option_index)) != EOF ) { switch (c) { case 'h': fprintf(stderr, "%s", helptext); exit(EXIT_SUCCESS); case 'V': exit(EXIT_SUCCESS); case 'd': ttydev = strndup(optarg, MAXLEN); break; case 's': baud = atoi(optarg); break; case 'p': parity_s = strndup(optarg, MAXLEN); break; case 'f': // run in forground run_forground = 1; break; case '?': /* getopt_long already printed an error message. */ default: fprintf(stderr, "%s", helptext); exit(EXIT_SUCCESS); } } if(!run_forground){ fprintf(stderr, "Deamonizing...\n"); daemon(0, 0); } /* Setup signalhandler so that we shut down nicely on CTRL+C */ signal(SIGINT, int_handler); pidfile = pidfile_create(DEFAULT_PIDFILE, PMODE_RETURN, 0); mq_id = create_ipc(); /* Allocate space for an ADU frame */ pucFrame = eMBAllocateFrame(&usLen); while(outer_loop) { if(running == 1) printf("Restarting modbus layer\n"); else { printf("\n\n\n\n Restarting modbus layer\n\n\n\n"); running = 1; errorcount = 0; } /* Parse user inputs... */ if(strcmp(parity_s, "even") == 0) parity = MB_PAR_EVEN; else if(strcmp(parity_s, "odd") == 0) parity = MB_PAR_ODD; else parity = MB_PAR_NONE; PRINT_DBG(1, "init modbus at tty: %s parity %d baud %d", ttydev, parity, baud); /* mode, port, baud, parity */ eMBMasterInit(MB_RTU, ttydev, baud, parity); while(running) { /* Check message queue */ if((received = msgrcv(mq_id, &mymsg, sizeof(mymsg.text), 1, IPC_NOWAIT)) > 0) { /* Address */ address = parse_address(mymsg.text); /* Starting register */ reg_start = parse_reg_start(mymsg.text); /* Register type */ regt = parse_reg_type(mymsg.text); /* Register action */ reg_action_param = 0; reg_action = parse_reg_action(mymsg.text, ®_action_param); /* Optional: number of registers */ no_reg = parse_no_reg(mymsg.text); #ifdef DBG if(dbglev>=1){ printf("Got: %s\n", mymsg.text); printf("Parsing command:\n"); printf("Address: 0x%02x\n", address); printf("Register: %d\n", reg_start); printf("Register type: %d\n", regt); printf("Register action: %d Arg: %d\n", reg_action, reg_action_param); printf("Register count: %d\n", no_reg); } #endif switch(regt) { case MB_TYPE_COILS: switch(reg_action) { case ACTION_READ: err = build_eMBMasterReadCoils (pucFrame, reg_start, reg_action_param, &usLen); break; case ACTION_WRITE: err = build_eMBMasterWriteCoils (pucFrame, reg_start, reg_action_param ? 0xff : 0x0, &usLen); break; case ACTION_WRITEMULTIPLE: err = build_eMBMasterWriteMultipleCoils (pucFrame, reg_start, no_reg, reg_action_param ? 0xff : 0x0, &usLen); break; } break; case MB_TYPE_INPUT: err = build_eMBMasterReadInput (pucFrame, reg_start, reg_action_param, &usLen); break; case MB_TYPE_HOLDING: switch(reg_action) { case ACTION_READ: err = build_eMBMasterReadHolding (pucFrame, reg_start, reg_action_param, &usLen); break; case ACTION_WRITE: err = build_eMBMasterWriteSingleHolding (pucFrame, reg_start, reg_action_param, &usLen); break; } break; } #ifdef DBG if(dbglev){ int n; printf("Dumping built frame:\n"); for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } #endif /* ? */ eMBEnable(); memset(result, 0, sizeof(result)); if(err == MB_EX_NONE) { /* Set the address of the device in question */ eMBSetSlaveAddress(address); /* Send the frame */ if( (err = eMBSendFrame(pucFrame, usLen)) == MB_ENOERR) { printf(" ---- done processing frame ----\n"); eException = MB_EX_ILLEGAL_FUNCTION; ucFuncType = pucFrame[MB_PDU_FUNC_OFF]; #ifdef DBG if(dbglev){ printf("%s():%d - after send...\n", __FUNCTION__, __LINE__); { int n; printf("Dumping received frame:\n"); for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } } #endif if(ucFuncType & 0x80) { UCHAR ucExceptType = pucFrame[MB_PDU_FUNC_OFF+1]; /* We encountered some sort of error */ switch(ucExceptType) { case MB_EX_ILLEGAL_FUNCTION: fprintf(stderr, "Error! Illegal function!\n"); break; case MB_EX_ILLEGAL_DATA_ADDRESS: fprintf(stderr, "Error! Illegal data address!\n"); break; case MB_EX_ILLEGAL_DATA_VALUE: fprintf(stderr, "Error! Illegal data value!\n"); break; case MB_EX_SLAVE_DEVICE_FAILURE: fprintf(stderr, "Error! Slave device failure!\n"); break; default: fprintf(stderr, "Unknown error (%d)!\n", eException); break; } } else { switch(ucFuncType) { case MB_FUNC_READ_COILS: eException = parse_eMBMasterReadCoils(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_WRITE_SINGLE_COIL: eException = parse_eMBMasterWriteCoils(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_READ_INPUT_REGISTER: eException = parse_eMBMasterReadInput(pucFrame, &usLen, (void *)result); #ifdef DBG if(dbglev) printf("Reply (%d): %04x\n", eException, result[0]); #endif break; case MB_FUNC_READ_HOLDING_REGISTER: eException = parse_eMBMasterReadHolding(pucFrame, &usLen, (void *)result); #ifdef DBG printf("Reply: %04x %04x %d %d\n", result[0],result[1], result_int, reg_action_param); #endif break; case MB_FUNC_WRITE_REGISTER: eException = parse_eMBMasterWriteSingleHolding(pucFrame, &usLen, (void *)result); #ifdef DBG printf("Reply: %04x\n", result[0]); #endif break; case MB_FUNC_WRITE_MULTIPLE_COILS: usLen = 5; eException = parse_eMBMasterWriteMultipleCoils(pucFrame, &usLen, (void *)result); if(eException == MB_EX_NONE) printf("Write multiple coils SUCCESS!\n"); else printf("Write multiple coils FAIL!\n"); break; default: printf("Unknown function type : %x\n", ucFuncType); printf("%d : %s()\n", __LINE__, __FUNCTION__); { int n; for(n=0; n<10; n++) printf("%02x ",pucFrame[n]); printf("\n"); } break; } switch(ucFuncType) { case MB_FUNC_READ_HOLDING_REGISTER: case MB_FUNC_READ_INPUT_REGISTER: if(reg_action_param == 2){ printf("!!!!\n"); result_int = (result[0]<<16) | result[1]; }else { result_int = result[0]; } break; default: result_int = result[0]; break; } if(eException == MB_EX_NONE) { snprintf(mymsg.text, sizeof(mymsg.text), "%ld:REG:%d:RESULT:%d", time(NULL), reg_start, result_int); } else { snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Parsing frame"); } #ifdef DBG printf("%s():%d - reply: %s\n", __FUNCTION__, __LINE__, mymsg.text); #endif goto out; } } else { printf("Error sending frame. (%d)\n", err); snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Sending frame"); if(errorcount > 10) running = 0; else errorcount++; } } else { printf("Error in frame arguments.\n"); snprintf(mymsg.text, sizeof(mymsg.text), "ERROR:Wrong argument"); } out: /* Set the reply */ mymsg.type = 2; #ifdef DBG printf("%s():%d - reply: %s\n", __FUNCTION__, __LINE__, mymsg.text); #endif msgsnd(mq_id, &mymsg, sizeof(mymsg.text), IPC_NOWAIT); eMBDisable(); } else { //printf("No messages. Sleeping (%d - %s)\n", received, received < 0 ? strerror(errno) : ""); } usleep(1000); } // free(pucFrame); eMBClose(); } destroy_ipc(PROJ_ID); pidfile_delete(pidfile); return 0; }
int main (int argc, char **argv) { int collectd_argc = 0; char *collectd = NULL; char **collectd_argv = NULL; struct sigaction sa; int i = 0; /* parse command line options */ while (42) { int c = getopt (argc, argv, "hc:P:"); if (-1 == c) break; switch (c) { case 'c': collectd = optarg; break; case 'P': pidfile = optarg; break; case 'h': default: exit_usage (argv[0]); } } for (i = optind; i < argc; ++i) if (0 == strcmp (argv[i], "-f")) break; /* i < argc => -f already present */ collectd_argc = 1 + argc - optind + ((i < argc) ? 0 : 1); collectd_argv = (char **)calloc (collectd_argc + 1, sizeof (char *)); if (NULL == collectd_argv) { fprintf (stderr, "Out of memory."); return 3; } collectd_argv[0] = (NULL == collectd) ? "collectd" : collectd; if (i == argc) collectd_argv[collectd_argc - 1] = "-f"; for (i = optind; i < argc; ++i) collectd_argv[i - optind + 1] = argv[i]; collectd_argv[collectd_argc] = NULL; openlog ("collectdmon", LOG_CONS | LOG_PID, LOG_DAEMON); if (-1 == daemonize ()) return 1; sa.sa_handler = sig_int_term_handler; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); if (0 != sigaction (SIGINT, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } if (0 != sigaction (SIGTERM, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } sa.sa_handler = sig_hup_handler; if (0 != sigaction (SIGHUP, &sa, NULL)) { syslog (LOG_ERR, "Error: sigaction() failed: %s", strerror (errno)); return 1; } while (0 == loop) { int status = 0; if (0 != collectd_start (collectd_argv)) { syslog (LOG_ERR, "Error: failed to start collectd."); break; } assert (0 < collectd_pid); while ((collectd_pid != waitpid (collectd_pid, &status, 0)) && (EINTR == errno)) if ((0 != loop) || (0 != restart)) collectd_stop (); collectd_pid = 0; log_status (status); check_respawn (); if (0 != restart) { syslog (LOG_INFO, "Info: restarting collectd"); restart = 0; } else if (0 == loop) syslog (LOG_WARNING, "Warning: restarting collectd"); } syslog (LOG_INFO, "Info: shutting down collectdmon"); pidfile_delete (); closelog (); free (collectd_argv); return 0; } /* main */
/* Exit and cleanup */ static void exit_server(int retval) { pidfile_delete(server_config.pidfile); CLOSE_LOG(); exit(retval); }