PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/freebsd/usr.sbin/sade/variable.c

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C | 324 lines | 223 code | 36 blank | 65 comment | 64 complexity | 611ff39f21908b68cd538a14f8d43ed7 MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /*
  2. * $FreeBSD$
  3. *
  4. * Copyright (c) 1995
  5. * Jordan Hubbard. All rights reserved.
  6. * Copyright (c) 2001
  7. * Murray Stokely. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer,
  14. * verbatim and that no modifications are made prior to this
  15. * point in the file.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. */
  33. #include "sade.h"
  34. /* Routines for dealing with variable lists */
  35. static void
  36. make_variable(char *var, char *value, int dirty)
  37. {
  38. Variable *vp;
  39. /* Trim leading and trailing whitespace */
  40. var = string_skipwhite(string_prune(var));
  41. if (!var || !*var)
  42. return;
  43. /* Now search to see if it's already in the list */
  44. for (vp = VarHead; vp; vp = vp->next) {
  45. if (!strcmp(vp->name, var)) {
  46. if (vp->dirty && !dirty)
  47. return;
  48. setenv(var, value, 1);
  49. free(vp->value);
  50. vp->value = strdup(value);
  51. if (dirty != -1)
  52. vp->dirty = dirty;
  53. return;
  54. }
  55. }
  56. setenv(var, value, 1);
  57. /* No? Create a new one */
  58. vp = (Variable *)safe_malloc(sizeof(Variable));
  59. vp->name = strdup(var);
  60. vp->value = strdup(value);
  61. if (dirty == -1)
  62. dirty = 0;
  63. vp->dirty = dirty;
  64. vp->next = VarHead;
  65. VarHead = vp;
  66. }
  67. void
  68. variable_set(char *var, int dirty)
  69. {
  70. char tmp[1024], *cp;
  71. if (!var)
  72. msgFatal("NULL variable name & value passed.");
  73. else if (!*var)
  74. msgDebug("Warning: Zero length name & value passed to variable_set()\n");
  75. SAFE_STRCPY(tmp, var);
  76. if ((cp = strchr(tmp, '=')) == NULL)
  77. msgFatal("Invalid variable format: %s", var);
  78. *(cp++) = '\0';
  79. make_variable(tmp, string_skipwhite(cp), dirty);
  80. }
  81. void
  82. variable_set2(char *var, char *value, int dirty)
  83. {
  84. if (!var || !value)
  85. msgFatal("Null name or value passed to set_variable2(%s) = %s!",
  86. var ? var : "", value ? value : "");
  87. else if (!*var || !*value)
  88. msgDebug("Warning: Zero length name or value passed to variable_set2(%s) = %s\n",
  89. var, value);
  90. make_variable(var, value, dirty);
  91. }
  92. char *
  93. variable_get(char *var)
  94. {
  95. return getenv(var);
  96. }
  97. int
  98. variable_cmp(char *var, char *value)
  99. {
  100. char *val;
  101. if ((val = variable_get(var)))
  102. return strcmp(val, value);
  103. return -1;
  104. }
  105. void
  106. variable_unset(char *var)
  107. {
  108. Variable *vp;
  109. char name[512], *cp;
  110. if ((cp = strchr(var, '=')) != NULL)
  111. sstrncpy(name, var, cp - var);
  112. else
  113. SAFE_STRCPY(name, var);
  114. unsetenv(name);
  115. /* Now search to see if it's in our list, if we have one.. */
  116. if (!VarHead)
  117. return;
  118. else if (!VarHead->next && !strcmp(VarHead->name, name)) {
  119. safe_free(VarHead->name);
  120. safe_free(VarHead->value);
  121. free(VarHead);
  122. VarHead = NULL;
  123. }
  124. else {
  125. for (vp = VarHead; vp; vp = vp->next) {
  126. if (!strcmp(vp->name, name)) {
  127. Variable *save = vp->next;
  128. safe_free(vp->name);
  129. safe_free(vp->value);
  130. *vp = *save;
  131. safe_free(save);
  132. break;
  133. }
  134. }
  135. }
  136. }
  137. /* Prompt user for the name of a variable */
  138. char *
  139. variable_get_value(char *var, char *prompt, int dirty)
  140. {
  141. char *cp;
  142. cp = variable_get(var);
  143. if (cp && variable_get(VAR_NONINTERACTIVE))
  144. return cp;
  145. else if ((cp = msgGetInput(cp, "%s", prompt)) != NULL)
  146. variable_set2(var, cp, dirty);
  147. else
  148. cp = NULL;
  149. return cp;
  150. }
  151. /* Check if value passed in data (in the form "variable=value") is
  152. * valid, and it's status compared to the value of variable stored in
  153. * env
  154. *
  155. * Possible return values :
  156. * -3: Invalid line, the data string is NOT set as an env variable
  157. * -2: Invalid line, the data string is set as an env variable
  158. * -1: Invalid line
  159. * 0: Valid line, is NOT equal to env version
  160. * 1: Valid line, is equal to env version
  161. * 2: Valid line, value empty - e.g. foo=""
  162. * 3: Valid line, does not exist in env
  163. */
  164. int
  165. variable_check2(char *data)
  166. {
  167. char *cp, *cp2, *cp3, tmp[256];
  168. if (data == NULL)
  169. return -1;
  170. SAFE_STRCPY(tmp, data);
  171. if ((cp = strchr(tmp, '=')) != NULL) {
  172. *(cp++) = '\0';
  173. if (*cp == '"') { /* smash quotes if present */
  174. ++cp;
  175. if ((cp3 = strchr(cp, '"')) != NULL)
  176. *cp3 = '\0';
  177. }
  178. else if ((cp3 = strchr(cp, ',')) != NULL)
  179. *cp3 = '\0';
  180. cp2 = variable_get(tmp);
  181. if (cp2 != NULL) {
  182. if (*cp == '\0')
  183. return 2;
  184. else
  185. return strcmp(cp, cp2) == 0 ? 1 : 0;
  186. }
  187. else
  188. return 3;
  189. }
  190. else
  191. return variable_get(tmp) != NULL ? -2 : -3;
  192. }
  193. /* Check if the value passed in data (in the form "variable=value") is
  194. equal to the value of variable stored in env */
  195. int
  196. variable_check(char *data)
  197. {
  198. int ret;
  199. ret = variable_check2(data);
  200. switch(ret) {
  201. case -2:
  202. case 1:
  203. case 2:
  204. return TRUE;
  205. /* NOT REACHED */
  206. default:
  207. return FALSE;
  208. }
  209. }
  210. int
  211. dump_variables(dialogMenuItem *unused)
  212. {
  213. FILE *fp;
  214. Variable *vp;
  215. if (isDebug())
  216. msgDebug("Writing %s variables to file..\n", ProgName);
  217. fp = fopen("/etc/sade.vars", "w");
  218. if (!fp) {
  219. msgConfirm("Unable to write to /etc/%s.vars: %s",
  220. ProgName, strerror(errno));
  221. return DITEM_FAILURE;
  222. }
  223. for (vp = VarHead; vp; vp = vp->next)
  224. fprintf(fp, "%s=\"%s\" (%d)\n", vp->name, vp->value, vp->dirty);
  225. fclose(fp);
  226. return DITEM_SUCCESS;
  227. }
  228. /* Free all of the variables, useful to really start over as when the
  229. user selects "restart" from the interrupt menu. */
  230. void
  231. free_variables(void)
  232. {
  233. Variable *vp;
  234. /* Free the variables from our list, if we have one.. */
  235. if (!VarHead)
  236. return;
  237. else if (!VarHead->next) {
  238. unsetenv(VarHead->name);
  239. safe_free(VarHead->name);
  240. safe_free(VarHead->value);
  241. free(VarHead);
  242. VarHead = NULL;
  243. }
  244. else {
  245. for (vp = VarHead; vp; ) {
  246. Variable *save = vp;
  247. unsetenv(vp->name);
  248. safe_free(vp->name);
  249. safe_free(vp->value);
  250. vp = vp->next;
  251. safe_free(save);
  252. }
  253. VarHead = NULL;
  254. }
  255. }
  256. /*
  257. * Persistent variables. The variables modified by these functions
  258. * are not cleared between invocations of sysinstall. This is useful
  259. * to allow the user to completely restart sysinstall, without having
  260. * it load all of the modules again from the installation media which
  261. * are still in memory.
  262. */
  263. void
  264. pvariable_set(char *var)
  265. {
  266. char *p;
  267. char tmp[1024];
  268. if (!var)
  269. msgFatal("NULL variable name & value passed.");
  270. else if (!*var)
  271. msgDebug("Warning: Zero length name & value passed to variable_set()\n");
  272. /* Add a trivial namespace to whatever name the caller chooses. */
  273. SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
  274. if (strchr(var, '=') == NULL)
  275. msgFatal("Invalid variable format: %s", var);
  276. strlcat(tmp, var, 1024);
  277. p = strchr(tmp, '=');
  278. *p = '\0';
  279. setenv(tmp, p + 1, 1);
  280. }
  281. char *
  282. pvariable_get(char *var)
  283. {
  284. char tmp[1024];
  285. SAFE_STRCPY(tmp, "SYSINSTALL_PVAR");
  286. strlcat(tmp, var, 1024);
  287. return getenv(tmp);
  288. }