int cmd_call(int argc, CmdArg* argv) { cmd_start(); if (argc < 2) { puts("usage: call <address> <args>\n"); puts(" <address> is subroutine address (pair=ARM, odd=THUMB)\n"); puts(" <args> are subroutine arguments (integers), if any.\n"); puts(" [!] limited to 4 args max subroutines at the moment.\n"); return 0; } else if (argc > 6) { puts("[!] Sorry, call is limited to 4 args max subroutines ATM.\n"); return -1; } else if (argv[1].type!=CMDARG_TYPE_INTEGER) { puts("[!] <address> needs to be an integer !\n"); return -1; } int addr = argv[1].uinteger; int r0, r1, r2, r3; if (argc >= 3) r0 = cmd_get_arg(argv[2]); if (argc >= 4) r1 = cmd_get_arg(argv[3]); if (argc >= 5) r2 = cmd_get_arg(argv[4]); if (argc >= 6) r3 = cmd_get_arg(argv[5]); int (*pSub)(int, int, int, int) = (int (*)(int, int, int, int)) addr; int ret = pSub(r0, r1, r2, r3); printf("returned: %08x\n", ret); return 0; }
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal) { if (strcmp(cmdline, "mem") == 0 && cons->sht != 0) { cmd_mem(cons, memtotal); } else if (strcmp(cmdline, "cls") == 0 && cons->sht != 0) { cmd_cls(cons); } else if (strcmp(cmdline, "dir") == 0 && cons->sht != 0) { cmd_dir(cons, cmdline); } else if (strcmp(cmdline, "task") == 0) { cmd_task(); } else if (strcmp(cmdline, "exit") == 0) { cmd_exit(cons, fat); } else if (strncmp(cmdline, "start ", 6) == 0) { cmd_start(cons, cmdline, memtotal); } else if (strncmp(cmdline, "ncst ", 5) == 0) { cmd_ncst(cons, cmdline, memtotal); } else if (strncmp(cmdline, "langmode ", 9) == 0) { cmd_langmode(cons, cmdline); } else if (strncmp(cmdline, "taskmgr", 7) == 0) { open_taskmgr(memtotal); } else if (cmdline[0] != 0) { if (cmd_app(cons, fat, cmdline) == 0) { /* Ŀ�ǵ嵵 �ƴϰ�, ���ø����̼ǵ� �ƴϰ�, �� �൵ �ƴϴ� */ cons_putstr0(cons, "Bad command or file name.\n\n"); } } return; }
/* ** DBus method call: "RoomStart" */ gboolean on_handle_room_start(Warfacebot *object, GDBusMethodInvocation *invocation) { cmd_start(); warfacebot_complete_room_start(object, invocation); return TRUE; }
int fbimg_cmd(int argc, CmdArg* argv) { cmd_start(); if (argc < 2) { puts("usage: fbimg <address>\n"); return 0; } fb_draw_image((unsigned int*)argv[1].uinteger, 0, 0, gFbTWidth, gFbTHeight); }
/** * Send Prepare Flash request * * @param ucMBaddr * @param ucBank * @return */ UCHAR cmd_prepareflash(UCHAR ucMBaddr, UCHAR ucBank) { UCHAR buf[8]; cmdFrameHeader *pFrame = (cmdFrameHeader *)buf; DEBUG_PUTSTRING1("PREPARE_FLASH addr=", ucMBaddr); pFrame->mbAddr = ucMBaddr; pFrame->cmdId = MB_FUNC_BOOT_PREPAREFLASH; pFrame->subcmdId = ucBank; pFrame->status = 0; cmd_start(); eMBSendFrame(buf, MB_FUNC_BOOT_PREPAREFLASH_SIZE + 1); return cmd_status_wait(); }
int cmd_md(int argc, CmdArg* argv) { cmd_start(); if(argc != 2) { puts("usage: md <address>\n"); return 0; } unsigned int value = GETREG32(argv[1].uinteger); enter_critical_section(); printf("%p\n", value); exit_critical_section(); return value; }
int cmd_mw(int argc, CmdArg* argv) { cmd_start(); if(argc != 3) { puts("usage: mw <address> <value>\n"); return 0; } unsigned int address = argv[1].uinteger; unsigned int value = argv[2].uinteger; SETREG32(address, value); //clear_cpu_caches(); return 0; }
int fb_cmd(int argc, CmdArg* argv) { cmd_start(); int i = 0; if (argc < 2) { puts("usage: fbecho <message>\n"); return 0; } //enter_critical_section(); for (i = 1; i < argc; i++) { fb_print(argv[i].string); fb_print(" "); } //exit_critical_section(); fb_print("\n"); return 0; }
/** * @brief read data through register port, one of the two ports to transfer data. the other one is l2 port * @author Yang Yiming * @date 2012-12-25 * @param [in]pBuf * @param [in]nBufLen * @return T_U32 */ static T_U32 reg_read(T_U8 *pBuf, T_U8 nBufLen) { T_U8 i; T_U32 nRet = 0; clear_interface_status(); REG32(NFC_CMD_REG) = ((nBufLen - 1) << NFC_CMD_REG_INFO_POS) | NFC_CMD_REG_REG_IN_CONF | NFC_CMD_REG_LAST_BIT; cmd_start(); if (AK_FALSE == cmd_end()) return NAND_FAIL_NFC_TIMEOUT; for (i = 0; i < nBufLen; i++) { if (i < 4) { pBuf[i] = (T_U8)(0xFF & (REG32(NFC_DAT_REG1) >> (i << 3))) ; //akerror("Reg_\n",pBuf[i],1); } else {
void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, int memtotal) { if (strcmp(cmdline, "mem") == 0 && cons->sht != 0) { cmd_mem(cons, memtotal); } else if (strcmp(cmdline, "cls") == 0 && cons->sht != 0) { cmd_cls(cons); } else if (strcmp(cmdline, "dir") == 0 && cons->sht != 0) { cmd_dir(cons); } else if (strncmp(cmdline, "type ", 5) == 0 && cons->sht != 0) { cmd_type(cons, fat, cmdline); } else if (strcmp(cmdline, "exit") == 0) { cmd_exit(cons, fat); } else if (strncmp(cmdline, "start ", 6) == 0) { cmd_start(cons, cmdline, memtotal); } else if (strncmp(cmdline, "ncst ", 5) == 0) { cmd_ncst(cons, cmdline, memtotal); } else if (cmdline[0] != 0) { if (cmd_app(cons, fat, cmdline) == 0) { /* コマンドではなく、アプリでもなく、さらに空行でもない */ cons_putstr0(cons, "Bad command.\n\n"); } } return; }
int main (int argc, char *argv[]) { setpgrp(); // Become the leader of its group. // Child's CMD line int m = sysconf(_SC_ARG_MAX); // Maximum CMD line length char *cmd; // Store child's CMD line cmd = (char *) calloc(m, sizeof(char)); // Child's parameters int *child_delay = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *child_delay = 0; // Delay before starting (shared between parent and child) int child_pid = -1; // PID after the fork() int child_status = -1; // Used during waitpid() char *child_file = NULL; // Binary file // Telnet server int ts_port = -1; // TCP (console) and UDP (serial converter) port char *xtitle = "Terminal Server"; // Title for telnet clients // Select parameters int *infd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing int *outfd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing fd_set active_fd_set; // Contains active FD using in select() FD_ZERO(&active_fd_set); fd_set read_fd_set; // Contains FD selected in current loop FD_ZERO(&read_fd_set); // Other parameters int i = -1; // Counter int j = -1; // Counter int opt = NULL; // Store CMD options int rc = -1; // Generic return code char *tmp = NULL; // Generic char string struct sigaction sa; // Manage signals (SIGHUP, SIGTERM...) // Wrapper parameters int child_afsocket[100]; // Store AF_UNIX child sockets memset(&child_afsocket, 0, sizeof(child_afsocket)); int ser_remoteid[64]; // Store Remote Device ID (used for UDP communication) memset(&ser_remoteid, 0, sizeof(ser_remoteid)); int ser_remoteif[64]; // Store Remote Interface ID (used for UDP communication) memset(&ser_remoteif, 0, sizeof(ser_remoteif)); int udpserver_socket = -1; // UDP socket for serial communications int wrapper_afsocket[100]; // Store AF_UNIX wrapper sockets memset(&wrapper_afsocket, 0, sizeof(wrapper_afsocket)); // Parsing options while ((opt = getopt(argc, argv, ":vT:D:d:t:F:x")) != -1) { switch (opt) { default: usage(argv[0]); exit(1); // Begin standard parameters case 'v': printf("%s\n", VERSION); exit(0); case 'T': // Mandatory: Tenant ID tenant_id = atoi(optarg); if (tenant_id < 0) { UNLLog(LLERROR,"Tenant_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Tennant_id = %i\n", tenant_id); break; case 'D': // Mandatory: Device ID device_id = atoi(optarg); if (tenant_id < 0) { UNLLog(LLERROR,"Device_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Device_id = %i\n", device_id); break; case 'F': // Mandatory: IOS child_file = optarg; if (is_file(child_file) != 0) { UNLLog(LLERROR,"File '%s' does not exist.\n", child_file); exit(1); } break; case 'd': // Optional: child's startup delay (default 0) *child_delay = atoi(optarg); if (*child_delay < 0) { UNLLog(LLERROR,"Delay must be integer.\n"); exit(1); } break; case 't': // Optional: telnet window title (default "Terminal Server") xtitle = optarg; break; } } // Checking if tenant_id is set if (tenant_id < 0) { UNLLog(LLERROR,"Tenant ID not set.\n"); exit(1); } // Checking if device_id is set if (device_id < 0) { UNLLog(LLERROR,"Device ID not set.\n"); exit(1); } // Checking if child_file is set if (child_file == NULL) { UNLLog(LLERROR,"Subprocess executable not set.\n"); exit(1); } // Building the CMD line ts_port = 32768 + 128 * tenant_id + device_id; tmp = (char *) malloc(m * sizeof(char)); sprintf(tmp, "/usr/bin/dynamips -N '%s' -T %i", xtitle, ts_port); cmd_add(&cmd, tmp); free(tmp); // Adding parameters after "--" j = 0; for (i = 1; i < argc; i++) { if (j == 1) { // Adding parameter given after "--" cmd_add(&cmd, " "); cmd_add(&cmd, argv[i]); } if (strcmp(argv[i], "--") == 0) { // Found "--" j = 1; } } // Adding the IOS filename cmd_add(&cmd, " "); cmd_add(&cmd, child_file); // Creating PIPEs for select() if ((pipe(infd)) < 0 || pipe(outfd) < 0) { UNLLog(LLERROR, "Failed to create PIPEs (%s).\n", strerror(errno)); exit(1); } // Forking if ((rc = fork()) == 0) { // Child: stating subprocess UNLLog(LLINFO, "Starting child (%s).\n", cmd); if (*child_delay > 0) { // Delay is set, waiting for (; *child_delay > 0;) { rc = write(outfd[1], ".", 1); *child_delay = *child_delay - 1; sleep(1); } rc = write(outfd[1], "\n", 1); } close(STDIN_FILENO); // Closing child's stdin close(STDOUT_FILENO); // Closing child's stdout dup2(infd[0], STDIN_FILENO); // Linking stdin to PIPE dup2(outfd[1], STDOUT_FILENO); // Linking stdout to PIPE dup2(outfd[1], STDERR_FILENO); // Redirect child's stderr to child's stdout close(infd[0]); close(infd[1]); close(outfd[0]); close(outfd[1]); // Start process rc = cmd_start(cmd); // Subprocess terminated, killing the parent UNLLog(LLERROR,"Child terminated (%i).\n", rc); } else if (rc > 0) { // Parent close(infd[0]); // Used by the child close(outfd[1]); // Used by the child // Handling Signals signal(SIGPIPE,SIG_IGN); // Ignoring SIGPIPE when a client terminates sa.sa_handler = &signal_handler; // Setup the sighub handler sa.sa_flags = SA_RESTART; // Restart the system call, if at all possible sigemptyset(&sa.sa_mask); // Signals blocked during the execution of the handler sigaddset(&sa.sa_mask, SIGHUP); // Signal 1 sigaddset(&sa.sa_mask, SIGINT); // Signal 2 sigaddset(&sa.sa_mask, SIGTERM); // Signal 15 sigfillset(&sa.sa_mask); // Intercept SIGHUP, SIGINT, SIGUSR1 and SIGTERM if (sigaction(SIGHUP, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGHUP (%s).\n", strerror(errno)); } if (sigaction(SIGINT, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGINT (%s).\n", strerror(errno)); } if (sigaction(SIGTERM, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGTERM (%s).\n", strerror(errno)); } // Preparing select() FD_ZERO(&active_fd_set); FD_ZERO(&read_fd_set); if (udpserver_socket > 0) { FD_SET(udpserver_socket, &active_fd_set); // Adding UDP socket } // While subprocess is running, check IO from subprocess, telnet clients, socket and network waitpid(child_pid, &child_status, 0); // Child is no more running UNLLog(LLERROR, "Child is no more running.\n"); } else { UNLLog(LLERROR, "Failed to fork (%s).\n", strerror(errno)); exit(1); } exit(0); }
/** * @brief issue nand cycles including command cycle, address cycle, RB cycle etc. * @author Yang Yiming * @date 2012-12-25 * @param [in]nCmdSeq the cycle sequence * @return T_BOOL */ T_BOOL nfc_cycle(T_U32 nCmdSeq,...) { volatile T_U32 *pCmdReg = (T_U32 *)NFC_CMD_REG; T_VOID *pArg = (T_VOID *)&nCmdSeq; T_U32 nCycleVal; T_U16 nCycle; T_U8 nCycleType; T_BOOL bArr = AK_FALSE; T_U8 nDataCnt = 0; T_U8 aWdata[10]; clear_interface_status(); //this block is added in purpose of saving device code text compiled. //course pushing every parameter in stack take more instruction than //just pushing an array and a flag in. if (nCmdSeq == NAND_CYCLE_ARR_FLAG) { pArg = (T_VOID *)((T_U32)pArg + 4); pArg = (T_VOID *)(*(T_U32 *)pArg); bArr = AK_TRUE; } while (1) { nCycle = *(T_U16 *)pArg; if (AK_TRUE == bArr) { pArg = (T_VOID *)((T_U32)pArg + 2); } else { pArg = (T_VOID *)((T_U32)pArg + 4); } nCycleType = GET_NAND_CYCLY_TYPE(nCycle); nCycleVal = (nCycle & NAND_CYCLE_VALUE_MASK) << NFC_CMD_REG_INFO_POS; switch (nCycleType) { case COMMAND_C://command cycle { nCycleVal |= NFC_CMD_REG_CMD_CONF; } break; case ADDRESS_C://address cycle { nCycleVal |= NFC_CMD_REG_ADD_CONF; } break; case DELAY_C://delay several k asic. will it be used? { nCycleVal |= NFC_CMD_REG_DELAY_BIT; } break; case WDATA_C://output data cycle { nCycleVal = (0 << NFC_CMD_REG_INFO_POS) | NFC_CMD_REG_WDATA_CONF; aWdata[nDataCnt] = nCycle & NAND_CYCLE_VALUE_MASK;//get the data value nDataCnt++; } break; case READYB_C://wait for the RB signal { nCycleVal = NFC_CMD_REG_WAIT_JUMP_BIT; } break; case NULL_C://do nothing { continue; } break; case END_C://ending flag , way to exit { pCmdReg[-1] |= NFC_CMD_REG_LAST_BIT; if (nDataCnt > 0)//we use ecc sub module to deliver the data { //config and enable the ECC sub-Module REG32(ECC_CTRL_REG1) = ECC_CTRL_REG1_WRITE_BIT | ECC_CTRL_REG1_NFC_EN_BIT | ECC_CTRL_REG1_ADDR_CLR_BIT | ECC_CTRL_REG1_RESULT_NO_OK_BIT | ECC_CTRL_REG1_NO_ERR_BIT | ECC_CTRL_REG1_END_BIT; REG32(ECC_CTRL_REG2) = (nDataCnt << ECC_CTRL_REG2_SECTSIZE_POS) | (1 << ECC_CTRL_REG2_SECTCNT_POS); REG32(ECC_CTRL_REG3) = MMU_Vaddr2Paddr((T_U32)aWdata) & 0x3FFFF; REG32(ECC_CTRL_REG1) = ECC_CTRL_REG1_WRITE_BIT | ECC_CTRL_REG1_NFC_EN_BIT | ECC_CTRL_REG1_ADDR_CLR_BIT | ECC_CTRL_REG1_RESULT_NO_OK_BIT | ECC_CTRL_REG1_NO_ERR_BIT | ECC_CTRL_REG1_END_BIT | ECC_CTRL_REG1_START_BIT; } cmd_start(); return cmd_end(); } } *pCmdReg = nCycleVal; pCmdReg++; } }
void child_deliver_cmd_hook(pid_t pid, struct account *a, unused struct msg *msg, struct child_deliver_data *data, int *result) { struct mail_ctx *mctx = data->mctx; struct mail *m = data->mail; struct match_command_data *cmddata = data->cmddata; int flags, status, found = 0; char *s, *cause, *lbuf, *out, *err, tag[24]; size_t llen; struct cmd *cmd = NULL; struct rmlist rml; u_int i; /* If this is the parent, do nothing. */ if (pid != 0) { xfree(mctx); return; } /* Sort out the command. */ s = replacepath( &cmddata->cmd, m->tags, m, &m->rml, find_tag(m->tags, "home")); if (s == NULL || *s == '\0') { log_warnx("%s: empty command", a->name); goto error; } log_debug2("%s: %s: started (ret=%d re=%s)", a->name, s, cmddata->ret, cmddata->re.str == NULL ? "none" : cmddata->re.str); flags = CMD_ONCE; if (cmddata->pipe) flags |= CMD_IN; if (cmddata->re.str != NULL) flags |= CMD_OUT; cmd = cmd_start(s, flags, m->data, m->size, &cause); if (cmd == NULL) { log_warnx("%s: %s: %s", a->name, s, cause); goto error; } llen = IO_LINESIZE; lbuf = xmalloc(llen); for (;;) { /* Stop early if looking for regexp only. */ if (found && cmddata->ret == -1) { log_debug3("%s: %s: found. stopping early", a->name, s); status = 1; break; } status = cmd_poll( cmd, &out, &err, &lbuf, &llen, conf.timeout, &cause); if (status == -1) { log_warnx("%s: %s: %s", a->name, s, cause); goto error; } if (status != 0) break; if (err != NULL) log_warnx("%s: %s: %s", a->name, s, err); if (out == NULL) continue; log_debug3("%s: %s: out: %s", a->name, s, out); if (found) continue; found = re_string(&cmddata->re, out, &rml, &cause); if (found == -1) { log_warnx("%s: %s", a->name, cause); goto error; } if (found != 1) continue; /* Save the matches. */ if (!rml.valid) continue; for (i = 0; i < NPMATCH; i++) { if (!rml.list[i].valid) break; xsnprintf(tag, sizeof tag, "command%u", i); add_tag(&m->tags, tag, "%.*s", (int) (rml.list[i].eo - rml.list[i].so), out + rml.list[i].so); } } status--; log_debug2("%s: %s: returned %d, found %d", a->name, s, status, found); cmd_free(cmd); xfree(s); xfree(lbuf); status = cmddata->ret == status; if (cmddata->ret != -1 && cmddata->re.str != NULL) *result = (found && status) ? MATCH_TRUE : MATCH_FALSE; else if (cmddata->ret != -1 && cmddata->re.str == NULL) *result = status ? MATCH_TRUE : MATCH_FALSE; else if (cmddata->ret == -1 && cmddata->re.str != NULL) *result = found ? MATCH_TRUE : MATCH_FALSE; else *result = MATCH_ERROR; return; error: if (cause != NULL) xfree(cause); if (cmd != NULL) cmd_free(cmd); if (s != NULL) xfree(s); if (lbuf != NULL) xfree(lbuf); *result = MATCH_ERROR; }
int main (int argc, char *argv[]) { // Child's CMD line int m = sysconf(_SC_ARG_MAX); // Maximum CMD line length char *cmd; // Store child's CMD line cmd = (char *) calloc(m, sizeof(char)); // Child's parameters int *child_delay = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *child_delay = 0; // Delay before starting (shared between parent and child) int child_pid = -1; // PID after the fork() int child_status = -1; // Used during waitpid() char *child_file = NULL; // Binary file // Telnet server int ts_port = -1; // TCP (console) and UDP (serial converter) port int ts_socket = -1; // Telnet server socket char child_output = '\0'; // Store single char from child char client_input = '\0'; // Store single char from client char *xtitle = "Terminal Server"; // Title for telnet clients // Select parameters int *infd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing int *outfd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing int active_fd = -1; // Contains current active FD fd_set active_fd_set; // Contains active FD using in select() FD_ZERO(&active_fd_set); fd_set read_fd_set; // Contains FD selected in current loop FD_ZERO(&read_fd_set); // Wrapper parameters int child_afsocket = -1; // Store AF_UNIX child socket int *eth_socket = calloc(64, sizeof(int)); // Store FD of ethernet intefaces int *ser_remoteid = calloc(64, sizeof(int));// Store Remote Device ID (used for UDP communication) int *ser_remoteif = calloc(64, sizeof(int));// Store Remote Interface ID (used for UDP communication) int *ser_socket = calloc(64, sizeof(int)); // Store FD of serial intefaces int udpserver_socket = -1; // UDP socket for serial communications int wrapper_afsocket = -1; // Store AF_UNIX wrapper socket // Other parameters int af_ready = 0; // 1 = AF_UNIX files are configured (needed if IOL is delayed) int i = -1; // Counter int j = -1; // Counter int opt = NULL; // Store CMD options int rc = -1; // Generic return code char *tmp = NULL; // Generic char string struct sigaction sa; // Manage signals (SIGHUP, SIGTERM...) setpgrp(); // Check for iourc file tmp = (char *) malloc(m * sizeof(char)); sprintf(tmp, "iourc"); if (is_file(tmp) != 0) { printf("ERR: file '%s' does not exist.\n", tmp); exit(1); } free(tmp); // Adding options to child's CMD line while ((opt = getopt(argc, argv, ":vT:D:d:t:F:e:s:l:")) != -1) { switch (opt) { default: usage(argv[0]); exit(1); // Begin standard parameters case 'v': version(); exit(0); case 'T': // Mandatory: Tenant ID tenant_id = atoi(optarg); if (tenant_id < 0) { printf("ERR: tenant_id must be integer.\n"); exit(1); } break; case 'D': // Mandatory: Device ID device_id = atoi(optarg); if (tenant_id < 0) { printf("ERR: device_id must be integer.\n"); exit(1); } break; case 'F': child_file = optarg; if (is_file(child_file) != 0) { printf("ERR: file '%s' does not exist.\n", child_file); exit(1); } break; case 'd': // Optional: child's startup delay (default 0) *child_delay = atoi(optarg); if (*child_delay < 0) { printf("ERR: delay must be integer.\n"); exit(1); } break; case 't': // Optional: telnet window title (default "Terminal Server") xtitle = optarg; break; // End standard parameters // Optional: number of Ethernet progroups (default: 2) case 'e': child_eth = atoi(optarg); if (child_eth < 0) { printf("ERR: Ethernet portgroup must be integer.\n"); exit(1); } break; // Optional: number of Serial progroups (default: 2) case 's': child_ser = atoi(optarg); if (child_ser < 0) { printf("ERR: Serial portgroup must be numeric.\n"); exit(1); } break; // Optional: Serial link end-point (no default) case 'l': if (udpserver_socket == -1 && tenant_id != -1 && device_id != -1) { // First Serial2UDP definition, must listen() if ((rc = serial2udp_listen(32768 + 128 * tenant_id + device_id, &udpserver_socket)) != 0) { printf("%u:%u ERR: failed to open UDP socket (%i).\n", tenant_id, device_id, rc); exit(1); } // Now add serial end-point if ((rc = serial2udp_add(ser_socket, ser_remoteid, ser_remoteif, optarg)) != 0) { printf("%u:%u ERR: failed to add serial end-point (%i).\n", tenant_id, device_id, rc); exit(1); } } else if (udpserver_socket > 0) { // Serial2UDP wrapper already started, add serial end-point if ((rc = serial2udp_add(ser_socket, ser_remoteid, ser_remoteif, optarg)) != 0) { printf("%u:%u ERR: failed to add serial end-point (%i).\n", tenant_id, device_id, rc); exit(1); } } else { printf("ERR: flag '-l' must be after '-T' and '-D'.\n"); exit(1); } break; } } // Checking if tenant_id is set if (tenant_id < 0) { printf("ERR: tenant ID not set.\n"); exit(1); } // Checking if device_id is set if (device_id < 0) { printf("ERR: device ID not set.\n"); exit(1); } // Checking if child_file is set if (child_file == NULL) { printf("%u:%u ERR: subprocess executable not set.\n", tenant_id, device_id); exit(1); } // Checking total interfaces if (child_eth + child_ser > 16) { printf("%u:%u ERR: Ethernet + Serial portgroups must lower equal than 16.\n", tenant_id, device_id); exit(1); } // Building the CMD line cmd_add(&cmd, "LD_LIBRARY_PATH=/opt/unetlab/addons/iol/lib "); cmd_add(&cmd, child_file); // Adding interfaces tmp = (char *) malloc(m * sizeof(char)); sprintf(tmp, " -e %i -s %i", child_eth, child_ser); cmd_add(&cmd, tmp); free(tmp); // Adding parameters after "--" j = 0; for (i = 1; i < argc; i++) { if (j == 1) { // Adding parameter given after "--" cmd_add(&cmd, " "); cmd_add(&cmd, argv[i]); } if (strcmp(argv[i], "--") == 0) { // Found "--" j = 1; } } // Adding device_id as last tmp = (char *) malloc(m * sizeof(char)); sprintf(tmp, "%i", device_id); cmd_add(&cmd, " "); cmd_add(&cmd, tmp); free(tmp); // Creating NETMAP if ((rc = mk_netmap()) != 0) { printf("%u:%u ERR: failed to create NETMAP file (%i).\n", tenant_id, device_id, rc); exit(1); } // Creating PIPEs for select() if ((pipe(infd)) < 0 || pipe(outfd) < 0) { printf("%u:%u ERR: failed to create PIPEs (%s).\n", tenant_id, device_id, strerror(errno)); exit(1); } // Telnet listen ts_port = 32768 + 128 * tenant_id + device_id; tsclients_socket[0] = 0; if ((rc = ts_listen(ts_port, &ts_socket)) != 0) { printf("%u:%u ERR: failed to open TCP socket (%i).\n", tenant_id, device_id, rc); exit(1); } // Creating TAP interfaces if ((rc = mk_tap(child_eth, eth_socket)) != 0) { printf("%u:%u ERR: failed to create TAP interfaces (%i).\n", tenant_id, device_id, rc); kill(0, SIGTERM); exit(1); } // Forking if ((rc = fork()) == 0) { // Child: starting subprocess if (DEBUG > 0) printf("DEBUG: starting child (%s).\n", cmd); if (*child_delay > 0) { // Delay is set, waiting for (; *child_delay > 0;) { rc = write(outfd[1], ".", 1); *child_delay = *child_delay - 1; sleep(1); } rc = write(outfd[1], "\n", 1); } close(STDIN_FILENO); // Closing child's stdin close(STDOUT_FILENO); // Closing child's stdout dup2(infd[0], STDIN_FILENO); // Linking stdin to PIPE dup2(outfd[1], STDOUT_FILENO); // Linking stdout to PIPE dup2(outfd[1], STDERR_FILENO); // Redirect child's stderr to child's stdout close(infd[0]); close(infd[1]); close(outfd[0]); close(outfd[1]); // Start process rc = cmd_start(cmd); // Subprocess terminated, killing the parent printf("%u:%u ERR: child terminated (%i).\n", tenant_id, device_id, rc); } else if (rc > 0) { // Parent close(infd[0]); // Used by the child close(outfd[1]); // Used by the child // Handling Signals signal(SIGPIPE,SIG_IGN); // Ignoring SIGPIPE when a client terminates sa.sa_handler = &signal_handler; // Setup the sighub handler sa.sa_flags = SA_RESTART; // Restart the system call, if at all possible sigemptyset(&sa.sa_mask); // Signals blocked during the execution of the handler sigaddset(&sa.sa_mask, SIGHUP); // Signal 1 sigaddset(&sa.sa_mask, SIGINT); // Signal 2 sigaddset(&sa.sa_mask, SIGTERM); // Signal 15 sigfillset(&sa.sa_mask); // Intercept SIGHUP, SIGINT, SIGUSR1 and SIGTERM if (sigaction(SIGHUP, &sa, NULL) == -1) { printf("%u:%u ERR: cannot handle SIGHUP (%s).\n", tenant_id, device_id, strerror(errno)); } if (sigaction(SIGINT, &sa, NULL) == -1) { printf("%u:%u ERR: cannot handle SIGINT (%s).\n", tenant_id, device_id, strerror(errno)); } if (sigaction(SIGTERM, &sa, NULL) == -1) { printf("%u:%u ERR: cannot handle SIGTERM (%s).\n", tenant_id, device_id, strerror(errno)); } // Preparing select() FD_ZERO(&active_fd_set); FD_ZERO(&read_fd_set); if (DEBUG > 0) printf("DEBUG: adding subprocess stdout descriptor (%i).\n", outfd[0]); FD_SET(outfd[0], &active_fd_set); // Adding subprocess stdout if (DEBUG > 0) printf("DEBUG: adding telnet socket descriptor (%i).\n", ts_socket); FD_SET(ts_socket, &active_fd_set); // Adding telnet socket if (udpserver_socket > 0) { if (DEBUG > 0) printf("DEBUG: adding UDP socket descriptor (%i).\n", udpserver_socket); FD_SET(udpserver_socket, &active_fd_set); // Adding UDP socket } // Adding TAP interfaces for select() for (i = 0; i <= 63; i++) { if (eth_socket[i] > 0) { if (DEBUG > 0) printf("DEBUG: adding TAP interface descriptor (%i).\n", eth_socket[i]); FD_SET(eth_socket[i], &active_fd_set); } } // While subprocess is running, check IO from subprocess, telnet clients, socket and network while (waitpid(child_pid, &child_status, WNOHANG|WUNTRACED) == 0) { // Creating AF communication from child if (af_ready == 0 && *child_delay == 0) { // wait 3 seconds for AF_UNIX sleep(3); if ((rc = mk_afsocket(&wrapper_afsocket, &child_afsocket)) != 0) {; printf("%u:%u ERR: failed to create AF_UNIX socket file (%i).\n", tenant_id, device_id, rc); kill(0, SIGTERM); break; } af_ready = 1; if (DEBUG > 0) printf("DEBUG: adding wrapper socket descriptor (%i).\n", wrapper_afsocket); FD_SET(wrapper_afsocket, &active_fd_set); // Adding subprocess AF_UNIX socket } // Check if select() is valid read_fd_set = active_fd_set; if ((active_fd = select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL)) <= 0) { printf("%u:%u ERR: failed to select().\n", tenant_id, device_id); kill(0, SIGTERM); break; } if (DEBUG > 2) printf("DEBUG: data from select descriptor (%i).\n", active_fd); // Check if output from child if (FD_ISSET(outfd[0], &read_fd_set)) { if (read(outfd[0], &child_output, 1) <= 0) { printf("%u:%u ERR: error while reading data from the subprocess, killing it.\n", tenant_id, device_id); kill(0, SIGTERM); break; } // Writing to all telnet clients ts_broadcast(child_output, &active_fd_set, tsclients_socket); } // Check if new client is coming if (FD_ISSET(ts_socket, &read_fd_set)) { if ((rc = ts_accept(&active_fd_set, ts_socket, xtitle, tsclients_socket,1)) != 0) { printf("%u:%u ERR: failed to accept a new client (%i).\n", tenant_id, device_id, rc); } } // Check for output from all telnet clients if (ts_receive(&client_input, &read_fd_set, &active_fd_set, tsclients_socket) == 0) { // Write to child rc = write(infd[1], &client_input, 1); if (rc < 0) { printf("%u:%u ERR: error writing to the subprocess, closing.\n", tenant_id, device_id); kill(0, SIGTERM); break; } } // If AF, UDP and TAP sockets are configured, check for packets if (af_ready == 1) { // Check for packets from subprocess if (FD_ISSET(wrapper_afsocket, &read_fd_set)) { if ((rc = packet_af(wrapper_afsocket, eth_socket, ser_socket, ser_remoteid, ser_remoteif)) != 0) { printf("%u:%u ERR: error forwarding packet from AF_UNIX socket to TAP/UDP (%i).\n", tenant_id, device_id, rc); kill(0, SIGTERM); break; } } // Check for packets from TAP interfaces for (i = 0; i <= 63; i++) { if (eth_socket[i] > 0 && FD_ISSET(eth_socket[i], &read_fd_set)) { if ((rc = packet_tap(eth_socket[i], child_afsocket, i)) != 0) { if (rc == 3) { af_ready = 0; printf("Failed to forward TAP => AF_UNIX. Will try to recreate it later...\n"); } else { printf("%u:%u ERR: error forwarding packet from TAP to AF_UNIX socket (%i).\n", tenant_id, device_id, rc); kill(0, SIGTERM); break; } } } } // Check for incoming serial (UDP) packets if (udpserver_socket > 0) { if (FD_ISSET(udpserver_socket, &read_fd_set)) { if ((rc = packet_udp(udpserver_socket, child_afsocket)) != 0) { if (rc == 3) { af_ready = 0; printf("Failed to forward UDP => AF_UNIX. Will try to recreate it later...\n"); } else { printf("%u:%u ERR: error forwarding packet from UDP to AF_UNIX (%i).\n", tenant_id, device_id, rc); kill(0, SIGTERM); break; } } } } } // We should not have other active dscriptor } // Child is no more running printf("%u:%u ERR: child is no more running.\n", tenant_id, device_id); } else { printf("%u:%u ERR: failed to fork.\n", tenant_id, device_id); exit(1); } close(ts_socket); close(wrapper_afsocket); exit(0); }
void cmd_start_wrapper(void) { cmd_start(); }
int deliver_pipe_deliver(struct deliver_ctx *dctx, struct actitem *ti) { struct account *a = dctx->account; struct mail *m = dctx->mail; struct deliver_pipe_data *data = ti->data; char *s, *cause, *err; int status; struct cmd *cmd = NULL; char *lbuf; size_t llen; s = replacepath(&data->cmd, m->tags, m, &m->rml, dctx->udata->home); if (s == NULL || *s == '\0') { log_warnx("%s: empty command", a->name); goto error; } if (data->pipe) { log_debug2("%s: piping to \"%s\"", a->name, s); cmd = cmd_start(s, CMD_IN|CMD_ONCE, m->data, m->size, &cause); } else { log_debug2("%s: executing \"%s\"", a->name, s); cmd = cmd_start(s, 0, NULL, 0, &cause); } if (cmd == NULL) goto error_cause; log_debug3("%s: %s: started", a->name, s); llen = IO_LINESIZE; lbuf = xmalloc(llen); do { status = cmd_poll( cmd, NULL, &err, &lbuf, &llen, conf.timeout, &cause); if (status == -1) { xfree(lbuf); goto error_cause; } if (status == 0 && err != NULL) log_warnx("%s: %s: %s", a->name, s, err); } while (status == 0); status--; xfree(lbuf); if (status != 0) { log_warnx("%s: %s: command returned %d", a->name, s, status); goto error; } cmd_free(cmd); xfree(s); return (DELIVER_SUCCESS); error_cause: log_warnx("%s: %s: %s", a->name, s, cause); xfree(cause); error: if (cmd != NULL) cmd_free(cmd); if (s != NULL) xfree(s); return (DELIVER_FAILURE); }
int main (int argc, char *argv[]) { setpgrp(); // Become the leader of its group. // Child's CMD line int m = sysconf(_SC_ARG_MAX); // Maximum CMD line length char *cmd; // Store child's CMD line cmd = (char *) calloc(m, sizeof(char)); // Child's parameters char *child_file = NULL; // Binary file int child_pid = -1; // PID after the fork() int child_status = -1; // Used during waitpid() // Telnet server int ts_socket = -1; // Telnet server socket int ts_port = -1; // TCP (console) and UDP (serial converter) port char child_output = '\0'; // Store single char from child unsigned char client_input = '\0'; // Store single char from client char *xtitle = "Terminal Server"; // Title for telnet clients // Select parameters int *infd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing int *outfd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing fd_set active_fd_set; // Contains active FD using in select() FD_ZERO(&active_fd_set); fd_set read_fd_set; // Contains FD selected in current loop FD_ZERO(&read_fd_set); // Other parameters int i = -1; // Counter int j = -1; // Counter int opt = NULL; // Store CMD options int rc = -1; // Generic return code struct sigaction sa; // Manage signals (SIGHUP, SIGTERM...) // Parsing options while ((opt = getopt(argc, argv, ":vT:D:t:F:")) != -1) { switch (opt) { default: usage(argv[0]); exit(1); // Begin standard parameters case 'v': printf("%s\n", VERSION); exit(0); case 'T': // Mandatory: Tenant ID tenant_id = atoi(optarg); if (tenant_id < 0) { UNLLog(LLERROR,"Tenant_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Tennant_id = %i\n", tenant_id); break; case 'D': // Mandatory: Device ID device_id = atoi(optarg); if (device_id < 0) { UNLLog(LLERROR,"Device_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Device_id = %i\n", device_id); break; case 'F': // Mandatory: subprocess executable child_file = optarg; if (is_file(child_file) != 0) { UNLLog(LLERROR,"File '%s' does not exist.\n", child_file); exit(1); } break; case 't': // Optional: telnet window title (default "Terminal Server") xtitle = optarg; break; } } // Checking if tenant_id is set if (tenant_id < 0) { UNLLog(LLERROR, "Tenant ID not set.\n"); exit(1); } // Checking if device_id is set if (device_id < 0) { UNLLog(LLERROR, "Device ID not set.\n"); exit(1); } // Checking if child_file is set if (child_file == NULL) { UNLLog(LLERROR, "Subprocess executable not set.\n"); exit(1); } // Building the CMD line cmd_add(&cmd, child_file); // Adding parameters after "--" j = 0; for (i = 1; i < argc; i++) { if (j == 1) { // Adding parameter given after "--" cmd_add(&cmd, " "); cmd_add(&cmd, argv[i]); } if (strcmp(argv[i], "--") == 0) { // Found "--" j = 1; } } // Creating PIPEs for select() if ((pipe(infd)) < 0 || pipe(outfd) < 0) { UNLLog(LLERROR, "Failed to create PIPEs (%s).\n", strerror(errno)); exit(1); } // Telnet listen ts_port = 32768 + 128 * tenant_id + device_id; tsclients_socket[0] = 0; if ((rc = ts_listen(ts_port, &ts_socket)) != 0) { UNLLog(LLERROR, "Failed to open TCP socket (%i).\n", rc); exit(1); } // Forking if ((rc = fork()) == 0) { // Child: stating subprocess UNLLog(LLINFO, "Starting child (%s).\n", cmd); close(STDIN_FILENO); // Closing child's stdin close(STDOUT_FILENO); // Closing child's stdout dup2(infd[0], STDIN_FILENO); // Linking stdin to PIPE dup2(outfd[1], STDOUT_FILENO); // Linking stdout to PIPE dup2(outfd[1], STDERR_FILENO); // Redirect child's stderr to child's stdout close(infd[0]); close(infd[1]); close(outfd[0]); close(outfd[1]); // Start process while (rc == -1 || rc == 0) { // Start console until it fail rc = cmd_start(cmd); } // Subprocess terminated, killing the parent UNLLog(LLERROR, "Child terminated (%i).\n", rc); } else if (rc > 0) { // Parent close(infd[0]); // Used by the child close(outfd[1]); // Used by the child // Handling Signals signal(SIGPIPE,SIG_IGN); // Ignoring SIGPIPE when a client terminates sa.sa_handler = &signal_handler; // Setup the sighub handler sa.sa_flags = SA_RESTART; // Restart the system call, if at all possible sigemptyset(&sa.sa_mask); // Signals blocked during the execution of the handler sigaddset(&sa.sa_mask, SIGHUP); // Signal 1 sigaddset(&sa.sa_mask, SIGINT); // Signal 2 sigaddset(&sa.sa_mask, SIGTERM); // Signal 15 sigfillset(&sa.sa_mask); // Intercept SIGHUP, SIGINT, SIGUSR1 and SIGTERM if (sigaction(SIGHUP, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGHUP (%s).\n", strerror(errno)); } if (sigaction(SIGINT, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGINT (%s).\n", strerror(errno)); } if (sigaction(SIGTERM, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGTERM (%s).\n", strerror(errno)); } // Preparing select() FD_ZERO(&active_fd_set); FD_ZERO(&read_fd_set); FD_SET(outfd[0], &active_fd_set); // Adding subprocess stdout FD_SET(ts_socket, &active_fd_set); // Adding telnet socket // While subprocess is running, check IO from subprocess, telnet clients, socket and network while (waitpid(child_pid, &child_status, WNOHANG|WUNTRACED) == 0) { // Check if select() is valid read_fd_set = active_fd_set; if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) <= 0) { UNLLog(LLERROR, "Failed to select().\n"); kill(0, SIGTERM); break; } // Check if output from child if (FD_ISSET(outfd[0], &read_fd_set)) { if (read(outfd[0], &child_output, 1) <= 0) { UNLLog(LLERROR, "Error while reading data from the subprocess, killing it.\n"); kill(0, SIGTERM); break; } // Writing to all telnet clients ts_broadcast(child_output, &active_fd_set, tsclients_socket); } // Check if new client is coming if (FD_ISSET(ts_socket, &read_fd_set)) { if ((rc = ts_accept(&active_fd_set, ts_socket, xtitle, tsclients_socket,1)) != 0) { UNLLog(LLERROR, "Failed to accept a new client (%i).\n", rc); } } // Check for output from all telnet clients if (ts_receive(&client_input, &read_fd_set, &active_fd_set, tsclients_socket) == 0) { // Write to child rc = write(infd[1], &client_input, 1); if (rc < 0) { UNLLog(LLERROR, "Error writing to the subprocess, closing.\n"); kill(0, SIGTERM); break; } } } } else { UNLLog(LLERROR, "Failed to fork.\n" ); exit(1); } close(ts_socket); exit(0); }