Exemplo n.º 1
0
Arquivo: eval.c Projeto: S010/misc
struct expr    *
exec(struct expr * e, struct context * ctx)
{
	struct expr    *a, *re;
	struct args     args;
	struct list    *l;

	if (!e || list_len(e) < 2) {
		free_expr(e);
		return empty_list();
	}
	memset(&args, 0, sizeof(args));
	for (l = e->v.list->next; l != NULL; l = l->next) {
		a = eval(l->v, ctx);
		build_argv(a, &args);
		full_free_expr(a);
	}

	re = do_exec(&args);

	free_expr(e);
	free_args(&args);

	return re;
}
Exemplo n.º 2
0
/* Run tlsdate and redirects stdout to the monitor_fd */
int
tlsdate (struct state *state)
{
  char **new_argv;
  pid_t pid;
  switch ((pid = fork()))
    {
    case 0: /* child! */
      break;
    case -1:
      perror ("fork() failed!");
      return -1;
    default:
      verb_debug ("[tlsdate-monitor] spawned tlsdate: %d", pid);
      state->tlsdate_pid = pid;
      return 0;
   }
  if (!(new_argv = build_argv (&state->opts)))
    fatal ("out of memory building argv");
  /* Replace stdout with the pipe back to tlsdated */
  if (dup2 (state->tlsdate_monitor_fd, STDOUT_FILENO) < 0)
    {
      perror ("dup2 failed");
      _exit (2);
    }
  execve (new_argv[0], new_argv, state->envp);
  perror ("execve() failed");
  _exit (1);
}
Exemplo n.º 3
0
/* Build argv from matched node. */
static void
build_argv(struct cnode *cnode, struct vector *args, vindex_t vindex,
           struct vector *argv) {
  /* Reach to top node return here. */
  if (cnode_is_top(cnode)) {
    return;
  }

  /* Set node. */
  if (CHECK_FLAG(cnode->flags, CNODE_FLAG_SET_NODE)) {
    return;
  }

  /* Delete node. */
  if (CHECK_FLAG(cnode->flags, CNODE_FLAG_DELETE_NODE)) {
    return;
  }

  /* Recursive call. */
  build_argv(cnode->parent, args, vindex - 1, argv);

  /* When cnode is keyword set it otherwise set input arg.*/
  if (cnode_is_keyword(cnode)) {
    vector_set(argv, cnode->name);
  } else {
    vector_set(argv, vector_slot(args, vindex));
  }
}
Exemplo n.º 4
0
void assignCommand(char* varname, ARGLIST* arglist) {
  pid_t pid;
  int state;
  /* file descriptor to pipe data from command */
  int fd[2];

  char** argv = build_argv(arglist);
  char* output = (char*)malloc(sizeof(char[LIMIT]));

  pipe(fd);
  if((pid = fork()) == 0) {
    dup2(fd[1], STDOUT_FILENO);
    execvp(argv[0], argv);
    exit(1);
  }
  if(waitpid(pid, &state, 0) < 0) {
    perror("WAITPID");
    kill(pid, SIGKILL);
  }

  /* read the output into a variable */
  read(fd[0], output, LIMIT);
  output[LIMIT-1] = '\0';
  addToVarList(varname, output);
  free(argv);
}
Exemplo n.º 5
0
static void
expr_term(struct num_exp_ctx *ctx, unsigned int *vp)
{
	char	*tok;

	tok = expr_get(ctx);
	if (*tok == '(') {
		expr_eval(ctx, vp, 1);
		expr_expect(ctx, ')');
	} else if (isdigit(*tok)) {
		char	*ep;

		*vp = strtoul(tok, &ep, 0);
		if (*ep)
			expr_fail(ctx);
	} else if (*tok == '$') {
		sc_macro_t	*mac;
		char		*argv[32];
		int		argc;

		if (!(mac = find_macro(ctx->state->profile, tok + 1)))
			expr_fail(ctx);
		argc = build_argv(ctx->state, "<expr>", mac->value, argv, 32);
		if (argc < 0
		 || get_uint_eval(ctx->state, argc, argv, vp) < 0)
			expr_fail(ctx);
	} else {
		parse_error(ctx->state,
			"Unexpected token \"%s\" in expression",
			tok);
		expr_fail(ctx);
	}
}
Exemplo n.º 6
0
int process_command_line(command_line* cmd_line) {
	int child_pid = fork();
	if (child_pid == 0) {
		// use pipe's fd for piping
		if (cmd_line->piped) {
			dup3(cmd_line->pipe_filedes[0], FD_STDIN);
			dup3(cmd_line->target_command_line->pipe_filedes[1], FD_STDOUT);
		}

		usleep(DELAY_EXEC_IN_MICRO_SECOND);

		char **argv = build_argv(cmd_line);
		execvp(argv[0], argv);
		fprintf(stderr, "failed to execute command \'%s\': No such file or directory\n", argv[0]);
		exit(-1);
	}

	cmd_line->pid = child_pid;
	
	if (equal_str(cmd_line->action, "wait")) {
		pid_t pid;
		int status;
		while ((pid = waitpid(child_pid, &status, 0))) {
			if (pid == -1 && errno == EINTR) {
				continue;
			}

			break;
		}
	}

	return 0;
}
void aplogd_load_usr_cfg(int argc, char* argv[])
{
    if (1 < argc) {
        DPRINT("Using cmd line argv\n");
        parse_usr_cfg(argc, argv);
    } else {
        /* Make cfg_prop static so that we can point usr_cfg_* persistent vars
         * at it from build_argv() & parse_usr_cfg().  This way we can avoid
         * making more copies.  In this way it will mimic the original argv
         * content. */
        static char cfg_prop[PROPERTY_VALUE_MAX];
        property_get(USR_CFG_PROP, cfg_prop, "");
        DPRINT(USR_CFG_PROP "=%s\n", cfg_prop);
        if ('\0' == cfg_prop[0]) {
            /* Just use the defaults. */
            DPRINT("Using default user config\n");
        } else {
            DPRINT("Building argv from " USR_CFG_PROP "\n");
            int new_argc;
            char** new_argv = build_argv(cfg_prop, &new_argc);
            if (new_argv) {
                parse_usr_cfg(new_argc, new_argv);
                free(new_argv);
            } else {
                /* Just use the defaults. */
                EPRINT("Couldn't parse " USR_CFG_PROP "; using default user config\n");
            }
        }
    }
    DPRINT("usr_cfg_collect=%s\n", usr_cfg_collect);
    DPRINT("usr_cfg_format=%s\n", usr_cfg_format);
    DPRINT("usr_cfg_size=%u\n", usr_cfg_size);
    DPRINT("usr_cfg_seq=%u\n", usr_cfg_seq);
    DPRINT("usr_cfg_ext=%u\n", usr_cfg_ext);
}
Exemplo n.º 8
0
static int
build_argv(struct state *cur, const char *cmdname,
		scconf_list *list, char **argv, unsigned int max)
{
	unsigned int	argc;
	const char	*str;
	sc_macro_t	*mac;
	int		r;

	for (argc = 0; list; list = list->next) {
		if (argc >= max) {
			parse_error(cur, "%s: too many arguments", cmdname);
			return SC_ERROR_INVALID_ARGUMENTS;
		}

		str = list->data;
		if (str[0] != '$') {
			argv[argc++] = list->data;
			continue;
		}

		/* Expand macro reference */
		if (!(mac = find_macro(cur->profile, str + 1))) {
			parse_error(cur, "%s: unknown macro \"%s\"",
					cmdname, str);
			return SC_ERROR_SYNTAX_ERROR;
		}

#if 0
		{
			scconf_list *list;

			printf("Expanding macro %s:", mac->name);
			for (list = mac->value; list; list = list->next)
				printf(" %s", list->data);
			printf("\n");
		}
#endif
		r = build_argv(cur, cmdname, mac->value,
				argv + argc, max - argc);
		if (r < 0)
			return r;

		argc += r;
	}

	return argc;
}
Exemplo n.º 9
0
/* The main entry point for the Windows version.  We save away all GUI
   related stuff, parse the command line and finally call the real
   main.  */
