Fawkes API  Fawkes Development Version
string.cpp
1 
2 /***************************************************************************
3  * string.cpp - string utilities
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 <list>
26 #include <tuple>
27 #include <string>
28 #include <cstring>
29 
30 namespace fawkes {
31 #if 0 /* just to make Emacs auto-indent happy */
32 }
33 #endif
34 
35 
36 /** Convert command args to string.
37  * @param argv arguments, assumed to be standard args as passed to programs,
38  * i.e. the first element is the executable, the following are the parameters.
39  * @return string, where all elements of argv have been concatenated
40  */
41 std::string
42 command_args_tostring(const char *argv[])
43 {
44  std::string command = "";
45  for (int i = 0; argv[i]; ++i) {
46  if (i > 0) command += " ";
47  command += argv[i];
48  }
49  return command;
50 }
51 
52 
53 /** Convert environment to string.
54  * This simply creates a string with semi-colon separated environment elements.
55  * This is mostly useful for debug output of the environment.
56  * @param envp environment string array
57  * @return string with printable environment
58  */
59 std::string
60 envp_tostring(char *envp[])
61 {
62  std::string environment = "";
63  for (int i = 0; envp[i]; ++i) {
64  if (i > 0) environment += "; ";
65  environment += envp[i];
66  }
67  return environment;
68 }
69 
70 
71 /** Copy an environment and extend certain paths.
72  * This will create a vector which comprises the environment in @p environ.
73  * The path_ext are assumed to be pairwise entries of environment variable
74  * name followed by an entry for the path extensions. Paths are here
75  * colon-separated strings of paths, e.g. like the PATH environment variable.
76  * If the variable had already been set, the given paths are appended to
77  * the variable (a closing colon will be maintained if it exists). If they
78  * were not set before, the entry is added.
79  * @param environ environment to copy
80  * @param path_ext path extension, an array of an odd number of elements,
81  * always pairwise an entry for the variable name followed by the path extension.
82  * The last element must always be NULL.
83  * @return vector of strings with copied and extended environment
84  */
85 std::vector<std::string>
86 envp_copy_expand(char *environ[], const char *path_ext[])
87 {
88  std::list<std::tuple<std::string, std::string, bool>> path_ext_m;
89  for (size_t i = 0; path_ext[i] && path_ext[i+1]; i += 2) {
90  std::string match = std::string(path_ext[i]) + "=";
91  path_ext_m.push_back(std::make_tuple(match, std::string(path_ext[i+1]), false));
92  }
93 
94  unsigned int extra_ent = 0;
95 
96  size_t environ_length = 0;
97  for (size_t i = 0; environ[i]; ++i) {
98  ++environ_length;
99  std::string ev = environ[i];
100  for (auto &m : path_ext_m) {
101  if (ev.find(std::get<0>(m)) == 0) {
102  std::get<2>(m) = true;
103  ++extra_ent;
104  break;
105  }
106  }
107  }
108 
109  size_t envp_length = environ_length + extra_ent;
110  std::vector<std::string> envp(envp_length);
111  for (size_t i = 0; environ[i]; ++i) {
112  std::string ev(environ[i]);
113  for (auto m : path_ext_m) {
114  if (ev.find(std::get<0>(m)) == 0) {
115  // modify
116  if (ev[ev.length()-1] == ':') {
117  ev += std::get<1>(m) + ":";
118  } else {
119  ev += ":" + std::get<1>(m);
120  }
121  }
122  }
123  envp[i] = ev;
124  }
125 
126  unsigned int extra_ind = 0;
127  for (auto m : path_ext_m) {
128  if (! std::get<2>(m)) {
129  std::string ev = std::get<0>(m) + std::get<1>(m) + ":";
130  envp[envp_length - extra_ent + extra_ind++] = ev;
131  }
132  }
133 
134  return envp;
135 }
136 
137 } // end namespace fawkes
138 
139 
Fawkes library namespace.
std::string command_args_tostring(const char *argv[])
Convert command args to string.
Definition: string.cpp:42
std::string envp_tostring(char *envp[])
Convert environment to string.
Definition: string.cpp:60
std::vector< std::string > envp_copy_expand(char *environ[], const char *path_ext[])
Copy an environment and extend certain paths.
Definition: string.cpp:86