udphole

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

common.c (2665B)


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