udphole

Basic UDP wormhole proxy
git clone git://git.finwo.net/app/udphole
Log | Files | Refs | README | LICENSE

common.c (2622B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <unistd.h>
      5 #include <sys/ioctl.h>
      6 
      7 #include "common.h"
      8 
      9 #ifndef NULL
     10 #define NULL (void*)0
     11 #endif
     12 
     13 struct cli_command *cli_commands = NULL;
     14 
     15 const char *cli_find_arg(int argc, const char **argv, const char *name) {
     16   for (int i = 0; i < argc - 1; i++)
     17     if (strcmp(argv[i], name) == 0)
     18       return argv[i + 1];
     19   return NULL;
     20 }
     21 
     22 size_t cli_collect_positional(int argc, const char **argv, int start,
     23     const char **out, size_t max_out) {
     24   size_t n = 0;
     25   for (int i = start; i < argc && n < max_out; i++) {
     26     if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] != '\0') {
     27       i++;
     28       continue;
     29     }
     30     out[n++] = argv[i];
     31   }
     32   return n;
     33 }
     34 
     35 const char *cli_resolve_default_config(void) {
     36   static char buf[1024];
     37   const char *home = getenv("HOME");
     38   if (home) {
     39     snprintf(buf, sizeof(buf), "%s/.config/udphole.conf", home);
     40     if (access(buf, R_OK) == 0) return buf;
     41     snprintf(buf, sizeof(buf), "%s/.udphole.conf", home);
     42     if (access(buf, R_OK) == 0) return buf;
     43   }
     44   if (access("/etc/udphole/udphole.conf", R_OK) == 0) return "/etc/udphole/udphole.conf";
     45   if (access("/etc/udphole.conf", R_OK) == 0) return "/etc/udphole.conf";
     46   return NULL;
     47 }
     48 
     49 int cli_get_output_width(int default_width) {
     50   if (!isatty(STDOUT_FILENO))
     51     return default_width;
     52   struct winsize w;
     53   if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0 || w.ws_col <= 0)
     54     return default_width;
     55   return (int)w.ws_col;
     56 }
     57 
     58 void cli_print_wrapped(FILE *out, const char *text, int width, int left_col_width) {
     59   if (!text || width <= left_col_width)
     60     return;
     61   char *copy = strdup(text);
     62   if (!copy)
     63     return;
     64   int len = left_col_width;
     65   char *tok = strtok(copy, " ");
     66   while (tok) {
     67     int toklen = (int)strlen(tok);
     68     if (len + 1 + toklen > width) {
     69       fprintf(out, "\n%*s", left_col_width, "");
     70       len = left_col_width;
     71     }
     72     if (len > left_col_width)
     73       fputc(' ', out);
     74     fputs(tok, out);
     75     len += (len > left_col_width ? 1 : 0) + toklen;
     76     tok = strtok(NULL, " ");
     77   }
     78   free(copy);
     79 }
     80 
     81 void cli_register_command(const char *name, const char *description, int (*fn)(int, const char **)) {
     82   struct cli_command *cmd = malloc(sizeof(*cmd));
     83   cmd->cmd = name;
     84   cmd->desc = description;
     85   cmd->fn = fn;
     86   cmd->next = cli_commands;
     87   cli_commands = cmd;
     88 }
     89 
     90 int cli_execute_command(int argc, const char **argv) {
     91   struct cli_command *cmd = cli_commands;
     92 
     93   while(cmd) {
     94     if (!strcmp(cmd->cmd, argv[0])) return cmd->fn(argc, argv);
     95     cmd = cmd->next;
     96   }
     97 
     98   fprintf(stderr, "Unknown command: %s\n", argv[0]);
     99   return 1;
    100 }