From 7049b5462bae9464c8bec4c066881ec3f1b85822 Mon Sep 17 00:00:00 2001 From: aixiao Date: Fri, 22 Nov 2019 18:57:18 +0800 Subject: [PATCH] optimization --- Makefile | 2 +- conf/cproxy.ini.explain | 4 +- conf/cproxy.transparent.ini | 16 +- cproxy.c | 1 + cproxy_request.c | 24 +- cproxy_request.h | 1 + kill.c | 686 +++++++++++++++--------------------- kill.h | 50 +-- log/cproxy.pid | 1 - 9 files changed, 341 insertions(+), 444 deletions(-) delete mode 100644 log/cproxy.pid diff --git a/Makefile b/Makefile index 21efba5..2a7bb8b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CROSS_COMPILE ?= CC := $(CROSS_COMPILE)gcc STRIP := $(CROSS_COMPILE)strip -CFLAGS += -g -Wall -I../iniparser/src -L../iniparser +CFLAGS += -g -O2 -Wall -I../iniparser/src -L../iniparser LIBS = -liniparser -static OBJ := cproxy diff --git a/conf/cproxy.ini.explain b/conf/cproxy.ini.explain index 2722451..fab54ee 100644 --- a/conf/cproxy.ini.explain +++ b/conf/cproxy.ini.explain @@ -1,5 +1,5 @@ 模块: [server], [http], [https] -[http]、[https]模块关键字: [M], [U], [V], [host], [port], \r, \n, \v, \f, \b, \t, \a. 如果原本请求头含有关键字也会被替换. +[http]、[https]模块关键字: [M], [U], [V], [H], [host], [port], \r, \n, \v, \f, \b, \t, \a. 如果原本请求头含有关键字也会被替换. [server]模块 uid 设置UID @@ -10,6 +10,7 @@ pid_file pid文件 [M] 原请求方法 [U] 原请求url [V] 原请求协议版本 +[H] 原[host]:[port] [host] 原请求host [port] 原请求端口 关键字strrep替换字符串指令. @@ -21,6 +22,7 @@ regrep = "Host*.+?->Host: iread.wo.cn:443"; 以"->"为分界符,匹配到的内 [M] 原请求方法 [U] 原请求url [V] 原请求协议版本 +[H] 原[host]:[port] [host] 原请求host [port] 原请求端口 关键字strrep替换字符串指令. diff --git a/conf/cproxy.transparent.ini b/conf/cproxy.transparent.ini index 9d61ce0..5b1b364 100644 --- a/conf/cproxy.transparent.ini +++ b/conf/cproxy.transparent.ini @@ -7,15 +7,11 @@ pid_file=log/cproxy.pid; http_ip=10.0.0.172; http_port=80; http_del="x-online-host,X-Online-Host,host,Host"; -;http_first="[M] [U] [V]\r\n.aixiao.me\rx-online-host: [host]\r\nhost: iread.wo.cn\r\n"; -http_first="[M] [U] [V]\r\nhost: [host]:[port]\r\n"; -;strrep = "Mi MIX 2->Linux"; +http_first="[M] [U] [V]\r\nhost: [host]\r\n"; + [https] -https_ip=10.0.0.172; -https_port=80; -https_del=",Host"; -;https_first="[M] iread.wo.cn//https://[host]:[port]#iread.wo.cn [V]\r\nhost: iread.wo.cn:443\r\n"; -https_first="[M] [U] [V]\r\nhost: [host]:[port]\r\n"; -;strrep = "Mi MIX 2->Linux"; -;regrep = "Host*.+?->Host: iread.wo.cn:443"; +https_ip=192.168.1.102; +https_port=1080; +https_del="Host"; +https_first="[M] [U] [V]\r\nhost: [H]\r\n"; diff --git a/cproxy.c b/cproxy.c index 8e45c86..54153bb 100644 --- a/cproxy.c +++ b/cproxy.c @@ -325,6 +325,7 @@ int _main(int argc, char *argv[]) break; case 's': if (strcasecmp(optarg, "stop") == 0) { + free_conf(configure); free(header_buffer); stop(1, executable_filename); } diff --git a/cproxy_request.c b/cproxy_request.c index 70c2bdd..a9cab02 100644 --- a/cproxy_request.c +++ b/cproxy_request.c @@ -311,6 +311,14 @@ char *delete_header(char *header_buffer, const char *character, int string) return strcat(header_buffer, p2 + 1); } +char *splice_host_port(char *tmp, char *host, char *port) { + //memset(tmp, 0, strlen(tmp)); + bzero(tmp, strlen(tmp)); + strcat(tmp, host); + strcat(tmp, ":"); + return strcat(tmp, port); +} + int replacement_http_head(char *header_buffer, char *remote_host, int *remote_port, int *SIGN, conf *p) { char *http_firsts = (char *)malloc(strlen(p->http_first) + 1); @@ -429,11 +437,16 @@ int replacement_http_head(char *header_buffer, char *remote_host, int *remote_po new_header_buffer = replace(new_header_buffer, &len, "[V]", 3, V, len_v); new_header_buffer = replace(new_header_buffer, &len, "[host]", 6, remote_host, len_remote_host); - char port_copy[(numbin(*remote_port) + 1)]; + char port_copy[(numbin(*remote_port) + 2)]; sprintf(port_copy, "%d", *remote_port); int len_remote_port = strlen(port_copy); new_header_buffer = replace(new_header_buffer, &len, "[port]", 6, port_copy, len_remote_port); + char H[(len_remote_port + len_remote_host) +1]; + splice_host_port(H, remote_host, port_copy); + int len_h = strlen(H); + new_header_buffer = replace(new_header_buffer, &len, "[H]", 3, H, len_h); + new_header_buffer = replace(new_header_buffer, &len, "\\r", 2, "\r", 1); new_header_buffer = replace(new_header_buffer, &len, "\\n", 2, "\n", 1); new_header_buffer = replace(new_header_buffer, &len, "\\b", 2, "\b", 1); @@ -539,10 +552,17 @@ int replacement_http_head(char *header_buffer, char *remote_host, int *remote_po new_header_buffer = replace(new_header_buffer, &len, "[V]", 3, V, len_v); new_header_buffer = replace(new_header_buffer, &len, "[host]", 6, remote_host, len_remote_host); - char port_copy[(numbin(*remote_port) + 1)]; + char port_copy[(numbin(*remote_port) + 2)]; sprintf(port_copy, "%d", *remote_port); int len_remote_port = strlen(port_copy); new_header_buffer = replace(new_header_buffer, &len, "[port]", 6, port_copy, len_remote_port); + + + char H[(len_remote_port + len_remote_host) +1]; + splice_host_port(H, remote_host, port_copy); + int len_h = strlen(H); + new_header_buffer = replace(new_header_buffer, &len, "[H]", 3, H, len_h); + new_header_buffer = replace(new_header_buffer, &len, "\\r", 2, "\r", 1); new_header_buffer = replace(new_header_buffer, &len, "\\n", 2, "\n", 1); diff --git a/cproxy_request.h b/cproxy_request.h index 2811ea9..cd289ae 100644 --- a/cproxy_request.h +++ b/cproxy_request.h @@ -18,6 +18,7 @@ void rewrite_header(); int numbin(int n); char *splice_head(char *header_buffer, const char *character, char *string); char *delete_header(char *header_buffer, const char *character, int string); +char *splice_host_port(char *tmp, char *host, char *port); int replacement_http_head(char *header_buffer, char *remote_host, int *remote_port, int *SIGN, conf *p); #endif diff --git a/kill.c b/kill.c index 1d29723..3237965 100644 --- a/kill.c +++ b/kill.c @@ -1,23 +1,32 @@ #include "kill.h" -static double -uptime() +static pid_t opt_ns_pid = 0; + +static int exact = 1, reg = 0, wait_until_dead = 1, process_group = 0, ignore_case = 0; +static long younger_than = 0, older_than = 0; + +typedef struct NAMEINFO { + const char *name; + int name_length; + struct stat st; +} NAMEINFO; + +static double uptime() { - char * savelocale; + char *savelocale; char buf[2048]; - FILE* file; - if (!(file=fopen( PROC_BASE "/uptime", "r"))) { - fprintf(stderr, "killall: error opening uptime file\n"); + FILE *file; + if (!(file = fopen(PROC_BASE "/uptime", "r"))) { exit(1); } - savelocale = setlocale(LC_NUMERIC,"C"); - if (fscanf(file, "%2047s", buf) == EOF) perror("uptime"); + savelocale = setlocale(LC_NUMERIC, "C"); + if (fscanf(file, "%2047s", buf) == EOF) + perror("uptime"); fclose(file); - setlocale(LC_NUMERIC,savelocale); + setlocale(LC_NUMERIC, savelocale); return atof(buf); } -/* process age from jiffies to seconds via uptime */ static double process_age(const unsigned long long jf) { double age; @@ -29,18 +38,6 @@ static double process_age(const unsigned long long jf) return age; } -typedef struct NAMEINFO { - const char *name; - int name_length; - struct stat st; -} NAMEINFO; - -static pid_t opt_ns_pid = 0; -static int verbose = 0, exact = 0, interactive = 0, reg = 0, - quiet = 0, wait_until_dead = 0, process_group = 0, - ignore_case = 0; -static long younger_than = 0, older_than = 0; - enum ns_type { IPCNS = 0, MNTNS, @@ -59,131 +56,15 @@ static const char *ns_names[] = { [UTSNS] = "uts", }; -static int -load_proc_cmdline(const pid_t pid, const char *comm, char **command, int *got_long) +const char *get_ns_name(int id) { - FILE *file; - char *path, *p, *command_buf; - int cmd_size = 128; - int okay; - - if (asprintf (&path, PROC_BASE "/%d/cmdline", pid) < 0) - return -1; - if (!(file = fopen (path, "r"))) - { - free (path); - return -1; - } - free(path); - - if ( (command_buf = (char *)malloc (cmd_size)) == NULL) - exit(1); - - while (1) - { - /* look for actual command so we skip over initial "sh" if any */ - - /* 'cmdline' has arguments separated by nulls */ - for (p=command_buf; ; p++) - { - int c; - if (p == (command_buf + cmd_size)) - { - char *new_command_buf; - int cur_size = cmd_size; - cmd_size *= 2; - new_command_buf = (char *)realloc(command_buf, cmd_size); - if (!new_command_buf) { - if (command_buf) - free(command_buf); - exit (1); - } - command_buf = new_command_buf; - p = command_buf + cur_size; - } - c = fgetc(file); - if (c == EOF || c == '\0') - { - *p = '\0'; - break; - } else { - *p = c; - } - } - if (strlen(command_buf) == 0) { - okay = 0; - break; - } - p = strrchr(command_buf,'/'); - p = p ? p+1 : command_buf; - if (strncmp(p, comm, COMM_LEN-1) == 0) { - okay = 1; - if (!(*command = strdup(p))) { - free(command_buf); - exit(1); - } - break; - } - } - (void) fclose(file); - free(command_buf); - command_buf = NULL; - - if (exact && !okay) - { - if (verbose) - fprintf (stderr, _("killall: skipping partial match %s(%d)\n"), - comm, pid); - *got_long = okay; - return -1; - } - *got_long = okay; - return 0; -} - -static int -ask (char *name, pid_t pid, const int signal) -{ - int res; - size_t len; - char *line; - - line = NULL; - len = 0; - - do { - if (signal == SIGTERM) - printf (_("Kill %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "", - pid); - else - printf (_("Signal %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "", - pid); - - fflush (stdout); - - if (getline (&line, &len, stdin) < 0) - return 0; - /* Check for default */ - if (line[0] == '\n') { - free(line); - return 0; - } - res = rpmatch(line); - if (res >= 0) { - free(line); - return res; - } - } while(1); - /* Never should get here */ -} - -const char *get_ns_name(int id) { - if (id >= NUM_NS) + if (id >= 6) return NULL; return ns_names[id]; } -static int get_ns(pid_t pid, int id) { +static int get_ns(pid_t pid, int id) +{ struct stat st; char buff[50]; snprintf(buff, sizeof(buff), "/proc/%i/ns/%s", pid, get_ns_name(id)); @@ -193,9 +74,31 @@ static int get_ns(pid_t pid, int id) { return st.st_ino; } +static int match_process_uid(pid_t pid, uid_t uid) +{ + char buf[128]; + uid_t puid; + FILE *f; + int re = -1; -static void -free_regexp_list(regex_t *reglist, int names) + snprintf(buf, sizeof buf, PROC_BASE "/%d/status", pid); + if (!(f = fopen(buf, "r"))) + return 0; + + while (fgets(buf, sizeof buf, f)) { + if (sscanf(buf, "Uid:\t%d", &puid)) { + re = uid == puid; + break; + } + } + fclose(f); + if (re == -1) { + exit(1); + } + return re; +} + +static void free_regexp_list(regex_t * reglist, int names) { int i; for (i = 0; i < names; i++) @@ -203,53 +106,43 @@ free_regexp_list(regex_t *reglist, int names) free(reglist); } -static regex_t * -build_regexp_list(int names, char **namelist) +static regex_t *build_regexp_list(int names, char **namelist) { int i; regex_t *reglist; - int flag = REG_EXTENDED|REG_NOSUB; + int flag = REG_EXTENDED | REG_NOSUB; - if (!(reglist = malloc (sizeof (regex_t) * names))) - { - perror ("malloc"); - exit (1); + if (!(reglist = malloc(sizeof(regex_t) * names))) { + perror("malloc"); + exit(1); } if (ignore_case) flag |= REG_ICASE; - for (i = 0; i < names; i++) - { - if (regcomp(®list[i], namelist[i], flag) != 0) - { - fprintf(stderr, _("killall: Bad regular expression: %s\n"), namelist[i]); + for (i = 0; i < names; i++) { + if (regcomp(®list[i], namelist[i], flag) != 0) { free_regexp_list(reglist, i); - exit (1); + exit(1); } } return reglist; } -static NAMEINFO * -build_nameinfo(const int names, char **namelist) +static NAMEINFO *build_nameinfo(const int names, char **namelist) { int i; NAMEINFO *ni = NULL; - if ( (ni = malloc(sizeof(NAMEINFO) * names)) == NULL) + if ((ni = malloc(sizeof(NAMEINFO) * names)) == NULL) return NULL; - for (i = 0; i < names; i++) - { + for (i = 0; i < names; i++) { ni[i].name = namelist[i]; ni[i].st.st_dev = 0; - if (!strchr (namelist[i], '/')) - { - ni[i].name_length = strlen (namelist[i]); - } - else if (stat (namelist[i], &(ni[i].st)) < 0) - { - perror (namelist[i]); + if (!strchr(namelist[i], '/')) { + ni[i].name_length = strlen(namelist[i]); + } else if (stat(namelist[i], &(ni[i].st)) < 0) { + perror(namelist[i]); free(ni); return NULL; } @@ -257,76 +150,6 @@ build_nameinfo(const int names, char **namelist) return ni; } -static pid_t * -create_pid_table(int *max_pids, int *pids) -{ - pid_t self, *pid_table; - int pid; - DIR *dir; - struct dirent *de; - - self = getpid (); - if (!(dir = opendir (PROC_BASE))) - { - perror (PROC_BASE); - exit (1); - } - *max_pids = 256; - pid_table = malloc (*max_pids * sizeof (pid_t)); - if (!pid_table) - { - perror ("malloc"); - exit (1); - } - *pids = 0; - while ( (de = readdir (dir)) != NULL) - { - if (!(pid = (pid_t) atoi (de->d_name)) || pid == self) - continue; - if (*pids == *max_pids) - { - if (!(pid_table = realloc (pid_table, 2 * *pids * sizeof (pid_t)))) - { - perror ("realloc"); - exit (1); - } - *max_pids *= 2; - } - pid_table[(*pids)++] = pid; - } - (void) closedir (dir); - return pid_table; -} - -static int -match_process_uid(pid_t pid, uid_t uid) -{ - char buf[128]; - uid_t puid; - FILE *f; - int re = -1; - - snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid); - if (!(f = fopen (buf, "r"))) - return 0; - - while (fgets(buf, sizeof buf, f)) - { - if (sscanf (buf, "Uid:\t%d", &puid)) - { - re = uid==puid; - break; - } - } - fclose(f); - if (re==-1) - { - fprintf(stderr, _("killall: Cannot get UID from process status\n")); - exit(1); - } - return re; -} - static int load_process_name_and_age(char *comm, double *process_age_sec, const pid_t pid, int load_age) @@ -338,16 +161,14 @@ load_process_name_and_age(char *comm, double *process_age_sec, unsigned lencomm; *process_age_sec = 0; - if (asprintf (&path, PROC_BASE "/%d/stat", pid) < 0) + if (asprintf(&path, PROC_BASE "/%d/stat", pid) < 0) return -1; - if (!(file = fopen (path, "r"))) - { + if (!(file = fopen(path, "r"))) { free(path); return -1; } - free (path); - if (fgets(buf, 1024, file) == NULL) - { + free(path); + if (fgets(buf, 1024, file) == NULL) { fclose(file); return -1; } @@ -357,18 +178,18 @@ load_process_name_and_age(char *comm, double *process_age_sec, lencomm = endcomm - startcomm; if (lencomm < 0) lencomm = 0; - if (lencomm > COMM_LEN -1) - lencomm = COMM_LEN -1; + if (lencomm > COMM_LEN - 1) + lencomm = COMM_LEN - 1; strncpy(comm, startcomm, lencomm); comm[lencomm] = '\0'; - endcomm += 2; // skip ") " - if (load_age) - { + endcomm += 2; // skip ") " + if (load_age) { unsigned long long proc_stt_jf = 0; - if (sscanf(endcomm, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", - &proc_stt_jf) != 1) - { + if (sscanf + (endcomm, + "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", + &proc_stt_jf) != 1) { return -1; } *process_age_sec = process_age(proc_stt_jf); @@ -376,14 +197,147 @@ load_process_name_and_age(char *comm, double *process_age_sec, return lencomm; } -#ifdef WITH_SELINUX +static int +load_proc_cmdline(const pid_t pid, const char *comm, char **command, + int *got_long) +{ + FILE *file; + char *path, *p, *command_buf; + int cmd_size = 128; + int okay; + + if (asprintf(&path, PROC_BASE "/%d/cmdline", pid) < 0) + return -1; + if (!(file = fopen(path, "r"))) { + free(path); + return -1; + } + free(path); + + if ((command_buf = (char *)malloc(cmd_size)) == NULL) + exit(1); + + while (1) { + for (p = command_buf;; p++) { + int c; + if (p == (command_buf + cmd_size)) { + char *new_command_buf; + int cur_size = cmd_size; + cmd_size *= 2; + new_command_buf = (char *)realloc(command_buf, cmd_size); + if (!new_command_buf) { + if (command_buf) + free(command_buf); + exit(1); + } + command_buf = new_command_buf; + p = command_buf + cur_size; + } + c = fgetc(file); + if (c == EOF || c == '\0') { + *p = '\0'; + break; + } else { + *p = c; + } + } + if (strlen(command_buf) == 0) { + okay = 0; + break; + } + p = strrchr(command_buf, '/'); + p = p ? p + 1 : command_buf; + if (strncmp(p, comm, COMM_LEN - 1) == 0) { + okay = 1; + if (!(*command = strdup(p))) { + free(command_buf); + exit(1); + } + break; + } + } + (void)fclose(file); + free(command_buf); + command_buf = NULL; + + if (exact && !okay) { + *got_long = okay; + return -1; + } + *got_long = okay; + return 0; +} + +static pid_t *create_pid_table(int *max_pids, int *pids) +{ + pid_t self, *pid_table; + int pid; + DIR *dir; + struct dirent *de; + + self = getpid(); + if (!(dir = opendir(PROC_BASE))) { + perror(PROC_BASE); + exit(1); + } + *max_pids = 256; + pid_table = malloc(*max_pids * sizeof(pid_t)); + if (!pid_table) { + perror("malloc"); + exit(1); + } + *pids = 0; + while ((de = readdir(dir)) != NULL) { + if (!(pid = (pid_t) atoi(de->d_name)) || pid == self) + continue; + if (*pids == *max_pids) { + if (!(pid_table = realloc(pid_table, 2 * *pids * sizeof(pid_t)))) { + perror("realloc"); + exit(1); + } + *max_pids *= 2; + } + pid_table[(*pids)++] = pid; + } + (void)closedir(dir); + return pid_table; +} + +#define strcmp2(A,B,I) (I? strcasecmp((A),(B)):strcmp((A),(B))) +#define strncmp2(A,B,L,I) (I? strncasecmp((A),(B),(L)):strncmp((A),(B),(L))) +static int match_process_name(const char *proc_comm, + const int comm_len, + const char *proc_cmdline, + const char *match_name, + const int match_len, const int got_long) +{ + if (comm_len == OLD_COMM_LEN - 1 && match_len >= OLD_COMM_LEN - 1) { + if (got_long) { + return (0 == strncmp2(match_name, proc_cmdline, OLD_COMM_LEN - 1, + ignore_case)); + } else { + return (0 == strncmp2(match_name, proc_comm, OLD_COMM_LEN - 1, + ignore_case)); + } + } + + if (comm_len == COMM_LEN - 1 && match_len >= COMM_LEN - 1) { + if (got_long) { + return (0 == strncmp2(match_name, proc_cmdline, COMM_LEN - 1, + ignore_case)); + } else { + return (0 == strncmp2(match_name, proc_comm, COMM_LEN - 1, + ignore_case)); + } + } + if (got_long) { + return (0 == strcmp2(match_name, proc_cmdline, ignore_case)); + } + return (0 == strcmp2(match_name, proc_comm, ignore_case)); +} + int -kill_all(int signal, int name_count, char **namelist, struct passwd *pwent, - regex_t *scontext ) -#else /*WITH_SELINUX*/ -int -kill_all (int signal, int name_count, char **namelist, struct passwd *pwent) -#endif /*WITH_SELINUX*/ +kill_all(int signal, int name_count, char **namelist, struct passwd *pwent) { struct stat st; NAMEINFO *name_info = NULL; @@ -396,70 +350,47 @@ kill_all (int signal, int name_count, char **namelist, struct passwd *pwent) unsigned long found; regex_t *reglist = NULL; long ns_ino = 0; -#ifdef WITH_SELINUX - security_context_t lcontext=NULL; -#endif /*WITH_SELINUX*/ if (opt_ns_pid) ns_ino = get_ns(opt_ns_pid, PIDNS); if (name_count && reg) reglist = build_regexp_list(name_count, namelist); - else - if ( (name_info = build_nameinfo(name_count, namelist)) == NULL) - exit(1); + else if ((name_info = build_nameinfo(name_count, namelist)) == NULL) + exit(1); pid_table = create_pid_table(&max_pids, &pids); found = 0; pids_killed = 0; - pid_killed = malloc (max_pids * sizeof (pid_t)); - if (!pid_killed) - { - perror ("malloc"); - exit (1); + pid_killed = malloc(max_pids * sizeof(pid_t)); + if (!pid_killed) { + perror("malloc"); + exit(1); } - if (process_group) - { - pgids = calloc (pids, sizeof (pid_t)); - if (!pgids) - { - perror ("malloc"); - exit (1); + if (process_group) { + pgids = calloc(pids, sizeof(pid_t)); + if (!pgids) { + perror("malloc"); + exit(1); } } got_long = 0; - for (i = 0; i < pids; i++) - { + for (i = 0; i < pids; i++) { pid_t id; int found_name = -1; double process_age_sec = 0; - /* match by UID */ - if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0) + if (pwent && match_process_uid(pid_table[i], pwent->pw_uid) == 0) continue; if (opt_ns_pid && ns_ino && ns_ino != get_ns(pid_table[i], PIDNS)) continue; - -#ifdef WITH_SELINUX - /* match by SELinux context */ - if (scontext) - { - if (getpidcon(pid_table[i], &lcontext) < 0) - continue; - if (regexec(scontext, lcontext, 0, NULL, 0) != 0) { - freecon(lcontext); - continue; - } - freecon(lcontext); - } -#endif /*WITH_SELINUX*/ - length = load_process_name_and_age(comm, &process_age_sec, pid_table[i], (younger_than||older_than)); + length = + load_process_name_and_age(comm, &process_age_sec, pid_table[i], + (younger_than || older_than)); if (length < 0) continue; - - /* test for process age, if required */ - if ( younger_than && (process_age_sec > younger_than ) ) + if (younger_than && (process_age_sec > younger_than)) continue; - if ( older_than && (process_age_sec < older_than ) ) + if (older_than && (process_age_sec < older_than)) continue; got_long = 0; @@ -470,148 +401,89 @@ kill_all (int signal, int name_count, char **namelist, struct passwd *pwent) if (length == COMM_LEN - 1) if (load_proc_cmdline(pid_table[i], comm, &command, &got_long) < 0) continue; + for (j = 0; j < name_count; j++) { + if (reg) { + if (regexec(®list[j], got_long ? command : comm, 0, NULL, 0) + != 0) + continue; + } else { + if (!name_info[j].st.st_dev) { + if (!match_process_name(comm, length, command, namelist[j], + name_info[j].name_length, got_long)) + continue; - /* match by process name */ - for (j = 0; j < name_count; j++) - { - if (reg) - { - if (regexec (®list[j], got_long ? command : comm, 0, NULL, 0) != 0) + } else { + int ok = 1; + if (asprintf(&path, PROC_BASE "/%d/exe", pid_table[i]) < 0) + continue; + if (stat(path, &st) < 0) + ok = 0; + else if (name_info[j].st.st_dev != st.st_dev || + name_info[j].st.st_ino != st.st_ino) { + size_t len = strlen(namelist[j]); + char *linkbuf = malloc(len + 1); + + if (!linkbuf || + readlink(path, linkbuf, len + 1) != (ssize_t) len || + memcmp(namelist[j], linkbuf, len)) + ok = 0; + free(linkbuf); + } + free(path); + if (!ok) continue; } - else /* non-regex */ - { - if (!name_info[j].st.st_dev) - { - if (length != COMM_LEN - 1 || name_info[j].name_length < COMM_LEN - 1) - { - if (ignore_case == 1) - { - if (strcasecmp (namelist[j], comm)) - continue; - } else { - if (strcmp(namelist[j], comm)) - continue; - } - } else { - if (ignore_case == 1) - { - if (got_long ? strcasecmp (namelist[j], command) : - strncasecmp (namelist[j], comm, COMM_LEN - 1)) - continue; - } else { - if (got_long ? strcmp (namelist[j], command) : - strncmp (namelist[j], comm, COMM_LEN - 1)) - continue; - } - } - } else { - int ok = 1; - if (asprintf (&path, PROC_BASE "/%d/exe", pid_table[i]) < 0) - continue; - if (stat (path, &st) < 0) - ok = 0; - else if (name_info[j].st.st_dev != st.st_dev || - name_info[j].st.st_ino != st.st_ino) - { - /* maybe the binary has been modified and std[j].st_ino - * is not reliable anymore. We need to compare paths. - */ - size_t len = strlen(namelist[j]); - char *linkbuf = malloc(len + 1); - - if (!linkbuf || - readlink(path, linkbuf, len + 1) != (ssize_t)len || - memcmp(namelist[j], linkbuf, len)) - ok = 0; - free(linkbuf); - } - free(path); - if (!ok) - continue; - } - } /* non-regex */ + } found_name = j; break; - } - if (name_count && found_name==-1) - continue; /* match by process name faild */ - - /* check for process group */ + } + if (name_count && found_name == -1) + continue; if (!process_group) id = pid_table[i]; - else - { + else { int j; - id = getpgid (pid_table[i]); + id = getpgid(pid_table[i]); pgids[i] = id; - if (id < 0) - { - fprintf (stderr, "killall: getpgid(%d): %s\n", - pid_table[i], strerror (errno)); - } for (j = 0; j < i; j++) if (pgids[j] == id) break; if (j < i) continue; - } - if (interactive && !ask (comm, id, signal)) - continue; - if (kill (process_group ? -id : id, signal) >= 0) - { - if (verbose) - fprintf (stderr, _("Killed %s(%s%d) with signal %d\n"), got_long ? command : - comm, process_group ? "pgid " : "", id, signal); + } + + if (kill(process_group ? -id : id, signal) >= 0) { if (found_name >= 0) - /* mark item of namelist */ found |= 1UL << found_name; pid_killed[pids_killed++] = id; } - else if (errno != ESRCH || interactive) - fprintf (stderr, "%s(%d): %s\n", got_long ? command : - comm, id, strerror (errno)); } if (command) free(command); if (reglist) free_regexp_list(reglist, name_count); free(pgids); - if (!quiet) - for (i = 0; i < name_count; i++) - if (!(found & (1UL << i))) - fprintf (stderr, _("%s: no process found\n"), namelist[i]); if (name_count) - /* killall returns a zero return code if at least one process has - * been killed for each listed command. */ - error = found == ((1UL << (name_count - 1)) | ((1UL << (name_count - 1)) - 1)) ? 0 : 1; + error = + found == + ((1UL << (name_count - 1)) | ((1UL << (name_count - 1)) - 1)) ? 0 : + 1; else - /* in nameless mode killall returns a zero return code if at least - * one process has killed */ error = pids_killed ? 0 : 1; - /* - * We scan all (supposedly) killed processes every second to detect dead - * processes as soon as possible in order to limit problems of race with - * PID re-use. - */ - while (pids_killed && wait_until_dead) - { - for (i = 0; i < pids_killed;) - { - if (kill (process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 && - errno == ESRCH) - { + while (pids_killed && wait_until_dead) { + for (i = 0; i < pids_killed;) { + if (kill(process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 && + errno == ESRCH) { pid_killed[i] = pid_killed[--pids_killed]; continue; } i++; } - sleep (1); /* wait a bit longer */ + //sleep(1); } free(pid_killed); free(pid_table); free(name_info); return error; } - diff --git a/kill.h b/kill.h index 14200de..8feeb0f 100644 --- a/kill.h +++ b/kill.h @@ -1,9 +1,12 @@ #ifndef KILL_H #define KILL_H + + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif + #include #include #include @@ -19,38 +22,41 @@ #include #include #include -#include #include -#ifndef I18N_H -#define I18N_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef ENABLE_NLS -#include -#include -#define _(String) gettext (String) -#else +#define COMM_LEN 64 +#define OLD_COMM_LEN 16 #define _(String) (String) -#endif - -#endif - -#ifndef HAVE_RPMATCH #define rpmatch(line) \ ( (line == NULL)? -1 : \ (*line == 'y' || *line == 'Y')? 1 : \ (*line == 'n' || *line == 'N')? 0 : \ -1 ) -#endif -#define COMM_LEN 64 #define PROC_BASE "/proc" -#define NUM_NS 6 +#define MAX_NAMES (int)(sizeof(unsigned long)*8) -int kill_all (int signal, int name_count, char **namelist, struct passwd *pwent); +#define TSECOND "s" +#define TMINUTE "m" +#define THOUR "h" +#define TDAY "d" +#define TWEEK "w" +#define TMONTH "M" +#define TYEAR "y" + +#define TMAX_SECOND 31536000 +#define TMAX_MINUTE 525600 +#define TMAX_HOUR 8760 +#define TMAX_DAY 365 +#define TMAX_WEEK 48 +#define TMAX_MONTH 12 +#define TMAX_YEAR 1 + +#define ER_REGFAIL -1 +#define ER_NOMEM -2 +#define ER_UNKWN -3 +#define ER_OOFRA -4 + +int kill_all(int signal, int name_count, char **namelist, struct passwd *pwent); #endif diff --git a/log/cproxy.pid b/log/cproxy.pid deleted file mode 100644 index f578672..0000000 --- a/log/cproxy.pid +++ /dev/null @@ -1 +0,0 @@ -24157 \ No newline at end of file