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 
31 namespace 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  */
38 std::string
39 command_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  */
56 std::string
57 envp_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  */
82 std::vector<std::string>
83 envp_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::envp_tostring
std::string envp_tostring(char *envp[])
Convert environment to string.
Definition: string_commands.cpp:63
fawkes
fawkes::envp_copy_expand
std::vector< std::string > envp_copy_expand(char *environ[], const char *path_ext[])
Copy an environment and extend certain paths.
Definition: string_commands.cpp:89
fawkes::command_args_tostring
std::string command_args_tostring(const char *argv[])
Convert command args to string.
Definition: string_commands.cpp:45