Group :: System/Servers
RPM: 3proxy
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: 3proxy-0.5.3k-alt4.patch
Download
Download
src/3proxy.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++------
src/stringtable.c | 2 +-
2 files changed, 154 insertions(+), 19 deletions(-)
diff --git a/src/3proxy.c b/src/3proxy.c
index e3d0140..fc8f13d 100644
--- a/src/3proxy.c
+++ b/src/3proxy.c
@@ -13,6 +13,18 @@
#define DEFAULTCONFIG stringtable[20]
#endif
+// getopt
+#ifndef _WIN32
+#include <unistd.h>
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#endif
+
typedef int (*MAINFUNC)(int, char**);
pthread_mutex_t bandlim_mutex;
@@ -73,6 +85,54 @@ char *chrootp = NULL;
#endif
char * curconf = NULL;
+// parse options
+#ifndef __WIN32
+static int opt_daemon;
+static char *opt_user = NULL;
+static char *opt_group = NULL;
+static char *opt_conffile = NULL;
+static char *opt_pidfile = NULL;
+
+static int parse_cmdline(int argc, char **argv[])
+ {
+ int opt = 0;
+ while(1)
+ {
+ opt = getopt(argc, argv, "du:g:c:p:");
+ switch(opt)
+ {
+ case 'd': // daemonize
+ opt_daemon = 1;
+ break;
+
+ case 'u': // username
+ opt_user = strdup(optarg);
+ break;
+
+ case 'g': // groupname
+ opt_group = strdup(optarg);
+ break;
+
+ case 'c': // config file
+ opt_conffile = strdup(optarg);
+ break;
+
+ case 'p': // pidfile
+ opt_pidfile = strdup(optarg);
+ break;
+
+ case ':': // option value not found
+ case '?': // option or value not found
+ return -1;
+
+ }
+
+ if(opt == -1)
+ return 0;
+ }
+ }
+#endif
+
FILE * confopen(){
curconf = conffile;
#ifndef _WIN32
@@ -288,6 +348,8 @@ void mysigterm (int sig){
pthread_mutex_unlock(&odbc_mutex);
#endif
timetoexit = 1;
+ if(opt_pidfile)
+ unlink(opt_pidfile);
}
#endif
@@ -799,9 +861,8 @@ int readconfig(FILE * fp){
#endif
continue;
}
- else if(!strcmp((char *)ch->argv[0], "daemon") && ch->argc == 1) {
- if(!demon)daemonize();
- demon = 1;
+ else if(!strcmp((char *)ch->argv[0], "daemon") && ch->argc == 1) {
+ opt_daemon = 1;
continue;
}
else if(!strcmp((char *)ch->argv[0], "writable") && ch->argc == 1) {
@@ -1466,20 +1527,14 @@ int readconfig(FILE * fp){
continue;
}
#ifndef _WIN32
- else if(!strcmp((char *)ch->argv[0], "setuid") && ch->argc == 2) {
- res = atoi((char *)ch->argv[1]);
- if(!res || setuid(res)) {
- fprintf(stderr, "Unable to set uid %d", res);
- return(30);
- }
+ else if(!strcmp((char *)ch->argv[0], "setuid") && ch->argc == 2) {
+ if(opt_user) free(opt_user);
+ opt_user = strdup((char *)ch->argv[1]);
continue;
}
- else if(!strcmp((char *)ch->argv[0], "setgid") && ch->argc == 2) {
- res = atoi((char *)ch->argv[1]);
- if(!res || setgid(res)) {
- fprintf(stderr, "Unable to set gid %d", res);
- return(31);
- }
+ else if(!strcmp((char *)ch->argv[0], "setgid") && ch->argc == 2) {
+ if(opt_group) free(opt_group);
+ opt_group = strdup((char *)ch->argv[1]);
continue;
}
else if(!strcmp((char *)ch->argv[0], "chroot") && ch->argc == 2) {
@@ -1639,25 +1694,104 @@ int main(int argc, char * argv[]) {
}
RETURN(0);
}
-#endif
conffile = mystrdup((argc==2)?argv[1]:(char*)DEFAULTCONFIG);
+#else
+ // parse options
+ if(parse_cmdline(argc, argv))
+ {
+ fprintf(stderr, "parse option failed\n");
+ return 1;
+ }
+ conffile = mystrdup(opt_conffile ? opt_conffile : (char *)DEFAULTCONFIG);
+#endif
if(conffile && *conffile != '-') {
fp = confopen();
#ifndef _WIN32
if(!fp) fp = stdin;
#endif
}
+#ifdef _WIN32
if(argc > 2 || !(fp)) {
fprintf(stderr, "Usage: %s [conffile]\n", argv[0]);
-#ifdef _WIN32
fprintf(stderr, "\n\t%s --install\n\tto install as service\n"
"\n\t%s --remove\n\tto remove service\n", argv[0], argv[0]);
-#endif
fprintf(stderr, "\n%s", copyright);
return 1;
}
+#endif
+
+#ifndef _WIN32
+// handle options
+ uid_t uid = 0;
+ gid_t gid = 0;
+ if(opt_user)
+ {
+ struct passwd *p;
+
+ if(isdigit(opt_user[0]))
+ {
+ uid = atoi(opt_user);
+ p = getpwuid(uid);
+ }
+ else
+ p = getpwnam(opt_user);
+ if(!p)
+ {
+ fprintf(stderr, "user %s not found\n", opt_user);
+ return 1;
+ }
+ uid = p->pw_uid;
+ gid = p->pw_gid;
+ }
+
+ if(opt_group)
+ {
+ struct group *p;
+ if(isdigit(opt_group[0]))
+ {
+ gid = atoi(opt_group);
+ p = getgrgid(gid);
+ }
+ else
+ p = getgrnam(opt_group);
+ if(!p)
+ {
+ fprintf(stderr, "group %s not found\n", opt_group);
+ return 1;
+ }
+ gid = p->gr_gid;
+ }
+
+ if(gid && setgid(gid))
+ {
+ fprintf(stderr, "setgid failed: %s\n", strerror(errno));
+ return 1;
+ }
+
+ if(uid && setuid(uid))
+ {
+ fprintf(stderr, "setuid failed: %s\n", strerror(errno));
+ return 1;
+ }
+
+ if(opt_daemon) daemonize();
+ demon = 1;
+
+ if(opt_pidfile)
+ {
+ FILE *pidfile = fopen(opt_pidfile, "w");
+ if(!pidfile)
+ {
+ fprintf(stderr, "open pidfile: %s\n", strerror(errno));
+ return 1;
+ }
+
+ fprintf(pidfile, "%d\n", getpid());
+ fclose(pidfile);
+ }
+#endif
pthread_mutex_init(&acl_mutex, NULL);
pthread_mutex_init(&bandlim_mutex, NULL);
@@ -1690,6 +1824,7 @@ int main(int argc, char * argv[]) {
#else
signal(SIGCONT, mysigpause);
signal(SIGTERM, mysigterm);
+ signal(SIGINT, mysigterm);
signal(SIGUSR1, mysigusr1);
signal(SIGPIPE, SIG_IGN);
cyclestep();
diff --git a/src/stringtable.c b/src/stringtable.c
index 082a6bd..e4c29d9 100644
--- a/src/stringtable.c
+++ b/src/stringtable.c
@@ -23,7 +23,7 @@ unsigned char * strings[] = {
/* 19 */ NULL,
#ifndef TPROXY_CONF
#ifndef _WIN32
-/* 20 */ (unsigned char *)"/usr/local/etc/3proxy.cfg",
+/* 20 */ (unsigned char *)"/etc/3proxy.conf",
#else
/* 20 */ (unsigned char *)"3proxy.cfg",
#endif