int WINAPI
WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
{
  char **argv;
  int argc;

  /* We use the GetCommandLine function because that also includes the
     program name in contrast to the CMDLINE arg. */
  argv = build_argv (GetCommandLineA (), 0);
  if (!argv)
    return 2; /* Can't do much about a malloc failure.  */
  for (argc=0; argv[argc]; argc++)
    ;

  glob_hinst = hinst;

  return w32_main (argc, argv);
}
Exemplo n.º 10
0
void		lexer(t_vars *v)
{
  static int	loop;

  if (v->alias && which_it_is(v) != BUILT_ALI)
    {
      if (loop < 10 && is_there_an_alias(v))
	{
	  loop += 1;
	  build_argv(v);
	  lexer(v);
	}
      else if (loop == 10)
	loop = 0;
    }
  else if (there_is_home(v))
    modify_prompt_for_home(v);
  loop = 0;
}
Exemplo n.º 11
0
static int
process_command(struct state *cur, struct command *cmd_info, scconf_list *list)
{
	const char	*cmd = cmd_info->name;
	char		*argv[32];
	int		argc, max = 32;

	if (cmd_info->max_args >= 0 && max > cmd_info->max_args)
		max = cmd_info->max_args;

	if ((argc = build_argv(cur, cmd, list, argv, max)) < 0)
		return argc;

	if (argc < cmd_info->min_args) {
		parse_error(cur, "%s: not enough arguments\n", cmd);
		return 1;
	}
	return cmd_info->func(cur, argc, argv);
}
Exemplo n.º 12
0
/*
 * Run tlsdate in a child process. We fork it off, then wait a specified time
 * for it to exit; if it hasn't exited by then, we kill it and log a baffled
 * message. We return tlsdate's exit code if tlsdate exits normally, and a
 * negative value if we can't launch it or it exits uncleanly, so this function
 * returns 0 for success and nonzero for failure, with >0 being a tlsdate exit
 * code and <0 being an exec/fork/wait error.
 */
