Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37521672
en ru br
ALT Linux repos
S:0.6.1-alt2
5.0: 0.5.3k-alt4
4.1: 0.5.3k-alt3.M41.1
4.0: 0.5.3k-alt3.M40.1

Group :: System/Servers
RPM: 3proxy

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: 3proxy-0.5.3k-alt4.patch
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
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin