]> prime8.dev >> repos - ttyd.git/commitdiff
Re organize and format code
authorShuanglei Tao <tsl0922@gmail.com>
Sat, 17 Sep 2016 03:58:40 +0000 (11:58 +0800)
committerShuanglei Tao <tsl0922@gmail.com>
Sat, 17 Sep 2016 03:58:40 +0000 (11:58 +0800)
CMakeLists.txt
README.md
http.c
protocol.c
server.c
server.h
utils.c [new file with mode: 0644]
utils.h [new file with mode: 0644]

index 3a3485ee841a1c7d416e79dd74cf0fcfa84347dd..0499f95dbd699c697c741acf5543e7348858d234 100644 (file)
@@ -3,7 +3,7 @@ set(CMAKE_C_STANDARD 99)
 
 project(ttyd)
 
-set(SOURCE_FILES server.c http.c protocol.c)
+set(SOURCE_FILES server.c http.c protocol.c utils.c)
 
 find_package(OpenSSL REQUIRED)
 find_package(Libwebsockets QUIET)
index 0cf80017332b86aabdc465119ebec849f19a1ad7..862e7096b748e825bef506d8a0124f72838e6b4e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ brew install ttyd --HEAD
 Ubuntu as example:
 
 ```bash
-sudo apt-get install cmake libwebsockets-dev libjson-c-dev libssl-dev
+sudo apt-get install cmake g++ pkg-config git vim-common libwebsockets-dev libjson-c-dev libssl-dev
 git clone https://github.com/tsl0922/ttyd.git
 cd ttyd && mkdir build && cd build
 cmake ..
diff --git a/http.c b/http.c
index 7c167a625d55fe0e4b17ab2735ec347c091c6d8e..c7d1681e5b50ef14274222e392446e39efd14e32 100644 (file)
--- a/http.c
+++ b/http.c
@@ -34,7 +34,7 @@ check_auth(struct lws *wsi) {
         return 1;
     if (lws_add_http_header_by_token(wsi,
                                      WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
-                                     (unsigned char *)"Basic realm=\"ttyd\"",
+                                     (unsigned char *) "Basic realm=\"ttyd\"",
                                      18, &p, end))
         return 1;
     if (lws_add_http_header_content_length(wsi, 0, &p, end))
index 7bce529b547823a2335c4996d2377864fb4a18e9..b581e279f66385fd5d7d0b8285bc0d54d56240af 100644 (file)
 
 #define BUF_SIZE 1024
 
-char *
-base64_encode(const unsigned char *buffer, size_t length) {
-    BIO *bio, *b64;
-    BUF_MEM *bptr;
-
-    b64 = BIO_new(BIO_f_base64());
-    bio = BIO_new(BIO_s_mem());
-    b64 = BIO_push(b64, bio);
-
-    BIO_write(b64, buffer, (int) length);
-    BIO_flush(b64);
-    BIO_get_mem_ptr(b64, &bptr);
-
-    char *data = (char *)malloc(bptr->length);
-    memcpy(data, bptr->data, bptr->length-1);
-    data[bptr->length-1] = 0;
-
-    BIO_free_all(b64);
-
-    return data;
-}
-
 int
 send_initial_message(struct lws *wsi) {
     unsigned char message[LWS_PRE + 256];
@@ -76,7 +54,7 @@ parse_window_size(const char *json) {
     }
     rows = json_object_get_int(o);
 
-    struct winsize *size = malloc(sizeof(struct winsize));
+    struct winsize *size = t_malloc(sizeof(struct winsize));
     memset(size, 0, sizeof(struct winsize));
     size->ws_col = (unsigned short) columns;
     size->ws_row = (unsigned short) rows;
@@ -151,10 +129,10 @@ thread_run_command(void *args) {
                 if (FD_ISSET (pty, &des_set)) {
                     memset(buf, 0, BUF_SIZE);
                     bytes = (int) read(pty, buf, BUF_SIZE);
-                    struct pty_data *frame = (struct pty_data *) malloc(sizeof(struct pty_data));
+                    struct pty_data *frame = (struct pty_data *) t_malloc(sizeof(struct pty_data));
                     frame->len = bytes;
                     if (bytes > 0) {
-                        frame->data = malloc((size_t) bytes);
+                        frame->data = t_malloc((size_t) bytes);
                         memcpy(frame->data, buf, bytes);
                     }
                     pthread_mutex_lock(&client->lock);
@@ -212,7 +190,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                 // read error or client exited, close connection
                 if (frame->len <= 0) {
                     STAILQ_REMOVE_HEAD(&client->queue, list);
-                    free(frame);
+                    t_free(frame);
                     return -1;
                 }
 
@@ -222,7 +200,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                 unsigned char *p = &message[LWS_PRE];
                 size_t n = sprintf((char *) p, "%c%s", OUTPUT, b64_text);
 
-                free(b64_text);
+                t_free(b64_text);
 
                 if (lws_write(wsi, p, n, LWS_WRITE_TEXT) < n) {
                     lwsl_err("lws_write\n");
@@ -230,8 +208,8 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                 }
 
                 STAILQ_REMOVE_HEAD(&client->queue, list);
-                free(frame->data);
-                free(frame);
+                t_free(frame->data);
+                t_free(frame);
 
                 if(lws_partial_buffered(wsi)){
                     lws_callback_on_writable(wsi);
@@ -266,7 +244,7 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
                         if (ioctl(client->pty, TIOCSWINSZ, size) == -1) {
                             lwsl_err("ioctl TIOCSWINSZ: %d (%s)\n", errno, strerror(errno));
                         }
-                        free(size);
+                        t_free(size);
                     }
                     break;
                 default:
index 153b7b656405b4befb92bdea0ddaab081c122ad4..aba04060554cf6d304a5ad4763d5d94481c5432d 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1,94 +1,75 @@
 #include "server.h"
 
-#ifdef __linux__
-/*
- *  sys_signame -- an ordered list of signals.
- *  lifted from /usr/include/linux/signal.h
- *  this particular order is only correct for linux.
- *  this is _not_ portable.
- */
-const char *sys_signame[NSIG] = {
-    "zero",  "HUP",  "INT",   "QUIT", "ILL",   "TRAP", "IOT",  "UNUSED",
-    "FPE",   "KILL", "USR1",  "SEGV", "USR2",  "PIPE", "ALRM", "TERM",
-    "STKFLT","CHLD", "CONT",  "STOP", "TSTP",  "TTIN", "TTOU", "IO",
-    "XCPU",  "XFSZ", "VTALRM","PROF", "WINCH", NULL
-};
-#endif
-
 volatile bool force_exit = false;
 struct lws_context *context;
 struct tty_server *server;
 
 // websocket protocols
 static const struct lws_protocols protocols[] = {
-        {"http-only", callback_http, 0, 0},
-        {"tty", callback_tty, sizeof(struct tty_client), 128},
-        {NULL, NULL, 0, 0}
+        {"http-only", callback_http, 0,                         0},
+        {"tty",       callback_tty,  sizeof(struct tty_client), 128},
+        {NULL, NULL,                 0,                         0}
 };
 
 // websocket extensions
 static const struct lws_extension extensions[] = {
         {"permessage-deflate", lws_extension_callback_pm_deflate, "permessage-deflate"},
-        {"deflate-frame", lws_extension_callback_pm_deflate, "deflate_frame"},
+        {"deflate-frame",      lws_extension_callback_pm_deflate, "deflate_frame"},
         {NULL, NULL, NULL}
 };
 
 // command line options
 static const struct option options[] = {
-        {"port",          required_argument, NULL, 'p'},
-        {"interface",     required_argument, NULL, 'i'},
-        {"credential",    required_argument, NULL, 'c'},
-        {"uid",           required_argument, NULL, 'u'},
-        {"gid",           required_argument, NULL, 'g'},
-        {"signal",        required_argument, NULL, 's'},
-        {"reconnect",     required_argument, NULL, 'r'},
-#ifdef LWS_OPENSSL_SUPPORT
-        {"ssl",           no_argument,       NULL, 'S'},
-        {"ssl-cert",      required_argument, NULL, 'C'},
-        {"ssl-key",       required_argument, NULL, 'K'},
-        {"ssl-ca",        required_argument, NULL, 'A'},
-#endif
-        {"debug",         required_argument, NULL, 'd'},
-        {"help",          no_argument,       NULL, 'h'},
-        {NULL, 0, 0,                               0}
+        {"port", required_argument, NULL, 'p'},
+        {"interface", required_argument, NULL, 'i'},
+        {"credential", required_argument, NULL, 'c'},
+        {"uid", required_argument, NULL, 'u'},
+        {"gid", required_argument, NULL, 'g'},
+        {"signal", required_argument, NULL, 's'},
+        {"reconnect", required_argument, NULL, 'r'},
+        {"ssl", no_argument, NULL, 'S'},
+        {"ssl-cert", required_argument, NULL, 'C'},
+        {"ssl-key", required_argument, NULL, 'K'},
+        {"ssl-ca", required_argument, NULL, 'A'},
+        {"debug", required_argument, NULL, 'd'},
+        {"help", no_argument, NULL, 'h'},
+        {NULL, 0, 0, 0}
 };
 static const char *opt_string = "p:i:c:u:g:s:r:aSC:K:A:d:vh";
 
 void print_help() {
     fprintf(stderr, "ttyd is a tool for sharing terminal over the web\n\n"
-                    "USAGE: ttyd [options] <command> [<arguments...>]\n\n"
-                    "OPTIONS:\n"
-                    "\t--port, -p              Port to listen (default: 7681)\n"
-                    "\t--interface, -i         Network interface to bind\n"
-                    "\t--credential, -c        Credential for Basic Authentication (format: username:password)\n"
-                    "\t--uid, -u               User id to run with\n"
-                    "\t--gid, -g               Group id to run with\n"
-                    "\t--signal, -s            Signal to send to the command when exit it (default: SIGHUP)\n"
-                    "\t--reconnect, -r         Time to reconnect for the client in seconds (default: 10)\n"
-#ifdef LWS_OPENSSL_SUPPORT
-                    "\t--ssl, -S               Enable ssl\n"
-                    "\t--ssl-cert, -C          Ssl certificate file path\n"
-                    "\t--ssl-key, -K           Ssl key file path\n"
-                    "\t--ssl-ca, -A            Ssl ca file path\n"
-#endif
-                    "\t--debug, -d             Set log level (0-9, default: 7)\n"
-                    "\t--help, -h              Print this text and exit\n"
+            "USAGE: ttyd [options] <command> [<arguments...>]\n\n"
+            "OPTIONS:\n"
+            "\t--port, -p              Port to listen (default: 7681)\n"
+            "\t--interface, -i         Network interface to bind\n"
+            "\t--credential, -c        Credential for Basic Authentication (format: username:password)\n"
+            "\t--uid, -u               User id to run with\n"
+            "\t--gid, -g               Group id to run with\n"
+            "\t--signal, -s            Signal to send to the command when exit it (default: SIGHUP)\n"
+            "\t--reconnect, -r         Time to reconnect for the client in seconds (default: 10)\n"
+            "\t--ssl, -S               Enable ssl\n"
+            "\t--ssl-cert, -C          Ssl certificate file path\n"
+            "\t--ssl-key, -K           Ssl key file path\n"
+            "\t--ssl-ca, -A            Ssl ca file path\n"
+            "\t--debug, -d             Set log level (0-9, default: 7)\n"
+            "\t--help, -h              Print this text and exit\n"
     );
 }
 
-struct tty_server*
+struct tty_server *
 tty_server_new(int argc, char **argv) {
     struct tty_server *ts;
     size_t cmd_len = 0;
 
-    ts = malloc(sizeof(struct tty_server));
+    ts = t_malloc(sizeof(struct tty_server));
     LIST_INIT(&ts->clients);
     ts->client_count = 0;
     ts->credential = NULL;
     ts->reconnect = 10;
     ts->sig_code = SIGHUP;
     ts->sig_name = strdup("SIGHUP");
-    ts->argv = malloc(sizeof(char *) * (argc + 1));
+    ts->argv = t_malloc(sizeof(char *) * (argc + 1));
     for (int i = 0; i < argc; i++) {
         ts->argv[i] = strdup(argv[i]);
         cmd_len += strlen(ts->argv[i]);
@@ -98,11 +79,11 @@ tty_server_new(int argc, char **argv) {
     }
     ts->argv[argc] = NULL;
 
-    ts->command = malloc(cmd_len);
+    ts->command = t_malloc(cmd_len);
     char *ptr = ts->command;
     for (int i = 0; i < argc; i++) {
         ptr = stpcpy(ptr, ts->argv[i]);
-        if (i != argc -1) {
+        if (i != argc - 1) {
             sprintf(ptr++, "%c", ' ');
         }
     }
@@ -110,37 +91,6 @@ tty_server_new(int argc, char **argv) {
     return ts;
 }
 
-char *
-uppercase(char *str) {
-    int i = 0;
-    do {
-        str[i] = (char) toupper(str[i]);
-    } while (str[i++] != '\0');
-    return str;
-}
-
-// Get human readable signal string
-int
-get_sig_name(int sig, char *buf) {
-    int n = sprintf(buf, "SIG%s", sig < NSIG ? sys_signame[sig] : "unknown");
-    uppercase(buf);
-    return n;
-}
-
-// Get signal code from string like SIGHUP
-int
-get_sig(const char *sig_name) {
-    if (strcasestr(sig_name, "sig") != sig_name || strlen(sig_name) <= 3) {
-        return -1;
-    }
-    for (int sig = 1; sig < NSIG; sig++) {
-        const char *name = sys_signame[sig];
-        if (strcasecmp(name, sig_name + 3) == 0)
-            return sig;
-    }
-    return -1;
-}
-
 void
 sig_handler(int sig) {
     char sig_name[20];
@@ -154,16 +104,16 @@ int
 calc_command_start(int argc, char **argv) {
     // make a copy of argc and argv
     int argc_copy = argc;
-    char **argv_copy = malloc(sizeof(char *) * argc);
+    char **argv_copy = t_malloc(sizeof(char *) * argc);
     for (int i = 0; i < argc; i++) {
         argv_copy[i] = strdup(argv[i]);
     }
 
     // do not print error message for invalid option
     opterr = 0;
-    while(getopt_long(argc_copy, argv_copy, opt_string, options, NULL) != -1)
-        ;;
-    int start= -1;
+    while (getopt_long(argc_copy, argv_copy, opt_string, options, NULL) != -1);
+
+    int start = -1;
     if (optind < argc) {
         char *command = argv_copy[optind];
         for (int i = 0; i < argc; i++) {
@@ -176,9 +126,9 @@ calc_command_start(int argc, char **argv) {
 
     // free argv copy
     for (int i = 0; i < argc; i++) {
-        free(argv_copy[i]);
+        t_free(argv_copy[i]);
     }
-    free(argv_copy);
+    t_free(argv_copy);
 
     // reset for next use
     opterr = 1;
@@ -217,12 +167,10 @@ main(int argc, char **argv) {
 
     int debug_level = 7;
     char iface[128] = "";
-#ifdef LWS_OPENSSL_SUPPORT
     bool ssl = false;
     char cert_path[1024] = "";
     char key_path[1024] = "";
     char ca_path[1024] = "";
-#endif
 
     // parse command line options
     int c;
@@ -239,7 +187,7 @@ main(int argc, char **argv) {
                 break;
             case 'i':
                 strncpy(iface, optarg, sizeof(iface));
-                iface[sizeof(iface)-1] = '\0';
+                iface[sizeof(iface) - 1] = '\0';
                 break;
             case 'c':
                 if (strchr(optarg, ':') == NULL) {
@@ -254,22 +202,20 @@ main(int argc, char **argv) {
             case 'g':
                 info.gid = atoi(optarg);
                 break;
-            case 's':
-                {
-                    int sig = get_sig(optarg);
-                    if (sig > 0) {
-                        server->sig_code = get_sig(optarg);
-                        server->sig_name = uppercase(strdup(optarg));
-                    } else {
-                        fprintf(stderr, "ttyd: invalid signal: %s\n", optarg);
-                        return -1;
-                    }
+            case 's': {
+                int sig = get_sig(optarg);
+                if (sig > 0) {
+                    server->sig_code = get_sig(optarg);
+                    server->sig_name = uppercase(strdup(optarg));
+                } else {
+                    fprintf(stderr, "ttyd: invalid signal: %s\n", optarg);
+                    return -1;
                 }
+            }
                 break;
             case 'r':
                 server->reconnect = atoi(optarg);
                 break;
-#ifdef LWS_OPENSSL_SUPPORT
             case 'S':
                 ssl = true;
                 break;
@@ -285,7 +231,6 @@ main(int argc, char **argv) {
                 strncpy(ca_path, optarg, sizeof(ca_path) - 1);
                 ca_path[sizeof(ca_path) - 1] = '\0';
                 break;
-#endif
             case '?':
                 break;
             default:
@@ -298,7 +243,6 @@ main(int argc, char **argv) {
 
     if (strlen(iface) > 0)
         info.iface = iface;
-#ifdef LWS_OPENSSL_SUPPORT
     if (ssl) {
         info.ssl_cert_filepath = cert_path;
         info.ssl_private_key_filepath = key_path;
@@ -320,7 +264,6 @@ main(int argc, char **argv) {
         info.options |= LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS;
 #endif
     }
-#endif
 
     signal(SIGINT, sig_handler);
 
@@ -356,15 +299,15 @@ main(int argc, char **argv) {
 
     // cleanup
     if (server->credential != NULL)
-        free(server->credential);
-    free(server->command);
+        t_free(server->credential);
+    t_free(server->command);
     int i = 0;
     do {
-        free(server->argv[i++]);
+        t_free(server->argv[i++]);
     } while (server->argv[i] != NULL);
-    free(server->argv);
-    free(server->sig_name);
-    free(server);
+    t_free(server->argv);
+    t_free(server->sig_name);
+    t_free(server);
 
     return 0;
 }
index 4f9417342cf1c225662ef34b4d10673bc8b9cafe..dd29ed4b48e839d62cd5091ed2cd54bf6926db9e 100644 (file)
--- a/server.h
+++ b/server.h
@@ -1,12 +1,8 @@
 #include "lws_config.h"
 
-// warning: implicit declaration of function
-#define _GNU_SOURCE
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
-#include <ctype.h>
 #include <signal.h>
 #include <string.h>
 #include <fcntl.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <assert.h>
 
 #ifdef __APPLE__
+
 #include <util.h>
+
 #else
 #include <pty.h>
 #endif
@@ -28,6 +27,8 @@
 #include <libwebsockets.h>
 #include <json.h>
 
+#include "utils.h"
+
 extern volatile bool force_exit;
 extern struct lws_context *context;
 extern struct tty_server *server;
diff --git a/utils.c b/utils.c
new file mode 100644 (file)
index 0000000..f32564e
--- /dev/null
+++ b/utils.c
@@ -0,0 +1,102 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+
+// http://web.mit.edu/~svalente/src/kill/kill.c
+#ifdef __linux__
+/*
+ *  sys_signame -- an ordered list of signals.
+ *  lifted from /usr/include/linux/signal.h
+ *  this particular order is only correct for linux.
+ *  this is _not_ portable.
+ */
+const char *sys_signame[NSIG] = {
+    "zero",  "HUP",  "INT",   "QUIT", "ILL",   "TRAP", "IOT",  "UNUSED",
+    "FPE",   "KILL", "USR1",  "SEGV", "USR2",  "PIPE", "ALRM", "TERM",
+    "STKFLT","CHLD", "CONT",  "STOP", "TSTP",  "TTIN", "TTOU", "IO",
+    "XCPU",  "XFSZ", "VTALRM","PROF", "WINCH", NULL
+};
+#endif
+
+void *
+t_malloc(size_t size) {
+    if (size == 0)
+        return NULL;
+    void *p = malloc(size);
+    if (!p)
+        abort();
+    return p;
+}
+
+void t_free(void *p) {
+    if (p)
+        free(p);
+}
+
+void *
+t_realloc(void *p, size_t size) {
+    if ((size == 0) && (p == NULL))
+        return NULL;
+    p = realloc(p, size);
+    if (!p)
+        abort();
+    return p;
+}
+
+char *
+uppercase(char *str) {
+    int i = 0;
+    do {
+        str[i] = (char) toupper(str[i]);
+    } while (str[i++] != '\0');
+    return str;
+}
+
+int
+get_sig_name(int sig, char *buf) {
+    int n = sprintf(buf, "SIG%s", sig < NSIG ? sys_signame[sig] : "unknown");
+    uppercase(buf);
+    return n;
+}
+
+int
+get_sig(const char *sig_name) {
+    if (strcasestr(sig_name, "sig") != sig_name || strlen(sig_name) <= 3) {
+        return -1;
+    }
+    for (int sig = 1; sig < NSIG; sig++) {
+        const char *name = sys_signame[sig];
+        if (strcasecmp(name, sig_name + 3) == 0)
+            return sig;
+    }
+    return -1;
+}
+
+char *
+base64_encode(const unsigned char *buffer, size_t length) {
+    BIO *bio, *b64;
+    BUF_MEM *bptr;
+
+    b64 = BIO_new(BIO_f_base64());
+    bio = BIO_new(BIO_s_mem());
+    b64 = BIO_push(b64, bio);
+
+    BIO_write(b64, buffer, (int) length);
+    BIO_flush(b64);
+    BIO_get_mem_ptr(b64, &bptr);
+
+    char *data = (char *) t_malloc(bptr->length);
+    memcpy(data, bptr->data, bptr->length - 1);
+    data[bptr->length - 1] = 0;
+
+    BIO_free_all(b64);
+
+    return data;
+}
\ No newline at end of file
diff --git a/utils.h b/utils.h
new file mode 100644 (file)
index 0000000..c8ffade
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,32 @@
+#ifndef TTYD_UTIL_H
+#define TTYD_UTIL_H
+
+// malloc with NULL check
+void *
+t_malloc(size_t size);
+
+// free with NULL check
+void
+t_free(void *p);
+
+// realloc with NULL check
+void *
+t_realloc(void *p, size_t size);
+
+// Convert a string to upper case
+char *
+uppercase(char *str);
+
+// Get human readable signal string
+int
+get_sig_name(int sig, char *buf);
+
+// Get signal code from string like SIGHUP
+int
+get_sig(const char *sig_name);
+
+// Encode text to base64, the caller should free the returned string
+char *
+base64_encode(const unsigned char *buffer, size_t length);
+
+#endif //TTYD_UTIL_H