int
tlsdate (struct opts *opts, char *envp[])
{
  pid_t pid;
  build_argv(opts);
  
  if ((pid = fork ()) > 0)
    {
      /*
       * We launched tlsdate; wait for up to kMaxTries intervals of
       * kWaitBetweenTries for it to exit, then kill it if it still
       * hasn't.
       */
      int status = -1;
      int i = 0;
      for (i = 0; i < opts->subprocess_tries; ++i)
  {
    info ("wait for child attempt %d", i);
    if (waitpid (-1, &status, WNOHANG) > 0)
      break;
    sleep (opts->subprocess_wait_between_tries);
  }
      if (i == opts->subprocess_tries)
  {
    error ("child hung?");
    kill (pid, SIGKILL);
    /* still have to wait() so we don't leak the child. */
    wait (&status);
    return -1;
  }
      info ("child exited with %d", status);
      return WIFEXITED (status) ? WEXITSTATUS (status) : -1;
    }
  else if (pid < 0)
    {
      pinfo ("fork() failed");
      return -1;
    }
  execve (opts->argv[0], opts->argv, envp);
  pinfo ("execve() failed");
  exit (1);
}
Exemplo n.º 13
0
int euca_exec_no_wait(const char *file, ...)
{
    int result = 0;
    char **argv = NULL;

    {
        va_list va;
        va_start(va, file);
        argv = build_argv(file, va);
        va_end(va);
        if (argv == NULL)
            return EUCA_INVALID_ERROR;
    }

    pid_t pid;
    result = euca_execvp_fd(&pid, NULL, NULL, NULL, argv);
    free_char_list(argv);

    return result;
}
Exemplo n.º 14
0
void runCommand(ARGLIST* arglist, int background) {
	pid_t pid;
	int state;

    char** argv = build_argv(arglist);

	if((pid = fork()) == 0){
		execvp(argv[0], argv);
		exit(1);
	}
    if(background) {
        addToJobList(pid, argv[0]);
    } else {
        if(waitpid(pid, &state, 0) < 0){
            perror("WAITPID");
            kill(pid, SIGKILL);
        }
    }
	free(argv);
}
Exemplo n.º 15
0
void possible_command::print(int is_last, FILE *fp)
{
  build_argv();
  if (IS_BSHELL(argv[0])
      && argv[1] != 0 && strcmp(argv[1], BSHELL_DASH_C) == 0
      && argv[2] != 0 && argv[3] == 0)
    fputs(argv[2], fp);
  else {
    fputs(argv[0], fp);
    string str;
    for (int i = 1; argv[i] != 0; i++) {
      str.clear();
      append_arg_to_string(argv[i], str);
      put_string(str, fp);
    }
  }
  if (is_last)
    putc('\n', fp);
  else
    fputs(" | ", fp);
}
Exemplo n.º 16
0
Arquivo: eval.c Projeto: S010/misc
int
build_argv(struct expr * e, struct args * a)
{
	struct list    *l;

	if (!e || !a)
		return 0;

	if (e->t == LATOM) {
		dbgprintf("build_argv: an atom\n");

		if (!e->v.atom || !e->v.atom->v)
			return 0;

		if (!a->argv) {
			a->argv = malloc(sizeof(char *) * 2);
			a->argv[0] = strdup(e->v.atom->v);
			a->argv[1] = NULL;
			a->argc = 1;
		} else {
			a->argv = realloc(a->argv, sizeof(char *) * (a->argc + 2));
			a->argv[a->argc++] = strdup(e->v.atom->v);
			a->argv[a->argc] = NULL;
		}

		dbgprintf("build_argv: added \"%s\"\n", a->argv[a->argc - 1]);

		return a->argc;
	} else if (e->t == LLIST) {
		for (l = e->v.list; l != NULL; l = l->next) {
			dbgprintf("build_argv: descending into list\n");
			build_argv(l->v, a);
		}
		return a->argc;
	}
}
Exemplo n.º 17
0
//!
//! Run a daemonized program and maintain its state. If a PID file is given, it will check if the
//! process is currently running and if the running process matches the given program. If not, the
//! current process will be terminated and restarted with the new program. If the process is running
//! and matche our program name, it will be left alone. If the process is not currently running,
//! it will be started.
//!
//! @param[in] psPidFilePath a constant string pointer to the PID file path
//! @param[in] psRootWrap a constant string pointer to the rootwrap program location
//! @param[in] force set to TRUE if we want to kill the process regardless of its state and restart it. Otherwise set to FALSE.
//! @param[in] psProgram a constant string pointer to the pathname of a program which is to be executed
//! @param[in] ... the list of string arguments to pass to the program
//!
//! @return 0 on success or 1 on failure
//!
//! @pre
//!     - psProgram should not be NULL
//!     - There more be more than 1 variable argument provided
//!
//! @post
//!     On success, the program is executed and its PID is recorded in the psPidFilePath location if provided. If
//!     the process is already running, nothing will change. On failure, depending of where it occured, the system
//!     is left into a non-deterministic state from the caller's perspective.
//!
//! @note
//!
//! @todo
//!     We should move this to something more global under util/euca_system.[ch]
//!
int eucanetd_run_program(const char *psPidFilePath, const char *psRootWrap, boolean force, const char *psProgram, ...)
{
#define PID_STRING_LEN       32

    int i = 0;
    int rc = 0;
    char *psPidId = NULL;
    char *pString = NULL;
    char **argv = NULL;
    char sPid[PID_STRING_LEN] = "";
    char sFilePath[EUCA_MAX_PATH] = "";
    char sCommand[EUCA_MAX_PATH] = "";
    const char *psProgramName = psProgram;
    FILE *pFh = NULL;
    pid_t pid = 0;
    boolean found = FALSE;
    va_list va = { {0} };

    // Make sure we know what app we are running
    if (!psProgram) {
        return (1);
    }
    // turn variable arguments into a array of strings for the euca_execvp_fd()
    va_start(va, psProgram);
    {
        argv = build_argv(psProgram, va);
    }
    va_end(va);

    // Make sure we have a valid arg list
    if (argv == NULL)
        return (1);

    //
    // Set the psProgramName properly. If its currently the rootwrap program, then move to the
    // next argument in the list
    //
    if (!strcmp(psProgram, psRootWrap)) {
        // We should have another argument or I don't see how we can run rootwrap without something else?!?!?
        if (argv[1] == NULL) {
            free_char_list(argv);
            return (1);
        }
        // We're good, use the next argument
        psProgramName = argv[1];
    }
    // Do we need to check if we have the exact same program running?
    if (psPidFilePath) {
        found = FALSE;

        // Does the PID file exists?
        if ((rc = check_file(psPidFilePath)) == 0) {
            //
            // read and make sure the command matches. If it does not match, we will need to restart.
            //
            if ((psPidId = file2str(psPidFilePath)) != NULL) {
                snprintf(sFilePath, EUCA_MAX_PATH, "/proc/%s/cmdline", psPidId);
                // Check if the process is running
                if (check_file(sFilePath) == 0) {
                    // read the old command and make sure we have the same command running
                    if ((pFh = fopen(sFilePath, "r")) != NULL) {
                        if (fgets(sCommand, EUCA_MAX_PATH, pFh)) {
                            if (strstr(sCommand, psProgramName)) {
                                // process is running, and is indeed psProgram
                                found = TRUE;
                            }
                        }
                        fclose(pFh);
                    }
                }

                EUCA_FREE(psPidId);
            }

            if (found) {
                // pidfile passed in and process is already running
                if (force) {
                    // kill process and remove pidfile
                    LOGTRACE("Stopping '%s'\n", psProgramName);
                    rc = safekillfile(psPidFilePath, psProgramName, 9, psRootWrap);
                } else {
                    // nothing to do
                    LOGTRACE("Program '%s' running properly. Nothing to do.\n", psProgramName);
                    free_char_list(argv);
                    return (0);
                }
            } else {
                // pidfile passed in but process is not running
                unlink(psPidFilePath);
            }
        }

    }
    // Build the command string for debugging purpose
    for (i = 0, pString = sCommand; argv[i] != NULL; i++) {
        pString += snprintf(pString, (EUCA_MAX_PATH - (pString - sCommand)), "%s ", argv[i]);
    }

    rc = euca_execvp_fd(&pid, NULL, NULL, NULL, argv);
    LOGTRACE("Executed '%s'. PID=%d, RC=%d\n", sCommand, pid, rc);
    free_char_list(argv);

    if (psPidFilePath) {
        snprintf(sPid, PID_STRING_LEN, "%d", pid);
        rc = write2file(psPidFilePath, sPid);
    }
    return (rc);

#undef PID_STRING_LEN
}
Exemplo n.º 18
0
/* Parse the line. */
enum cparse_result
cparse(char *line, struct cnode *top, struct cparam *param, int exec) {
  uint32_t i;
  uint32_t j;
  char *arg;
  struct cnode *cnode;
  enum match_type current;

  struct vector *args;
  struct vector *matched;
  struct vector *candidate;
  struct vector *argv;

  /* Arguments, matched and candidate. */
  args = param->args;
  matched = param->matched;
  candidate = param->candidate;
  argv = param->argv;

  /* Lexical analysis. */
  clex(line, args);

  /* Set top candidate. */
  vector_reset(candidate);
  vector_append(candidate, top->v);

  /* Empty line. */
  if (vector_max(args) == 0) {
    return CPARSE_EMPTY_LINE;
  }

  /* Parse user input arguments. */
  for (i = 0; i < vector_max(args); i++) {
    /* Set current word to arg. */
    arg = vector_slot(args, i);

    /* Empty tail space. */
    if (strcmp(arg, "") == 0) {
      if (param->index > 0) {
        param->index--;
      }
      if (args->max > 0) {
        args->max--;
      }
      param->tail = 1;
      break;
    }

    /* Remember index. */
    param->index = i;

    /* Starting from no match. */
    current = NONE_MATCH;

    /* Rest matched vector. */
    vector_reset(matched);

    /* Match with schema. */
    for (j = 0; j < vector_max(candidate); j++) {
      enum match_type match = NONE_MATCH;

      cnode = vector_slot(candidate, j);

      if (exec == CPARSE_EXEC_MODE || exec == CPARSE_CONFIG_EXEC_MODE) {
        cnode_schema_match(cnode, arg, &match);
      }

      if (exec == CPARSE_CONFIG_MODE ||
          (exec == CPARSE_CONFIG_EXEC_MODE && match == NONE_MATCH)) {
        if (strcmp(arg, cnode->name) == 0) {
          match = KEYWORD_MATCH;
        }
      }

      if (match == NONE_MATCH) {
        continue;
      }

      if (match > current) {
        vector_reset(matched);
        current = match;
        vector_set(matched, cnode);
      } else if (match == current) {
        vector_set(matched, cnode);
      }

      if (CHECK_FLAG(cnode->flags, CNODE_FLAG_SET_NODE)) {
        SET32_FLAG(param->flags, CNODE_FLAG_SET_NODE);
      }

      if (CHECK_FLAG(cnode->flags, CNODE_FLAG_DELETE_NODE)) {
        SET32_FLAG(param->flags, CNODE_FLAG_DELETE_NODE);
      }
    }

    /* There is no match. */
    if (vector_max(matched) == 0) {
      break;
    }

    /* Update next level schema. */
    vector_reset(candidate);
    for (j = 0; j < vector_max(matched); j++) {
      cnode = vector_slot(matched, j);
      vector_append(candidate, cnode->v);
    }
  }

  /* Match result check. */
  if (vector_max(matched) == 0) {
    return CPARSE_NO_MATCH;
  } else if (vector_max(matched) > 1) {
    return CPARSE_AMBIGUOUS;
  }

  /* Parse success, set matched node. */
  param->exec = vector_first(matched);

  /* Return incomplete if the node is not leaf. */
  if (!cnode_is_leaf(param->exec)) {
    return CPARSE_INCOMPLETE;
  }

  /* Here we can build argc/argv.  This is only possible at this stage
   * since during parsing, we can't determine which node is actually
   * matched.  We allow user to abbreviate input so there could be
   * multiple candidate node during parsing.  */
  if (exec) {
    build_argv(param->exec, args, vector_max(args) - 1, argv);
  }

  /* Success. */
  return CPARSE_SUCCESS;
}
Exemplo n.º 19
0
int
main(int argc, char** argv)
{
	status_t status = init_timers();
	if (status < B_OK) {
		fprintf(stderr, "tcp_tester: Could not initialize timers: %s\n",
			strerror(status));
		return 1;
	}

	_add_builtin_module((module_info*)&gNetStackModule);
	_add_builtin_module((module_info*)&gNetBufferModule);
	_add_builtin_module((module_info*)&gNetSocketModule);
	_add_builtin_module((module_info*)&gNetDatalinkModule);
	_add_builtin_module(modules[0]);
	if (_get_builtin_dependencies() < B_OK) {
		fprintf(stderr, "tcp_tester: Could not initialize modules: %s\n",
			strerror(status));
		return 1;
	}

	sockaddr_in interfaceAddress;
	interfaceAddress.sin_len = sizeof(sockaddr_in);
	interfaceAddress.sin_family = AF_INET;
	interfaceAddress.sin_addr.s_addr = htonl(0xc0a80001);
	gInterface.address = (sockaddr*)&interfaceAddress;
	gInterface.domain = &sDomain;

	status = get_module("network/protocols/tcp/v1", (module_info **)&gTCPModule);
	if (status < B_OK) {
		fprintf(stderr, "tcp_tester: Could not open TCP module: %s\n",
			strerror(status));
		return 1;
	}

	net_protocol* client = init_protocol(&gClientSocket);
	if (client == NULL)
		return 1;
	net_protocol* server = init_protocol(&gServerSocket);
	if (server == NULL)
		return 1;

	setup_context(sClientContext, false);
	setup_context(sServerContext, true);

	printf("*** Server: %p (%ld), Client: %p (%ld)\n", server,
		sServerContext.thread, client, sClientContext.thread);

	setup_server();

	while (true) {
		printf("> ");
		fflush(stdout);

		char line[1024];
		if (fgets(line, sizeof(line), stdin) == NULL)
			break;

        argc = 0;
        argv = build_argv(line, &argc);
        if (argv == NULL || argc == 0)
            continue;

        int length = strlen(argv[0]);

#if 0
		char *newLine = strchr(line, '\n');
		if (newLine != NULL)
			newLine[0] = '\0';
#endif

		if (!strcmp(argv[0], "quit")
			|| !strcmp(argv[0], "exit")
			|| !strcmp(argv[0], "q"))
			break;

		bool found = false;

		for (cmd_entry* command = sBuiltinCommands; command->name != NULL; command++) {
			if (!strncmp(command->name, argv[0], length)) {
				command->func(argc, argv);
				found = true;
				break;
			}
		}

		if (!found)
			fprintf(stderr, "Unknown command \"%s\". Type \"help\" for a list of commands.\n", argv[0]);

		free(argv);
	}

	close_protocol(client);
	close_protocol(server);

	snooze(2000000);

	cleanup_context(sClientContext);
	cleanup_context(sServerContext);

	put_module("network/protocols/tcp/v1");
	uninit_timers();
	return 0;
}