📄 common.c
字号:
/*common.cCopyright (C) 1999, 2000 Lars Brinkhoff. See COPYING for terms and conditions.Code common to both htc and hts.*/#include <time.h>#include <stdio.h>#include <netdb_.h>#include <fcntl.h>#include <stdlib.h>#include <signal.h>#include <syslog_.h>#include <termios.h>#include <sys/poll_.h>#include "tunnel.h"#include "common.h"#ifndef TRUE#define TRUE 1#define FALSE 0#endif#ifdef DEBUG_MODEstatic voidlog_level (int level, char *fmt0, va_list ap){ if (debug_level >= level) { struct tm *t2; char s[40]; time_t t; int i; time (&t); t2 = localtime (&t); strftime (s, sizeof s, "%Y%m%d %H%M%S ", t2); fprintf (debug_file, "%s", s); for (i = 1; i < level; i++) fprintf (debug_file, " "); vfprintf (debug_file, fmt0, ap); fprintf (debug_file, "\n"); fflush (debug_file); }}#endifvoidlog_exit (int status){ log_notice ("exit with status = %d", status); exit (status);}voidlog_notice (char *fmt0, ...){ va_list ap; va_start(ap, fmt0);#ifdef DEBUG_MODE log_level (1, fmt0, ap);#else vsyslog (LOG_NOTICE, fmt0, ap);#endif va_end(ap);}voidlog_error (char *fmt0, ...){ va_list ap; va_start(ap, fmt0);#ifdef DEBUG_MODE log_level (2, fmt0, ap);#else vsyslog (LOG_ERROR, fmt0, ap);#endif va_end(ap);}#ifdef DEBUG_MODEvoidlog_debug (char *fmt0, ...){ va_list ap; va_start(ap, fmt0); log_level (3, fmt0, ap); va_end(ap);}#endif#ifdef DEBUG_MODEvoidlog_verbose (char *fmt0, ...){ va_list ap; va_start(ap, fmt0); log_level (4, fmt0, ap); va_end(ap);}#endif#ifdef DEBUG_MODEvoidlog_annoying (char *fmt0, ...){ va_list ap; va_start (ap, fmt0); log_level (5, fmt0, ap); va_end(ap);}#endifintserver_socket (int port, int backlog){ struct sockaddr_in address; int i, s; s = socket (PF_INET, SOCK_STREAM, 0); if (s == -1) return -1; i = 1; if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof i) == -1) { log_error ("server_socket: setsockopt SO_REUSEADDR: %s", strerror (errno)); } address.sin_family = PF_INET; address.sin_port = htons ((short)port); address.sin_addr.s_addr = INADDR_ANY; if (bind (s, (struct sockaddr *)&address, sizeof (address)) == -1) { close (s); return -1; } if (listen (s, (unsigned)backlog) == -1) { close (s); return -1; } return s;}intset_address (struct sockaddr_in *address, const char *host, int port){ address->sin_family = PF_INET; address->sin_port = htons ((short)port); address->sin_addr.s_addr = inet_addr (host); if (address->sin_addr.s_addr == INADDR_NONE) { struct hostent *ent; unsigned int ip; log_annoying ("set_address: gethostbyname (\"%s\")", host); ent = gethostbyname (host); log_annoying ("set_address: ent = %p", ent); if (ent == 0) return -1; memcpy(&address->sin_addr.s_addr, ent->h_addr, (unsigned)ent->h_length); ip = ntohl (address->sin_addr.s_addr); log_annoying ("set_address: host = %d.%d.%d.%d", ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); } return 0;}intopen_device (char *device){ struct termios t; int fd; fd = open (device, O_RDWR | O_NONBLOCK); if (fd == -1) return -1; if (tcgetattr (fd, &t) == -1) { if (errno == ENOTTY || errno == EINVAL) return fd; else return -1; } t.c_iflag = 0; t.c_oflag = 0; t.c_lflag = 0; if (tcsetattr (fd, TCSANOW, &t) == -1) return -1; return fd;}#ifdef DEBUG_MODEvoiddump_buf (FILE *f, unsigned char *buf, size_t len){ const int N = 20; int i, j; for (i = 0; i < len;) { fputc ('[', f); for (j = 0; j < N && i + j < len; j++) fprintf (f, "%02x", buf[i + j]); for (; j < N; j++) fprintf (f, " "); fputc (']', f); fputc ('[', f); for (j = 0; j < N && i + j < len; j++) { int c = buf[i + j]; if (c < ' ' || c > 126) fputc ('.', f); else fputc (c, f); } fputc (']', f); fputc ('\n', f); i += j; }}#endifinthandle_device_input (Tunnel *tunnel, int fd, int events){ unsigned char buf[10240]; ssize_t n, m; if (events & POLLIN) { n = read (fd, buf, sizeof buf); if (n == 0 || n == -1) { if (n == -1 && errno != EAGAIN) log_error ("handle_device_input: read() error: %s", strerror (errno)); return n; }#ifdef DEBUG_MODE log_annoying ("read %d bytes from device:", n); if (debug_level >= 5) dump_buf (debug_file, buf, (size_t)n);#endif m = tunnel_write (tunnel, buf, (size_t)n); log_annoying ("tunnel_write (%p, %p, %d) = %d", tunnel, buf, n, m); return m; } else if (events & POLLHUP) { log_error ("handle_device_input: POLLHUP"); sleep (5); } else if (events & POLLERR) log_error ("handle_device_input: POLLERR"); else if (events & POLLNVAL) log_error ("handle_device_input: POLLINVAL"); else log_error ("handle_device_input: none of the above"); errno = EIO; return -1;}inthandle_tunnel_input (Tunnel *tunnel, int fd, int events){ unsigned char buf[10240]; ssize_t n, m; if (events & POLLIN) { n = tunnel_read (tunnel, buf, sizeof buf); if (n <= 0) {log_annoying ("handle_tunnel_input: tunnel_read() = %d\n", n); if (n == -1 && errno != EAGAIN) log_error ("handle_tunnel_input: tunnel_read() error: %s", strerror (errno)); return n; }#ifdef DEBUG_MODE log_annoying ("read %d bytes from tunnel:", n); if (debug_level >= 5) dump_buf (debug_file, buf, (size_t)n);#endif m = write_all (fd, buf, (size_t)n); log_annoying ("write_all (%d, %p, %d) = %d", fd, buf, n, m); return m; } else if (events & POLLHUP) log_error ("handle_device_input: POLLHUP"); else if (events & POLLERR) log_error ("handle_device_input: PULLERR"); else if (events & POLLNVAL) log_error ("handle_device_input: PULLINVAL"); else log_error ("handle_device_input: none of the above"); errno = EIO; return -1;}voidname_and_port (const char *nameport, char **name, int *port){ char *p; *name = strdup (nameport); if (*name == NULL) { fprintf (stderr, "Out of memory\n"); exit (1); } p = strchr (*name, ':'); if (p != NULL) { *port = atoi (p + 1); *p = '\0'; }}intatoi_with_postfix (const char *s_){ char *s = strdup (s_); int n = strlen (s); int factor = 1; int x; if (s == NULL) { fprintf (stderr, "Out of memory\n"); exit (1); } switch (s[n - 1]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; case 'k': case 'K': factor = 1024; break; case 'M': factor = 1024 * 1024; break; case 'G': factor = 1024 * 1024 * 1024; break; default: fprintf (stderr, "Unknown postfix: %c\n", s[n - 1]); exit (1); } if (factor != 1) s[n - 1] = '\0'; x = factor * atoi (s); free (s); return x;}#ifdef DEBUG_MODERETSIGTYPElog_sigpipe (int sig){ log_debug ("caught SIGPIPE"); signal (SIGPIPE, log_sigpipe);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -