/* Environment test program for GNU Pies. Copyright (C) 2019 Sergey Poznyakoff GNU Pies is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Pies is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Pies. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include static int envcmp (void const *a, void const *b) { char const *as = *(char const **)a; char const *bs = *(char const **)b; int c; while (*as && *bs) { c = *as - *bs; if (c || *as == '=' || *bs == '=') break; as++; bs++; } return c; } static void sortenv (char **env) { size_t n; for (n = 0; env[n]; n++) ; qsort (env, n, sizeof (env[0]), envcmp); } static void printenv (char **env) { size_t i; for (i = 0; env[i]; i++) { char *p = env[i]; while (*p) { fputc (*p, stdout); if (*p++ == '=') break; } if (*p) { int c; fputc ('"', stdout); while ((c = *p++) != 0) { int c1; if (isascii (c) && isprint (c) && c != '\\' && c != '"') fputc (c, stdout); else if ((c1 = wordsplit_c_quote_char (c))) { fputc ('\\', stdout); fputc (c1, stdout); } } fputc ('"', stdout); } fputc ('\n', stdout); } } char *defenv[] = { "PATH=/usr/local/bin:/usr/bin:/bin", "HOME=/home/user", "USER=user", "LOGIN=user", "PWD=/home", "LC_ALL=C", "LC_CTYPE=C", "LC_MESSAGES=C", "LC_NUMERIC=C", NULL }; extern char **environ; int main (int argc, char **argv) { envop_t *envop = NULL; int opcode = envop_set; environ_t *env = NULL; if (argc > 1) { if (strcmp (argv[1], "-clone") == 0) { env = environ_create (environ); argc--; argv++; } else if (strcmp (argv[1], "-null") == 0) { env = environ_create (NULL); argc--; argv++; } } if (!env) env = environ_create (defenv); if (!env) { perror ("environ_create"); abort (); } while (--argc) { char *a = *++argv; if (strcmp (a, "-set") == 0) opcode = envop_set; else if (strcmp (a, "-unset") == 0) opcode = envop_unset; else if (strcmp (a, "-keep") == 0) opcode = envop_keep; else if (strcmp (a, "-clear") == 0) { int rc = envop_entry_add (&envop, envop_clear, NULL, NULL); if (rc) { perror ("envop_entry_add"); return 1; } } else if (strcmp (a, "-exec") == 0) { --argc; ++argv; if (argc == 0) { fprintf (stderr, "program name required after -exec\n"); return 1; } break; } else if (a[0] == '-') { fprintf (stderr, "unrecognized option: %s\n", a); return 1; } else { int rc; char *p = strchr (a, '='); if (p) *p++ = 0; rc = envop_entry_add (&envop, opcode, a, p); if (rc) { perror ("envop_entry_add"); return 1; } } } if (envop_exec (envop, env)) { perror ("envop_exec"); return 1; } if (argc) { environ = environ_ptr (env); execvp (argv[0], argv); perror ("execvp"); abort (); } sortenv (env->env_base); printenv (env->env_base); return 0; }