PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/usr/src/cmd/svr4pkg/libinst/depchk.c

https://github.com/richlowe/illumos-gate
C | 349 lines | 206 code | 52 blank | 91 comment | 49 complexity | a13fe77f1db37bc63d4a3cc7686ca692 MD5 | raw file
  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. /*
  26. * System includes
  27. */
  28. #include <stdio.h>
  29. #include <limits.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #include <errno.h>
  34. #include <sys/types.h>
  35. #include <locale.h>
  36. #include <libintl.h>
  37. #include <assert.h>
  38. /*
  39. * local pkg command library includes
  40. */
  41. #include "libinst.h"
  42. #include "messages.h"
  43. /*
  44. * forward declarations
  45. */
  46. static int
  47. collectError(int *r_numZones, char **r_zoneNames, char *a_packageName,
  48. depckl_t *a_dck, int a_depIndex, depckErrorRecord_t *a_eir,
  49. int a_errIndex);
  50. /*
  51. * *****************************************************************************
  52. * global external (public) functions
  53. * *****************************************************************************
  54. */
  55. int
  56. depchkReportErrors(depckl_t *a_dck)
  57. {
  58. char *packageName;
  59. char *zonenames;
  60. char msgbuf[4096];
  61. int err;
  62. int i;
  63. int numzones = 0;
  64. /* entry assertions */
  65. assert(a_dck != (depckl_t *)NULL);
  66. /* entry debugging info */
  67. echoDebug(DBG_DEPCHK_ENTRY);
  68. zonenames = (char *)NULL;
  69. /* go through dependency table, collect, collapse, report errors */
  70. for (i = 0; a_dck[i].name != (char *)NULL; i++) {
  71. int j;
  72. depckError_t *erc;
  73. if (zonenames != (char *)NULL) {
  74. free(zonenames);
  75. zonenames = (char *)NULL;
  76. }
  77. erc = a_dck[i].record;
  78. if (erc->er_numEntries == 0) {
  79. continue;
  80. }
  81. for (j = 0; j < erc->er_numEntries; j++) {
  82. int k;
  83. depckErrorRecord_t *eir;
  84. if (zonenames != (char *)NULL) {
  85. free(zonenames);
  86. zonenames = (char *)NULL;
  87. }
  88. eir = &erc->er_theEntries[j];
  89. packageName = eir->ier_packageName;
  90. for (k = 0; k < eir->ier_numZones; k++) {
  91. int err;
  92. err = collectError(&numzones, &zonenames,
  93. packageName, a_dck, i, eir, k);
  94. if (err != 0) {
  95. if (zonenames != (char *)NULL) {
  96. free(zonenames);
  97. zonenames = (char *)NULL;
  98. }
  99. return (err);
  100. }
  101. }
  102. if (a_dck[i].ignore_values == (char *)NULL) {
  103. continue;
  104. }
  105. if (a_dck[i].err_msg == (char **)NULL) {
  106. (void) snprintf(msgbuf, sizeof (msgbuf),
  107. ERR_DEPENDENCY_IGNORED, a_dck[i].name,
  108. packageName,
  109. numzones == 1 ? "zone" : "zones",
  110. zonenames ? zonenames : "?");
  111. } else {
  112. /* LINTED variable format specifier to ... */
  113. (void) snprintf(msgbuf, sizeof (msgbuf),
  114. *a_dck[i].err_msg, "package",
  115. packageName,
  116. numzones == 1 ? "zone" : "zones",
  117. zonenames ? zonenames : "??");
  118. }
  119. if (a_dck[i].depcklFunc != NULL) {
  120. /* call check function */
  121. err = (a_dck[i].depcklFunc)(msgbuf,
  122. packageName);
  123. echoDebug(DBG_DEPCHK_REPORT_ERROR,
  124. a_dck[i].ignore_values, err,
  125. packageName, msgbuf);
  126. if (err != 0) {
  127. if (zonenames != (char *)NULL) {
  128. free(zonenames);
  129. zonenames = (char *)NULL;
  130. }
  131. return (err);
  132. }
  133. } else {
  134. /* no check function - just report message */
  135. echoDebug(DBG_DEPCHK_IGNORE_ERROR,
  136. a_dck[i].ignore_values, packageName,
  137. msgbuf);
  138. ptext(stderr, "\\n%s", msgbuf);
  139. }
  140. }
  141. }
  142. if (zonenames != (char *)NULL) {
  143. free(zonenames);
  144. zonenames = (char *)NULL;
  145. }
  146. return (0);
  147. }
  148. void
  149. depchkRecordError(depckError_t *a_erc, char *a_pkginst,
  150. char *a_zoneName, char *a_value)
  151. {
  152. depckErrorRecord_t *erc;
  153. int i;
  154. /*
  155. * create new error record and entry if first entry
  156. * record will look like this:
  157. * err->er_#entry=1
  158. * err->entry[0]->record->ier_numZones=1
  159. * err->entry[0]->record->ier_packageName=a_pkginst
  160. * err->entry[0]->record->ier_zones[0]=a_zoneName
  161. * err->entry[0]->record->ier_values[0]=a_value
  162. */
  163. if (a_erc->er_numEntries == 0) {
  164. depckErrorRecord_t *eir;
  165. eir = (depckErrorRecord_t *)calloc(1,
  166. sizeof (depckErrorRecord_t));
  167. eir->ier_packageName = strdup(a_pkginst);
  168. eir->ier_numZones = 1;
  169. eir->ier_zones = (char **)calloc(1, sizeof (char **));
  170. (eir->ier_zones)[eir->ier_numZones-1] = strdup(a_zoneName);
  171. eir->ier_values = (char **)calloc(1, sizeof (char *));
  172. (eir->ier_values)[eir->ier_numZones-1] = strdup(a_value);
  173. a_erc->er_numEntries = 1;
  174. a_erc->er_theEntries = eir;
  175. echoDebug(DBG_DEPCHK_RECORD_ERROR, (long)a_erc, a_pkginst,
  176. a_zoneName, a_value);
  177. return;
  178. }
  179. /* see if this package already has an entry if so add zone to list */
  180. for (i = 0; i < a_erc->er_numEntries; i++) {
  181. erc = &a_erc->er_theEntries[i];
  182. if (strcmp(erc->ier_packageName, a_pkginst) != 0) {
  183. continue;
  184. }
  185. echoDebug(DBG_DEPCHK_RECORD_ZERROR, (long)a_erc, a_zoneName,
  186. a_value, erc->ier_packageName, erc->ier_numZones,
  187. erc->ier_zones[0]);
  188. /*
  189. * this package already has an entry - add zone to
  190. * existing package entry the modified records will
  191. * look like this:
  192. * err->er_#entry++;
  193. * err->entry[0]->...
  194. * err->entry[i]->
  195. * -------------->record->
  196. * ---------------------->ier_numZones++;
  197. * ---------------------->ier_packageName=a_pkginst
  198. * ---------------------->ier_zones[0]=...
  199. * ---------------------->ier_zones[...]=...
  200. * ---------------------->ier_zones[ier_numZones-1]=a_zoneName
  201. * ---------------------->ier_values[0]=...
  202. * ---------------------->ier_values[...]=...
  203. * ---------------------->ier_values[ier_numZones-1]=a_value
  204. * err->entry[i+1]->...
  205. */
  206. erc->ier_numZones++;
  207. erc->ier_zones = (char **)realloc(erc->ier_zones,
  208. sizeof (char **)*erc->ier_numZones);
  209. (erc->ier_zones)[erc->ier_numZones-1] = strdup(a_zoneName);
  210. erc->ier_values = (char **)realloc(erc->ier_values,
  211. sizeof (char **)*erc->ier_numZones);
  212. (erc->ier_values)[erc->ier_numZones-1] = strdup(a_value);
  213. return;
  214. }
  215. /*
  216. * this packages does not have an entry - add new package
  217. * entry for this zone the modified records will look like this:
  218. * err->er_#entry++;
  219. * err->entry[0]->record->ier_numZones=...
  220. * err->entry[0]->record->ier_packageName=...
  221. * err->entry[0]->record->ier_zones[0]=...
  222. * err->entry[0]->record->ier_values[0]=...
  223. * err->entry[er_#entry-1]->record->ier_numZones=1
  224. * err->entry[er_#entry-1]->record->ier_packageName=a_pkginst
  225. * err->entry[er_#entry-1]->record->ier_zones[0]=a_zoneName
  226. * err->entry[er_#entry-1]->record->ier_values[0]=a_value
  227. */
  228. echoDebug(DBG_DEPCHK_RECORD_PERROR, (long)a_erc,
  229. a_erc->er_numEntries, a_pkginst, a_zoneName, a_value);
  230. a_erc->er_numEntries++;
  231. a_erc->er_theEntries = realloc(a_erc->er_theEntries,
  232. sizeof (depckErrorRecord_t)*a_erc->er_numEntries);
  233. erc = &a_erc->er_theEntries[a_erc->er_numEntries-1];
  234. erc->ier_packageName = strdup(a_pkginst);
  235. erc->ier_numZones = 1;
  236. erc->ier_zones = (char **)calloc(1, sizeof (char *));
  237. (erc->ier_zones)[erc->ier_numZones-1] = strdup(a_zoneName);
  238. erc->ier_values = (char **)calloc(1, sizeof (char *));
  239. (erc->ier_values)[erc->ier_numZones-1] = strdup(a_value);
  240. }
  241. /*
  242. * *****************************************************************************
  243. * static internal (private) functions
  244. * *****************************************************************************
  245. */
  246. static int
  247. collectError(int *r_numZones, char **r_zoneNames, char *a_packageName,
  248. depckl_t *a_dck, int a_depIndex, depckErrorRecord_t *a_eir,
  249. int a_errIndex)
  250. {
  251. char msgbuf[4096];
  252. char *zn = *r_zoneNames;
  253. if (a_dck[a_depIndex].ignore_values == (char *)NULL) {
  254. if (a_dck[a_depIndex].err_msg == (char **)NULL) {
  255. (void) snprintf(msgbuf, sizeof (msgbuf),
  256. ERR_DEPENDENCY_REPORT, a_eir->ier_values[a_errIndex],
  257. "package", a_packageName,
  258. "zone", a_eir->ier_zones[a_errIndex]);
  259. } else {
  260. /* LINTED variable format specifier to snprintf(); */
  261. (void) snprintf(msgbuf, sizeof (msgbuf),
  262. *a_dck[a_depIndex].err_msg,
  263. a_eir->ier_values[a_errIndex],
  264. "package", a_packageName,
  265. "zone", a_eir->ier_zones[a_errIndex]);
  266. }
  267. if (a_dck[a_depIndex].depcklFunc != NULL) {
  268. int err;
  269. err = (a_dck[a_depIndex].depcklFunc)(msgbuf,
  270. a_packageName);
  271. echoDebug(DBG_DEPCHK_COLLECT_ERROR, err, a_packageName,
  272. msgbuf);
  273. if (err != 0) {
  274. return (err);
  275. }
  276. } else {
  277. echoDebug(DBG_DEPCHK_COLLECT_IGNORE, a_packageName,
  278. msgbuf);
  279. ptext(stderr, "\\n%s", msgbuf);
  280. }
  281. return (0);
  282. }
  283. *r_numZones = (*r_numZones)+1;
  284. if (zn == (char *)NULL) {
  285. zn = strdup(a_eir->ier_zones[a_errIndex]);
  286. } else {
  287. char *p;
  288. int len = strlen(zn)+strlen(a_eir->ier_zones[a_errIndex])+3;
  289. p = calloc(1, len);
  290. (void) snprintf(p, len, "%s, %s", zn,
  291. a_eir->ier_zones[a_errIndex]);
  292. free(zn);
  293. zn = p;
  294. }
  295. *r_zoneNames = zn;
  296. return (0);
  297. }