#include #include #include #include #include #include #include "utils.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define INT_DIGITS 19 /* enough for 64 bit integer */ #ifdef HAS_SYSLOG int use_syslog = 0; #endif #ifndef __MINGW32__ void ERROR(const char *s) { char *msg = strerror(errno); LOGE("%s: %s", s, msg); } #endif #ifdef __MINGW32__ char *ss_itoa(int i) #else char *itoa(int i) #endif { /* Room for INT_DIGITS digits, - and '\0' */ static char buf[INT_DIGITS + 2]; char *p = buf + INT_DIGITS + 1; /* points to terminating '\0' */ if (i >= 0) { do { *--p = '0' + (i % 10); i /= 10; } while (i != 0); return p; } else /* i < 0 */ { do { *--p = '0' - (i % 10); i /= 10; } while (i != 0); *--p = '-'; } return p; } char *ss_strndup(const char *s, size_t n) { size_t len = strlen(s); char *ret; if (len <= n) return strdup(s); ret = malloc(n + 1); strncpy(ret, s, n); ret[n] = '\0'; return ret; } void FATAL(const char *msg) { LOGE("%s", msg); exit(-1); } void usage() { printf("\n"); printf("shadowsocks-libev %s\n\n", VERSION); printf(" maintained by Max Lv and Linus Yang \n\n"); printf(" usage:\n\n"); printf(" ss-[local|redir|server|tunnel]\n"); printf(" -s host name or ip address of your remote server\n"); printf(" -p port number of your remote server\n"); printf(" -l port number of your local server\n"); printf(" -k password of your remote server\n"); printf("\n"); printf(" [-m ] encrypt method, supporting table, rc4,\n"); printf(" aes-128-cfb, aes-192-cfb, aes-256-cfb,\n"); printf(" bf-cfb, camellia-128-cfb, camellia-192-cfb,\n"); printf(" camellia-256-cfb, cast5-cfb, des-cfb,\n"); printf(" idea-cfb, rc2-cfb and seed-cfb\n"); printf(" [-f ] valid path to the pid file\n"); printf(" [-t ] socket timeout in seconds\n"); printf(" [-c ] json format config file\n"); printf("\n"); printf(" [-i ] specific network interface to bind,\n"); printf(" not available in redir mode\n"); printf(" [-b ] specific local address to bind,\n"); printf(" not available in server mode\n"); printf(" [-u] udprelay mode to supprot udp traffic\n"); printf(" not available in redir mode\n"); printf(" [-L :] setup a local port forwarding tunnel\n"); printf(" only available in tunnel mode\n"); printf(" [-v] verbose mode, debug output in console\n"); printf("\n"); } void demonize(const char* path) { #ifndef __MINGW32__ /* Our process ID and Session ID */ pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { FILE *file = fopen(path, "w"); if (file == NULL) FATAL("Invalid pid file\n"); fprintf(file, "%d", pid); fclose(file); exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); #endif }