]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/main.c
Merge branch 'master' of https://github.com/gburgessiv/ppp
[ppp.git] / pppd / main.c
index 4e1952b1da6227b83ff3453c4412a5652c095346..76b67d2485b71ce4dc11c6a9cd7ecfd2293f21d9 100644 (file)
 static const char rcsid[] = RCSID;
 
 /* interface vars */
-char ifname[32];               /* Interface name */
+char ifname[MAXIFNAMELEN];     /* Interface name */
 int ifunit;                    /* Interface unit number */
 
 struct channel *the_channel;
@@ -257,7 +257,6 @@ static void cleanup_db __P((void));
 static void handle_events __P((void));
 void print_link_stats __P((void));
 
-extern char    *ttyname __P((int));
 extern char    *getlogin __P((void));
 int main __P((int, char *[]));
 
@@ -298,13 +297,6 @@ struct protent *protocols[] = {
     NULL
 };
 
-/*
- * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name.
- */
-#if !defined(PPP_DRV_NAME)
-#define PPP_DRV_NAME   "ppp"
-#endif /* !defined(PPP_DRV_NAME) */
-
 int
 main(argc, argv)
     int argc;
@@ -737,8 +729,11 @@ void
 set_ifunit(iskey)
     int iskey;
 {
-    info("Using interface %s%d", PPP_DRV_NAME, ifunit);
-    slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+    if (req_ifname[0] != '\0')
+       slprintf(ifname, sizeof(ifname), "%s", req_ifname);
+    else
+       slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
+    info("Using interface %s", ifname);
     script_setenv("IFNAME", ifname, iskey);
     if (iskey) {
        create_pidfile(getpid());       /* write pid to file */
@@ -964,7 +959,7 @@ struct protocol_list {
     { 0x8051,  "KNX Bridging Control Protocol" },
     { 0x8053,  "Encryption Control Protocol" },
     { 0x8055,  "Individual Link Encryption Control Protocol" },
-    { 0x8057,  "IPv6 Control Protovol" },
+    { 0x8057,  "IPv6 Control Protocol" },
     { 0x8059,  "PPP Muxing Control Protocol" },
     { 0x805b,  "Vendor-Specific Network Control Protocol (VSNCP)" },
     { 0x806f,  "Stampede Bridging Control Protocol" },
@@ -1615,6 +1610,52 @@ safe_fork(int infd, int outfd, int errfd)
        return 0;
 }
 
+static bool
+add_script_env(pos, newstring)
+    int pos;
+    char *newstring;
+{
+    if (pos + 1 >= s_env_nalloc) {
+       int new_n = pos + 17;
+       char **newenv = realloc(script_env, new_n * sizeof(char *));
+       if (newenv == NULL) {
+           free(newstring - 1);
+           return 0;
+       }
+       script_env = newenv;
+       s_env_nalloc = new_n;
+    }
+    script_env[pos] = newstring;
+    script_env[pos + 1] = NULL;
+    return 1;
+}
+
+static void
+remove_script_env(pos)
+    int pos;
+{
+    free(script_env[pos] - 1);
+    while ((script_env[pos] = script_env[pos + 1]) != NULL)
+       pos++;
+}
+
+/*
+ * update_system_environment - process the list of set/unset options
+ * and update the system environment.
+ */
+static void
+update_system_environment()
+{
+    struct userenv *uep;
+
+    for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+       if (uep->ue_isset)
+           setenv(uep->ue_name, uep->ue_value, 1);
+       else
+           unsetenv(uep->ue_name);
+    }
+}
+
 /*
  * device_script - run a program to talk to the specified fds
  * (e.g. to run the connector or disconnector script).
@@ -1670,13 +1711,52 @@ device_script(program, in, out, dont_wait)
        fprintf(stderr, "pppd: setuid failed\n");
        exit(1);
     }
+    update_system_environment();
     execl("/bin/sh", "sh", "-c", program, (char *)0);
     perror("pppd: could not exec /bin/sh");
-    exit(99);
+    _exit(99);
     /* NOTREACHED */
 }
 
 
+/*
+ * update_script_environment - process the list of set/unset options
+ * and update the script environment.  Note that we intentionally do
+ * not update the TDB.  These changes are layered on top right before
+ * exec.  It is not possible to use script_setenv() or
+ * script_unsetenv() safely after this routine is run.
+ */
+static void
+update_script_environment()
+{
+    struct userenv *uep;
+
+    for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
+       int i;
+       char *p, *newstring;
+       int nlen = strlen(uep->ue_name);
+
+       for (i = 0; (p = script_env[i]) != NULL; i++) {
+           if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=')
+               break;
+       }
+       if (uep->ue_isset) {
+           nlen += strlen(uep->ue_value) + 2;
+           newstring = malloc(nlen + 1);
+           if (newstring == NULL)
+               continue;
+           *newstring++ = 0;
+           slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value);
+           if (p != NULL)
+               script_env[i] = newstring;
+           else
+               add_script_env(i, newstring);
+       } else {
+           remove_script_env(i);
+       }
+    }
+}
+
 /*
  * run_program - execute a program with given arguments,
  * but don't wait for it unless wait is non-zero.
@@ -1747,6 +1827,7 @@ run_program(prog, args, must_exist, done, arg, wait)
 #endif
 
     /* run the program */
+    update_script_environment();
     execve(prog, args, script_env);
     if (must_exist || errno != ENOENT) {
        /* have to reopen the log, there's nowhere else
@@ -1755,7 +1836,7 @@ run_program(prog, args, must_exist, done, arg, wait)
        syslog(LOG_ERR, "Can't execute %s: %m", prog);
        closelog();
     }
-    _exit(-1);
+    _exit(99);
 }
 
 
@@ -1957,9 +2038,11 @@ script_setenv(var, value, iskey)
                free(p-1);
                script_env[i] = newstring;
 #ifdef USE_TDB
-               if (iskey && pppdb != NULL)
-                   add_db_key(newstring);
-               update_db_entry();
+               if (pppdb != NULL) {
+                   if (iskey)
+                       add_db_key(newstring);
+                   update_db_entry();
+               }
 #endif
                return;
            }
@@ -1967,25 +2050,16 @@ script_setenv(var, value, iskey)
     } else {
        /* no space allocated for script env. ptrs. yet */
        i = 0;
-       script_env = (char **) malloc(16 * sizeof(char *));
-       if (script_env == 0)
+       script_env = malloc(16 * sizeof(char *));
+       if (script_env == 0) {
+           free(newstring - 1);
            return;
+       }
        s_env_nalloc = 16;
     }
 
-    /* reallocate script_env with more space if needed */
-    if (i + 1 >= s_env_nalloc) {
-       int new_n = i + 17;
-       char **newenv = (char **) realloc((void *)script_env,
-                                         new_n * sizeof(char *));
-       if (newenv == 0)
-           return;
-       script_env = newenv;
-       s_env_nalloc = new_n;
-    }
-
-    script_env[i] = newstring;
-    script_env[i+1] = 0;
+    if (!add_script_env(i, newstring))
+       return;
 
 #ifdef USE_TDB
     if (pppdb != NULL) {
@@ -2016,9 +2090,7 @@ script_unsetenv(var)
            if (p[-1] && pppdb != NULL)
                delete_db_key(p);
 #endif
-           free(p-1);
-           while ((script_env[i] = script_env[i+1]) != 0)
-               ++i;
+           remove_script_env(i);
            break;
        }
     }