Fawkes API Fawkes Development Version
string_commands.cpp
1
2/***************************************************************************
3 * string.cpp - string utilities for command argv and envs
4 *
5 * Created: Fri Aug 22 15:32:47 2014
6 * Copyright 2014 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * Read the full text in the LICENSE.GPL file in the doc directory.
21 */
22
23#include "string.h"
24
25#include <cstring>
26#include <list>
27#include <string>
28#include <tuple>
29#include <vector>
30
31namespace fawkes {
32
33/** Convert command args to string.
34 * @param argv arguments, assumed to be standard args as passed to programs,
35 * i.e. the first element is the executable, the following are the parameters.
36 * @return string, where all elements of argv have been concatenated
37 */
38std::string
39command_args_tostring(const char *argv[])
40{
41 std::string command = "";
42 for (int i = 0; argv[i]; ++i) {
43 if (i > 0)
44 command += " ";
45 command += argv[i];
46 }
47 return command;
48}
49
50/** Convert environment to string.
51 * This simply creates a string with semi-colon separated environment elements.
52 * This is mostly useful for debug output of the environment.
53 * @param envp environment string array
54 * @return string with printable environment
55 */
56std::string
57envp_tostring(char *envp[])
58{
59 std::string environment = "";
60 for (int i = 0; envp[i]; ++i) {
61 if (i > 0)
62 environment += "; ";
63 environment += envp[i];
64 }
65 return environment;
66}
67
68/** Copy an environment and extend certain paths.
69 * This will create a vector which comprises the environment in @p environ.
70 * The path_ext are assumed to be pairwise entries of environment variable
71 * name followed by an entry for the path extensions. Paths are here
72 * colon-separated strings of paths, e.g. like the PATH environment variable.
73 * If the variable had already been set, the given paths are appended to
74 * the variable (a closing colon will be maintained if it exists). If they
75 * were not set before, the entry is added.
76 * @param environ environment to copy
77 * @param path_ext path extension, an array of an odd number of elements,
78 * always pairwise an entry for the variable name followed by the path extension.
79 * The last element must always be NULL.
80 * @return vector of strings with copied and extended environment
81 */
82std::vector<std::string>
83envp_copy_expand(char *environ[], const char *path_ext[])
84{
85 std::list<std::tuple<std::string, std::string, bool>> path_ext_m;
86 for (size_t i = 0; path_ext[i] && path_ext[i + 1]; i += 2) {
87 std::string match = std::string(path_ext[i]) + "=";
88 path_ext_m.push_back(std::make_tuple(match, std::string(path_ext[i + 1]), false));
89 }
90
91 unsigned int extra_ent = 0;
92
93 size_t environ_length = 0;
94 for (size_t i = 0; environ[i]; ++i) {
95 ++environ_length;
96 std::string ev = environ[i];
97 for (auto &m : path_ext_m) {
98 if (ev.find(std::get<0>(m)) == 0) {
99 std::get<2>(m) = true;
100 ++extra_ent;
101 break;
102 }
103 }
104 }
105
106 size_t envp_length = environ_length + extra_ent;
107 std::vector<std::string> envp(envp_length);
108 for (size_t i = 0; environ[i]; ++i) {
109 std::string ev(environ[i]);
110 for (auto m : path_ext_m) {
111 if (ev.find(std::get<0>(m)) == 0) {
112 // modify
113 if (ev[ev.length() - 1] == ':') {
114 ev += std::get<1>(m) + ":";
115 } else {
116 ev += ":" + std::get<1>(m);
117 }
118 }
119 }
120 envp[i] = ev;
121 }
122
123 unsigned int extra_ind = 0;
124 for (auto m : path_ext_m) {
125 if (!std::get<2>(m)) {
126 std::string ev = std::get<0>(m) + std::get<1>(m) + ":";
127 envp[envp_length - extra_ent + extra_ind++] = ev;
128 }
129 }
130
131 return envp;
132}
133
134} // end namespace fawkes
Fawkes library namespace.
std::string command_args_tostring(const char *argv[])
Convert command args to string.
std::string envp_tostring(char *envp[])
Convert environment to string.
std::vector< std::string > envp_copy_expand(char *environ[], const char *path_ext[])
Copy an environment and extend certain paths.