37 |
37 |
38 /* Python DDU package module related definitions. */ |
38 /* Python DDU package module related definitions. */ |
39 #define DDU_PACKAGE_MODULE "DDU.ddu_package" |
39 #define DDU_PACKAGE_MODULE "DDU.ddu_package" |
40 #define DDU_PACKAGE_OBJECT "ddu_package_object" |
40 #define DDU_PACKAGE_OBJECT "ddu_package_object" |
41 |
41 |
42 /* Pkg commands. */ |
|
43 #define PKG_PUBLISHER "/usr/bin/pkg publisher" |
|
44 |
|
45 /* DDU error log */ |
42 /* DDU error log */ |
46 #define DDU_ERRLOG "/tmp/ddu_err.log" |
43 #define DDU_ERRLOG "/tmp/ddu_err.log" |
47 |
|
48 /* DDU error module related. */ |
|
49 #define DDU_ERROR_MODULE "DDU.ddu_errors" |
|
50 #define DDU_PACKAGE_NOT_FOUND_EXC "PackageNoFound" |
|
51 |
44 |
52 /* ICT module related definitions. */ |
45 /* ICT module related definitions. */ |
53 #define ICT_MODULE "osol_install.ict" |
46 #define ICT_MODULE "osol_install.ict" |
54 #define ICT_CLASS "ICT" |
47 #define ICT_CLASS "ICT" |
55 #define ICT_UPDATE_ARCHIVE "update_boot_archive" |
48 #define ICT_UPDATE_ARCHIVE "update_boot_archive" |
56 |
49 |
57 /* AI Manifest (AIM) related path definitions. */ |
50 /* AI Manifest (AIM) related path definitions. */ |
58 #define AIM_PREFACE "auto_install/ai_instance/add_drivers/" |
51 #define AIM_PREFACE "auto_install/ai_instance/add_drivers/" |
59 #define PKGSPEC_NODEPATH "software" |
52 #define PKGSPEC_NODEPATH "software" |
60 #define ORIGIN_NODEPATH "software/source/publisher/origin/name" |
53 #define ORIGIN_NODEPATH "software/source/publisher/origin/name" |
61 #define TYPE_NODEPATH "software[source/publisher/origin/" \ |
54 #define TYPE_NODEPATH \ |
62 "name=\"%s\"]/software_data/type" |
55 "software[source/publisher/origin/name=\"%s\"]/software_data/type" |
63 #define NAME_NODEPATH "software[source/publisher/origin/" \ |
56 #define NAME_NODEPATH \ |
64 "name=\"%s\":software_data/" \ |
57 "software[source/publisher/origin/name=\"%s\":software_data/type=\"%s\"]/software_data/name" |
65 "type=\"%s\"]/software_data/name" |
|
66 #define ACTION_NONAME_NODEPATH \ |
58 #define ACTION_NONAME_NODEPATH \ |
67 "software[source/publisher/origin/" \ |
59 "software[source/publisher/origin/name=\"%s\":software_data/type=\"%s\"]/software_data/action" |
68 "name=\"%s\":software_data/" \ |
|
69 "type=\"%s\"]/software_data/action" |
|
70 #define ACTION_YESNAME_NODEPATH \ |
60 #define ACTION_YESNAME_NODEPATH \ |
71 "software[source/publisher/origin/" \ |
61 "software[source/publisher/origin/name=\"%s\":software_data/type=\"%s\":software_data/name=\"%s\"]/software_data/action" |
72 "name=\"%s\":software_data/type=\"%s\":" \ |
|
73 "software_data/name=\"%s\"]/" \ |
|
74 "software_data/action" |
|
75 |
62 |
76 #define SEARCH_NODEPATH "search_all" |
63 #define SEARCH_NODEPATH "search_all" |
77 #define SEARCH_ORIGIN_NODEPATH "search_all/source/publisher/origin/name" |
64 #define SEARCH_ORIGIN_NODEPATH "search_all/source/publisher/origin/name" |
78 #define SEARCH_PUBNAME_NODEPATH "search_all/source/publisher/name" |
65 #define SEARCH_PUBNAME_NODEPATH "search_all/source/publisher/name" |
79 #define SEARCH_ADDALL_NODEPATH "search_all/addall" |
66 #define SEARCH_ADDALL_NODEPATH "search_all/addall" |
95 int post_prefix_len; |
81 int post_prefix_len; |
96 } path_t; |
82 } path_t; |
97 |
83 |
98 static py_state_t *auto_ddu_lib_init(); |
84 static py_state_t *auto_ddu_lib_init(); |
99 static void auto_ddu_lib_fini(py_state_t *py_state_p); |
85 static void auto_ddu_lib_fini(py_state_t *py_state_p); |
100 static void ai_dump_python_exception(); |
|
101 static PyObject *ai_call_ddu_devscan(py_state_t *py_state_p, |
86 static PyObject *ai_call_ddu_devscan(py_state_t *py_state_p, |
102 boolean_t get_only_missing_drivers, char *dev_type); |
87 boolean_t get_only_missing_drivers, char *dev_type); |
103 static int ai_call_ddu_package_lookup(py_state_t *py_state_p, |
88 static PyObject *ai_call_ddu_package_lookup(py_state_t *py_state_p, |
104 PyObject *pDevObj, PyObject *pRepoList, PyObject **pPackageObj_p); |
89 PyObject *pDevObj, PyObject *pRepoList); |
105 static int ai_call_ddu_install_package(py_state_t *py_state_p, |
90 static int ai_call_ddu_install_package(py_state_t *py_state_p, |
106 PyObject *ddu_package_obj, char *install_root, boolean_t third_party_ok); |
91 PyObject *ddu_package_obj, char *install_root, boolean_t third_party_ok); |
107 static PyObject *ai_new_ddu_package_object(py_state_t *py_state_p, |
92 static PyObject *ai_new_ddu_package_object(py_state_t *py_state_p, |
108 char *type, char *name, char *origin); |
93 char *type, char *name, char *origin); |
109 static int ai_get_ddu_package_object_values(PyObject *pDDUPackageObject, |
94 static int ai_get_ddu_package_object_values(PyObject *pDDUPackageObject, |
110 char **type, char **location, char **name, char **descr, char **inf_link, |
95 char **type, char **origin, char **name, char **descr, char **inf_link, |
111 boolean_t *third_party); |
96 boolean_t *third_party); |
112 static int ai_get_ddu_dev_data_values(PyObject *pDDUDevData, |
97 static int ai_get_ddu_dev_data_values(PyObject *pDDUDevData, |
113 char **dev_type_p, char **descr_p, char **vendor_ID_p, char **device_ID_p, |
98 char **dev_type, char **descr); |
114 char **class_p); |
99 static void ai_du_process_manual_pkg(py_state_t *py_state_p, |
115 static int ai_du_process_manual_pkg(py_state_t *py_state_p, |
|
116 PyObject *pPackageList, char *origin, char *type, char *name, |
100 PyObject *pPackageList, char *origin, char *type, char *name, |
117 char *noinstall); |
101 char *noinstall); |
118 static int ai_du_process_manual_pkg_names(py_state_t *py_state_p, |
102 static void ai_du_process_manual_pkg_names(py_state_t *py_state_p, |
119 path_t *path_p, PyObject *pPackageList, char *origin, char *type, |
103 PyObject *pPackageList, path_t *path_p, char *origin, char *type, |
120 char *name); |
104 char *name); |
121 static int ai_du_process_manual_pkg_types(py_state_t *py_state_p, |
105 static void ai_du_process_manual_pkg_types(py_state_t *py_state_p, |
122 PyObject *pPackageList, path_t *path_p, char *origin, char *type); |
106 PyObject *pPackageList, path_t *path_p, char *origin, char *type); |
123 static int ai_du_get_manual_pkg_list(py_state_t *py_state_p, path_t *path_p, |
107 static PyObject *ai_du_get_manual_pkg_list(py_state_t *py_state_p, |
124 PyObject **pPackageList_p); |
108 path_t *path_p); |
125 static int ai_du_get_searched_pkg_list(py_state_t *py_state_p, path_t *path_p, |
109 static PyObject *ai_du_get_searched_pkg_list(py_state_t *py_state_p, |
126 char *install_root, PyObject **pPackageList_p); |
110 path_t *path_p); |
127 static int ai_du_install_packages(py_state_t *py_state_p, |
111 static int ai_du_install_packages(py_state_t *py_state_p, |
128 PyObject *pPkgTupleList, char *install_root, boolean_t honor_noinstall, |
112 PyObject *pPkgTupleList, char *install_root, boolean_t honor_noinstall, |
129 int *num_installed_pkgs_p); |
113 int *num_installed_pkgs_p); |
130 static char **ai_uniq_manifest_values(char **in, int *len_p); |
114 static char **ai_uniq_manifest_values(char **in, int *len_p); |
131 static int ai_du_call_update_archive_ict(py_state_t *py_state_p, |
115 static int ai_du_call_update_archive_ict(py_state_t *py_state_p, |
156 * function, to undo the effects of this function. |
140 * function, to undo the effects of this function. |
157 */ |
141 */ |
158 static py_state_t * |
142 static py_state_t * |
159 auto_ddu_lib_init() |
143 auto_ddu_lib_init() |
160 { |
144 { |
|
145 PyObject *pName; |
161 py_state_t *py_state_p = malloc(sizeof (py_state_t)); |
146 py_state_t *py_state_p = malloc(sizeof (py_state_t)); |
162 |
147 |
163 static PyObject *pFunctionModule = NULL; |
148 py_state_p->pFunctionModule = NULL; |
164 static PyObject *pPackageModule = NULL; |
149 py_state_p->pPackageModule = NULL; |
165 static PyObject *pErrorModule = NULL; |
|
166 static PyObject *pICTModule = NULL; |
|
167 |
|
168 if (py_state_p == NULL) { |
|
169 auto_debug_print(AUTO_DBGLVL_ERR, "auto_ddu_lib_init: " |
|
170 "No memory.\n"); |
|
171 return (NULL); |
|
172 } |
|
173 |
|
174 /* If one of the above is NULL, all will be NULL. */ |
|
175 if (pFunctionModule == NULL) { |
|
176 PyObject *pName; |
|
177 |
|
178 /* Get names of modules for use by python/C interfaces. */ |
|
179 if ((pName = PyString_FromString(DDU_FUNCTION_MODULE)) != |
|
180 NULL) { |
|
181 pFunctionModule = PyImport_Import(pName); |
|
182 Py_DECREF(pName); |
|
183 } |
|
184 if ((pName = PyString_FromString(DDU_PACKAGE_MODULE)) != NULL) { |
|
185 pPackageModule = PyImport_Import(pName); |
|
186 Py_DECREF(pName); |
|
187 } |
|
188 if ((pName = PyString_FromString(DDU_ERROR_MODULE)) != NULL) { |
|
189 pErrorModule = PyImport_Import(pName); |
|
190 Py_DECREF(pName); |
|
191 } |
|
192 if ((pName = PyString_FromString(ICT_MODULE)) != NULL) { |
|
193 pICTModule = PyImport_Import(pName); |
|
194 Py_DECREF(pName); |
|
195 } |
|
196 |
|
197 /* Cleanup and return NULL on error. */ |
|
198 if ((pFunctionModule == NULL) || (pPackageModule == NULL) || |
|
199 (pErrorModule == NULL) || (pICTModule == NULL)) { |
|
200 auto_debug_print(AUTO_DBGLVL_ERR, "auto_ddu_lib_init: " |
|
201 "error accessing DDU library or ICT modules.\n"); |
|
202 PyErr_Print(); |
|
203 Py_XDECREF(pFunctionModule); |
|
204 Py_XDECREF(pPackageModule); |
|
205 Py_XDECREF(pErrorModule); |
|
206 Py_XDECREF(pICTModule); |
|
207 pFunctionModule = pPackageModule = NULL; |
|
208 pErrorModule = pICTModule = NULL; |
|
209 free(py_state_p); |
|
210 return (NULL); |
|
211 } |
|
212 } |
|
213 |
150 |
214 /* Set up python interpreter state. */ |
151 /* Set up python interpreter state. */ |
215 PyEval_InitThreads(); |
152 PyEval_InitThreads(); |
216 py_state_p->mainThreadState = PyThreadState_Get(); |
153 py_state_p->mainThreadState = PyThreadState_Get(); |
217 py_state_p->myThreadState = |
154 py_state_p->myThreadState = |
218 PyThreadState_New(py_state_p->mainThreadState->interp); |
155 PyThreadState_New(py_state_p->mainThreadState->interp); |
219 (void) PyThreadState_Swap(py_state_p->myThreadState); |
156 PyThreadState_Swap(py_state_p->myThreadState); |
220 |
157 |
221 py_state_p->pFunctionModule = pFunctionModule; |
158 /* Get names of modules for use by python/C interfaces. */ |
222 py_state_p->pPackageModule = pPackageModule; |
159 if ((pName = PyString_FromString(DDU_FUNCTION_MODULE)) != NULL) { |
223 py_state_p->pErrorModule = pErrorModule; |
160 py_state_p->pFunctionModule = PyImport_Import(pName); |
224 py_state_p->pICTModule = pICTModule; |
161 Py_DECREF(pName); |
|
162 } |
|
163 if ((pName = PyString_FromString(DDU_PACKAGE_MODULE)) != NULL) { |
|
164 py_state_p->pPackageModule = PyImport_Import(pName); |
|
165 Py_DECREF(pName); |
|
166 } |
|
167 if ((pName = PyString_FromString(ICT_MODULE)) != NULL) { |
|
168 py_state_p->pICTModule = PyImport_Import(pName); |
|
169 Py_DECREF(pName); |
|
170 } |
|
171 |
|
172 /* Cleanup and return NULL on error. */ |
|
173 if ((py_state_p->pFunctionModule == NULL) || |
|
174 (py_state_p->pPackageModule == NULL) || |
|
175 (py_state_p->pICTModule == NULL)) { |
|
176 auto_debug_print(AUTO_DBGLVL_ERR, "auto_ddu_lib_init: " |
|
177 "error accessing DDU library or ICT modules.\n"); |
|
178 PyErr_Print(); |
|
179 auto_ddu_lib_fini(py_state_p); |
|
180 py_state_p = NULL; |
|
181 } |
225 |
182 |
226 return (py_state_p); |
183 return (py_state_p); |
227 } |
184 } |
228 |
185 |
229 /* |
186 /* |
365 static PyObject * |
289 static PyObject * |
366 ai_call_ddu_devscan(py_state_t *py_state_p, |
290 ai_call_ddu_devscan(py_state_t *py_state_p, |
367 boolean_t get_only_missing_drivers, char *dev_type) |
291 boolean_t get_only_missing_drivers, char *dev_type) |
368 { |
292 { |
369 PyObject *pRet = NULL; |
293 PyObject *pRet = NULL; |
370 PyObject *pList = NULL; |
|
371 Py_ssize_t orig_listlen; |
|
372 char **vids, **dids, **classes; |
|
373 Py_ssize_t new_listused = 0; |
|
374 Py_ssize_t i, j; |
|
375 |
294 |
376 /* Find the function */ |
295 /* Find the function */ |
377 PyObject *pFunc = PyObject_GetAttrString(py_state_p->pFunctionModule, |
296 PyObject *pFunc = PyObject_GetAttrString(py_state_p->pFunctionModule, |
378 DDU_DEVSCAN); |
297 DDU_DEVSCAN); |
379 |
298 |
380 if ((pFunc == NULL) || (!PyCallable_Check(pFunc))) { |
299 if ((pFunc == NULL) || (!PyCallable_Check(pFunc))) { |
381 auto_debug_print(AUTO_DBGLVL_ERR, |
300 auto_debug_print(AUTO_DBGLVL_ERR, |
382 "Function not callable: %s\n", DDU_DEVSCAN); |
301 "Function not callable: %s\n", DDU_DEVSCAN); |
383 Py_XDECREF(pFunc); |
|
384 return (NULL); |
|
385 } else { |
302 } else { |
386 /* Set up args to python function and call it. */ |
303 /* Set up args to python function and call it. */ |
387 PyObject *pArgs = PyTuple_New(2); |
304 PyObject *pArgs = PyTuple_New(2); |
388 (void) PyTuple_SetItem(pArgs, 0, |
305 PyTuple_SetItem(pArgs, 0, |
389 PyBool_FromLong((long)get_only_missing_drivers)); |
306 PyBool_FromLong((long)get_only_missing_drivers)); |
390 (void) PyTuple_SetItem(pArgs, 1, PyString_FromString(dev_type)); |
307 PyTuple_SetItem(pArgs, 1, PyString_FromString(dev_type)); |
391 pList = PyObject_CallObject(pFunc, pArgs); |
308 pRet = PyObject_CallObject(pFunc, pArgs); |
392 |
309 |
393 Py_DECREF(pArgs); |
310 Py_DECREF(pArgs); |
394 if ((PyErr_Occurred() != NULL) || (pList == NULL) || |
311 if ((PyErr_Occurred()) || (pRet == NULL) || (pRet == Py_None)) { |
395 (pList == Py_None)) { |
|
396 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
312 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
397 auto_debug_print(AUTO_DBGLVL_ERR, |
313 auto_debug_print(AUTO_DBGLVL_ERR, |
398 "%s returned an error.\n", DDU_DEVSCAN); |
314 "%s returned an error.\n", DDU_DEVSCAN); |
399 ai_dump_python_exception(); |
315 if (PyErr_Occurred()) { |
400 Py_XDECREF(pList); |
316 PyErr_Print(); |
401 Py_XDECREF(pFunc); |
317 } |
402 return (NULL); |
318 Py_XDECREF(pRet); |
|
319 pRet = NULL; |
403 } |
320 } |
404 } |
321 } |
405 |
322 |
406 Py_XDECREF(pFunc); |
323 Py_XDECREF(pFunc); |
407 |
|
408 orig_listlen = PyList_Size(pList); |
|
409 if (orig_listlen < 2) { |
|
410 return (pList); |
|
411 } |
|
412 |
|
413 /* Check for duplicates. */ |
|
414 vids = (char **)malloc(sizeof (char *) * orig_listlen); |
|
415 dids = (char **)malloc(sizeof (char *) * orig_listlen); |
|
416 classes = (char **)malloc(sizeof (char *) * orig_listlen); |
|
417 if ((vids == NULL) || (dids == NULL) || (classes == NULL)) { |
|
418 auto_debug_print(AUTO_DBGLVL_ERR, |
|
419 "ai_call_ddu_devscan: No memory.\n"); |
|
420 return (NULL); |
|
421 } |
|
422 |
|
423 /* Build a list of unique values to be returned. */ |
|
424 pRet = PyList_New(0); |
|
425 |
|
426 /* Loop through the list. */ |
|
427 for (i = 0; i < orig_listlen; i++) { |
|
428 PyObject *pDDUDevData = PyList_GetItem(pList, i); |
|
429 char *vendor_ID, *device_ID, *class; |
|
430 boolean_t dup; |
|
431 |
|
432 if (ai_get_ddu_dev_data_values(pDDUDevData, NULL, NULL, |
|
433 &vendor_ID, &device_ID, &class) != AUTO_INSTALL_SUCCESS) { |
|
434 /* If can't compare, just allow it. */ |
|
435 continue; |
|
436 } |
|
437 |
|
438 /* Check for matching vendor, device, class. */ |
|
439 for (j = 0, dup = B_FALSE; j < new_listused; j++) { |
|
440 if ((strcmp(class, classes[j]) == 0) && |
|
441 (strcmp(device_ID, dids[j]) == 0) && |
|
442 (strcmp(vendor_ID, vids[j]) == 0)) { |
|
443 dup = B_TRUE; |
|
444 break; |
|
445 } |
|
446 } |
|
447 |
|
448 if (!dup) { |
|
449 (void) PyList_Append(pRet, pDDUDevData); |
|
450 vids[new_listused] = vendor_ID; |
|
451 dids[new_listused] = device_ID; |
|
452 classes[new_listused++] = class; |
|
453 } |
|
454 } |
|
455 |
|
456 free(vids); |
|
457 free(dids); |
|
458 free(classes); |
|
459 |
|
460 Py_XDECREF(pList); |
|
461 return (pRet); |
324 return (pRet); |
462 } |
325 } |
463 |
326 |
464 /* |
327 /* |
465 * ai_call_ddu_package_lookup: |
328 * ai_call_ddu_package_lookup: |
470 * Arguments: |
333 * Arguments: |
471 * py_state_p: Initialized py_state_t object. |
334 * py_state_p: Initialized py_state_t object. |
472 * pDevObj: A python ddu_dev_data object representing a device. |
335 * pDevObj: A python ddu_dev_data object representing a device. |
473 * pRepoList: A python list of ddu_repo_object objects. This represents the |
336 * pRepoList: A python list of ddu_repo_object objects. This represents the |
474 * list of repositories to search through for a driver package. |
337 * list of repositories to search through for a driver package. |
475 * pPackageObj_p: Pointer to the returned ddu_package_object. |
|
476 * |
338 * |
477 * Returns: |
339 * Returns: |
478 * AUTO_INSTALL_SUCCESS: pPackageObj_p points to an object representing a |
340 * Success: A python ddu_package_object representing a package to install for |
479 * package to install for the given device. |
341 * the given device. |
480 * AUTO_INSTALL_PKG_NOT_FOUND: No package was found to install for the given |
342 * Failure: NULL |
481 * device. pPackageObj_p set to NULL. |
343 */ |
482 * AUTO_INSTALL_FAILURE: Corresponds to an error other than not finding the |
344 static PyObject * |
483 * package to install for the given device. pPackageObj_p set to NULL. |
|
484 */ |
|
485 static int |
|
486 ai_call_ddu_package_lookup(py_state_t *py_state_p, |
345 ai_call_ddu_package_lookup(py_state_t *py_state_p, |
487 PyObject *pDevObj, PyObject *pRepoList, PyObject **pPackageObj_p) |
346 PyObject *pDevObj, PyObject *pRepoList) |
488 { |
347 { |
489 int err = AUTO_INSTALL_SUCCESS; |
348 PyObject *pRet = NULL; |
490 |
349 |
491 /* Find the function */ |
350 /* Find the function */ |
492 PyObject *pFunc = PyObject_GetAttrString(py_state_p->pFunctionModule, |
351 PyObject *pFunc = PyObject_GetAttrString(py_state_p->pFunctionModule, |
493 DDU_PACKAGE_LOOKUP); |
352 DDU_PACKAGE_LOOKUP); |
494 |
|
495 *pPackageObj_p = NULL; |
|
496 |
353 |
497 if ((pFunc == NULL) || (!PyCallable_Check(pFunc))) { |
354 if ((pFunc == NULL) || (!PyCallable_Check(pFunc))) { |
498 auto_debug_print(AUTO_DBGLVL_ERR, |
355 auto_debug_print(AUTO_DBGLVL_ERR, |
499 "Function not callable: %s\n", DDU_PACKAGE_LOOKUP); |
356 "Function not callable: %s\n", DDU_PACKAGE_LOOKUP); |
500 } else { |
357 } else { |
501 /* Set up args to python function. */ |
358 /* Set up args to python function. */ |
502 PyObject *pArgs = PyTuple_New(2); |
359 PyObject *pArgs = PyTuple_New(2); |
503 Py_INCREF(pDevObj); /* PyTuple_SetItem steals reference. */ |
360 Py_INCREF(pDevObj); /* PyTuple_SetItem steals reference. */ |
504 Py_INCREF(pRepoList); /* PyTuple_SetItem steals reference. */ |
361 Py_INCREF(pRepoList); /* PyTuple_SetItem steals reference. */ |
505 (void) PyTuple_SetItem(pArgs, 0, pDevObj); |
362 PyTuple_SetItem(pArgs, 0, pDevObj); |
506 (void) PyTuple_SetItem(pArgs, 1, pRepoList); |
363 PyTuple_SetItem(pArgs, 1, pRepoList); |
507 |
364 |
508 /* Call ddu_package_lookup() */ |
365 /* Call ddu_package_lookup() */ |
509 *pPackageObj_p = PyObject_CallObject(pFunc, pArgs); |
366 pRet = PyObject_CallObject(pFunc, pArgs); |
510 Py_DECREF(pArgs); |
367 Py_DECREF(pArgs); |
511 if ((PyErr_Occurred() != NULL) || (*pPackageObj_p == NULL) || |
368 if ((PyErr_Occurred()) || (pRet == NULL) || (pRet == Py_None)) { |
512 (*pPackageObj_p == Py_None)) { |
|
513 err = AUTO_INSTALL_FAILURE; |
|
514 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
369 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
515 auto_debug_print(AUTO_DBGLVL_ERR, |
370 auto_debug_print(AUTO_DBGLVL_ERR, |
516 "%s returned an error.\n", DDU_PACKAGE_LOOKUP); |
371 "%s returned an error.\n", DDU_PACKAGE_LOOKUP); |
517 if (PyErr_Occurred() != NULL) { |
372 if (PyErr_Occurred()) { |
518 PyObject *pType, *pValue, *pTraceback; |
373 PyErr_Print(); |
519 PyObject *pPkgNotFndExcObj = |
|
520 PyObject_GetAttrString( |
|
521 py_state_p->pErrorModule, |
|
522 DDU_PACKAGE_NOT_FOUND_EXC); |
|
523 PyErr_Fetch(&pType, &pValue, &pTraceback); |
|
524 |
|
525 if (PyObject_IsSubclass(pType, |
|
526 pPkgNotFndExcObj) == 1) { /* 1 = match */ |
|
527 err = AUTO_INSTALL_PKG_NOT_FND; |
|
528 } |
|
529 Py_DECREF(pType); |
|
530 Py_DECREF(pValue); |
|
531 Py_DECREF(pTraceback); |
|
532 Py_DECREF(pPkgNotFndExcObj); |
|
533 PyErr_Clear(); |
|
534 } |
374 } |
535 Py_XDECREF(*pPackageObj_p); |
375 Py_XDECREF(pRet); |
536 *pPackageObj_p = NULL; |
376 pRet = NULL; |
537 |
|
538 } else { |
|
539 /* |
|
540 * DDU can return a pPackageObj_p that has type unknown, |
|
541 * no location and no inf_link. Treat these as |
|
542 * "package not found" as well. |
|
543 */ |
|
544 char *ttype = empty_string; |
|
545 char *tlocn = empty_string; |
|
546 char *tinf_link = empty_string; |
|
547 (void) ai_get_ddu_package_object_values(*pPackageObj_p, |
|
548 &ttype, &tlocn, NULL, NULL, &tinf_link, NULL); |
|
549 if ((tlocn[0] == '\0') && (tinf_link[0] == '\0') && |
|
550 (strcmp(ttype, "UNK") == 0)) { |
|
551 err = AUTO_INSTALL_PKG_NOT_FND; |
|
552 Py_XDECREF(*pPackageObj_p); |
|
553 *pPackageObj_p = NULL; |
|
554 } |
|
555 } |
377 } |
556 } |
378 } |
557 |
379 |
558 Py_XDECREF(pFunc); |
380 Py_XDECREF(pFunc); |
559 return (err); |
381 return (pRet); |
560 } |
382 } |
561 |
383 |
562 /* |
384 /* |
563 * ai_call_ddu_install_package: |
385 * ai_call_ddu_install_package: |
564 * Call the DDU library ddu_install_package function. Install the package |
386 * Call the DDU library ddu_install_package function. Install the package |
599 } else { |
421 } else { |
600 |
422 |
601 /* Set up args to python function. */ |
423 /* Set up args to python function. */ |
602 PyObject *pArgs = PyTuple_New(3); |
424 PyObject *pArgs = PyTuple_New(3); |
603 Py_INCREF(pDDUPackageObj); /* PyTuple_SetItem steals ref */ |
425 Py_INCREF(pDDUPackageObj); /* PyTuple_SetItem steals ref */ |
604 (void) PyTuple_SetItem(pArgs, 0, pDDUPackageObj); |
426 PyTuple_SetItem(pArgs, 0, pDDUPackageObj); |
605 (void) PyTuple_SetItem(pArgs, 1, |
427 PyTuple_SetItem(pArgs, 1, PyString_FromString(install_root)); |
606 PyString_FromString(install_root)); |
428 PyTuple_SetItem(pArgs, 2, |
607 (void) PyTuple_SetItem(pArgs, 2, |
|
608 PyBool_FromLong((long)third_party_ok)); |
429 PyBool_FromLong((long)third_party_ok)); |
609 |
430 |
610 /* Call ddu_install_packages() */ |
431 /* Call ddu_install_packages() */ |
611 (void) PyObject_CallObject(pFunc, pArgs); |
432 PyObject_CallObject(pFunc, pArgs); |
612 Py_DECREF(pArgs); |
433 Py_DECREF(pArgs); |
613 |
434 |
614 if (PyErr_Occurred() != NULL) { |
435 if (PyErr_Occurred()) { |
615 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
436 auto_debug_dump_file(AUTO_DBGLVL_ERR, DDU_ERRLOG); |
616 auto_debug_print(AUTO_DBGLVL_ERR, |
437 auto_debug_print(AUTO_DBGLVL_ERR, |
617 "%s returned an error\n", DDU_INSTALL_PACKAGE); |
438 "%s returned an error\n", DDU_INSTALL_PACKAGE); |
618 ai_dump_python_exception(); |
439 PyErr_Print(); |
619 rval = AUTO_INSTALL_FAILURE; |
440 rval = AUTO_INSTALL_FAILURE; |
620 } |
441 } |
621 } |
442 } |
622 |
443 |
623 Py_XDECREF(pFunc); |
444 Py_XDECREF(pFunc); |
624 return (rval); |
445 return (rval); |
625 } |
446 } |
626 |
447 |
627 /* |
448 /* |
628 * ai_new_ddu_package_object: |
449 * ai_new_ddu_package_object: |
629 * Create a new ddu_package_object of given type, name and location. |
450 * Create a new ddu_package_object of given type, name and origin. |
630 * |
451 * |
631 * Arguments: |
452 * Arguments: |
632 * py_state_p: Initialized py_state_t object. |
453 * py_state_p: Initialized py_state_t object. |
633 * type: type of package. |
454 * type: type of package. |
634 * name: name of package. (Not used by all types of packages.) |
455 * name: name of package. (Not used by all types of packages.) |
635 * origin: directory of where package is located. |
456 * origin: directory of where package is located. |
636 * |
457 * |
637 * Returns: |
458 * Returns: |
638 * Success: A new python ddu_package_object object of the given |
459 * Success: A new python ddu_package_object object of the given |
639 * type/name/location. |
460 * type/name/origin. |
640 * Failure: NULL |
461 * Failure: NULL |
641 */ |
462 */ |
642 static PyObject * |
463 static PyObject * |
643 ai_new_ddu_package_object(py_state_t *py_state_p, |
464 ai_new_ddu_package_object(py_state_t *py_state_p, |
644 char *type, char *name, char *origin) |
465 char *type, char *name, char *origin) |
804 * Note: implementation is tied to the fields of the python object. |
626 * Note: implementation is tied to the fields of the python object. |
805 * |
627 * |
806 * Arguments: |
628 * Arguments: |
807 * pDDUDevData: Object to extract values from. Assumed to be a |
629 * pDDUDevData: Object to extract values from. Assumed to be a |
808 * ddu_dev_data object; not verified. |
630 * ddu_dev_data object; not verified. |
809 * dev_type_p: char string pointer returned filled in with "device_type" |
631 * dev_type: char string pointer returned filled in with "device_type" field. |
810 * field. Not processed if NULL. |
|
811 * descr_p: char string pointer returned filled in with "description" field. |
|
812 * Not processed if NULL. |
632 * Not processed if NULL. |
813 * vendor_ID_p: char string pointer returned filled in with "vendor ID" field. |
633 * descr: char string pointer returned filled in with "description" field. |
814 * Not processed if NULL. |
|
815 * device_ID_p: char string pointer returned filled in with "device ID" field. |
|
816 * Not processed if NULL. |
|
817 * class_p: char string pointer returned filled in with PCI "class" field. |
|
818 * Not processed if NULL. |
634 * Not processed if NULL. |
819 * |
635 * |
820 * Returns: |
636 * Returns: |
821 * AUTO_INSTALL_SUCCESS: when all requested fields are found and extracted. |
637 * AUTO_INSTALL_SUCCESS: when all requested fields are found and extracted. |
822 * AUTO_INSTALL_FAILURE: when one or more fields could not be found or |
638 * AUTO_INSTALL_FAILURE: when one or more fields could not be found or |
823 * extracted. |
639 * extracted. |
824 */ |
640 */ |
825 static int |
641 static int |
826 ai_get_ddu_dev_data_values(PyObject *pDDUDevData, char **dev_type_p, |
642 ai_get_ddu_dev_data_values(PyObject *pDDUDevData, char **dev_type, char **descr) |
827 char **descr_p, char **vendor_ID_p, char **device_ID_p, char **class_p) |
|
828 { |
643 { |
829 PyObject *pValue; |
644 PyObject *pValue; |
830 |
645 |
831 if (dev_type_p != NULL) { |
646 if (dev_type != NULL) { |
832 pValue = PyObject_GetAttrString(pDDUDevData, "device_type"); |
647 pValue = PyObject_GetAttrString(pDDUDevData, "device_type"); |
833 if (pValue == NULL) { |
648 if (pValue == NULL) { |
834 auto_debug_print(AUTO_DBGLVL_ERR, |
649 auto_debug_print(AUTO_DBGLVL_ERR, |
835 "ai_get_ddu_dev_data_values: " |
650 "ai_get_ddu_dev_data_values: " |
836 "no ddu_dev_data device_type field.\n"); |
651 "no ddu_dev_data device_type field.\n"); |
837 return (AUTO_INSTALL_FAILURE); |
652 return (AUTO_INSTALL_FAILURE); |
838 } |
653 } |
839 *dev_type_p = PyString_AsString(pValue); |
654 *dev_type = PyString_AsString(pValue); |
840 } |
655 } |
841 |
656 |
842 if (descr_p != NULL) { |
657 if (descr != NULL) { |
843 pValue = PyObject_GetAttrString(pDDUDevData, "description"); |
658 pValue = PyObject_GetAttrString(pDDUDevData, "description"); |
844 if (pValue == NULL) { |
659 if (pValue == NULL) { |
845 auto_debug_print(AUTO_DBGLVL_ERR, |
660 auto_debug_print(AUTO_DBGLVL_ERR, |
846 "ai_get_ddu_dev_data_values: " |
661 "ai_get_ddu_dev_data_values: " |
847 "no ddu_dev_data description field.\n"); |
662 "no ddu_dev_data description field.\n"); |
848 return (AUTO_INSTALL_FAILURE); |
663 return (AUTO_INSTALL_FAILURE); |
849 } |
664 } |
850 *descr_p = PyString_AsString(pValue); |
665 *descr = PyString_AsString(pValue); |
851 } |
|
852 |
|
853 if (vendor_ID_p != NULL) { |
|
854 pValue = PyObject_GetAttrString(pDDUDevData, "vendor_id"); |
|
855 if (pValue == NULL) { |
|
856 auto_debug_print(AUTO_DBGLVL_ERR, |
|
857 "ai_get_ddu_dev_data_values: " |
|
858 "no ddu_dev_data vendor_id field.\n"); |
|
859 return (AUTO_INSTALL_FAILURE); |
|
860 } |
|
861 *vendor_ID_p = PyString_AsString(pValue); |
|
862 } |
|
863 |
|
864 if (device_ID_p != NULL) { |
|
865 pValue = PyObject_GetAttrString(pDDUDevData, "device_id"); |
|
866 if (pValue == NULL) { |
|
867 auto_debug_print(AUTO_DBGLVL_ERR, |
|
868 "ai_get_ddu_dev_data_values: " |
|
869 "no ddu_dev_data device_id field.\n"); |
|
870 return (AUTO_INSTALL_FAILURE); |
|
871 } |
|
872 *device_ID_p = PyString_AsString(pValue); |
|
873 } |
|
874 |
|
875 if (class_p != NULL) { |
|
876 pValue = PyObject_GetAttrString(pDDUDevData, "class_code"); |
|
877 if (pValue == NULL) { |
|
878 auto_debug_print(AUTO_DBGLVL_ERR, |
|
879 "ai_get_ddu_dev_data_values: " |
|
880 "no ddu_dev_data class_code field.\n"); |
|
881 return (AUTO_INSTALL_FAILURE); |
|
882 } |
|
883 *class_p = PyString_AsString(pValue); |
|
884 } |
666 } |
885 |
667 |
886 return (AUTO_INSTALL_SUCCESS); |
668 return (AUTO_INSTALL_SUCCESS); |
887 } |
669 } |
888 |
670 |
935 pDDUPackageObject = ai_new_ddu_package_object(py_state_p, |
712 pDDUPackageObject = ai_new_ddu_package_object(py_state_p, |
936 type, name, origin); |
713 type, name, origin); |
937 |
714 |
938 if (pDDUPackageObject == NULL) { |
715 if (pDDUPackageObject == NULL) { |
939 auto_debug_print(AUTO_DBGLVL_ERR, |
716 auto_debug_print(AUTO_DBGLVL_ERR, |
940 "ai_du_process_manual_pkg: <add_drivers> error:\n" |
717 "ai_du_get_pkg_list: <add_drivers> error:\n" |
941 "Error creating new package object for " |
718 "Error creating new package object for " |
942 "origin %s %s\n", origin, name); |
719 "origin %s %s\n", origin, name); |
943 return (AUTO_INSTALL_FAILURE); |
720 return; |
944 } |
721 } |
945 |
722 |
946 pTuple = PyTuple_New(3); |
723 pTuple = PyTuple_New(3); |
947 (void) PyTuple_SetItem(pTuple, 0, pDDUPackageObject); |
724 PyTuple_SetItem(pTuple, 0, pDDUPackageObject); |
948 (void) PyTuple_SetItem(pTuple, 1, Py_True); /* third party OK */ |
725 PyTuple_SetItem(pTuple, 1, Py_True); /* third party OK */ |
949 (void) PyTuple_SetItem(pTuple, 2, |
726 PyTuple_SetItem(pTuple, 2, |
950 (strcmp(noinstall, "true") == 0) ? Py_True : Py_False); |
727 (strcmp(noinstall, "true") == 0) ? Py_True : Py_False); |
951 |
728 |
952 /* |
729 /* |
953 * NOTE: Don't decref pTuple here as PyList_Append doesn't |
730 * NOTE: Don't decref pTuple here as PyList_Append doesn't |
954 * steal a reference to it. |
731 * steal a reference to it. |
955 */ |
732 */ |
956 (void) PyList_Append(pPackageList, pTuple); |
733 PyList_Append(pPackageList, pTuple); |
957 return (AUTO_INSTALL_SUCCESS); |
|
958 } |
734 } |
959 |
735 |
960 /* |
736 /* |
961 * ai_du_process_manual_pkg_names: |
737 * ai_du_process_manual_pkg_names: |
962 * Do any processing of packages for which unique origin (location), type and |
738 * Do any processing of packages for which unique origin, type and name are |
963 * name are known. |
739 * known. |
964 * |
740 * |
965 * Arguments: |
741 * Arguments: |
966 * py_state_p: Initialized py_state_t object. |
742 * py_state_p: Initialized py_state_t object. |
967 * path_p: Used to build nodepath strings for manifest checking. |
|
968 * pPackageList: List of packages to append the new ddu_package_object to. |
743 * pPackageList: List of packages to append the new ddu_package_object to. |
969 * origin: directory of where package is located. |
744 * origin: directory of where package is located. |
970 * type: type of package. |
745 * type: type of package. |
971 * name: name of package. |
746 * name: name of package. |
972 * |
747 * |
973 * Returns: |
748 * Returns: None |
974 * AUTO_INSTALL_SUCCESS: Package processed successfully and appended to |
749 * Note 1: the pPackageList will be modified. |
975 * pPackageList. |
750 * Note 2: Appropriate error messages are logged/displayed. |
976 * AUTO_INSTALL_FAILURE: An error occurred. No package appended to |
751 */ |
977 * pPackageList. |
752 static void |
978 * |
753 ai_du_process_manual_pkg_names(py_state_t *py_state_p, PyObject *pPackageList, |
979 * Note 1: the object pointed to by pPackageList will be modified. |
754 path_t *path_p, char *origin, char *type, char *name) |
980 */ |
|
981 static int |
|
982 ai_du_process_manual_pkg_names(py_state_t *py_state_p, path_t *path_p, |
|
983 PyObject *pPackageList, char *origin, char *type, char *name) |
|
984 { |
755 { |
985 char **actions; |
756 char **actions; |
986 int actions_len; |
757 int actions_len; |
987 char *nodespec; |
758 char *nodespec; |
988 int rval; |
|
989 |
759 |
990 /* Get the action attribute. */ |
760 /* Get the action attribute. */ |
991 |
761 |
992 /* Search is different depending on whether a name is specified. */ |
762 /* Search is different depending on whether a name is specified. */ |
993 if (name == empty_string) { |
763 if (name == empty_string) { |
996 nodespec = ACTION_YESNAME_NODEPATH; |
766 nodespec = ACTION_YESNAME_NODEPATH; |
997 } |
767 } |
998 |
768 |
999 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
769 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
1000 nodespec, origin, type, name) >= path_p->post_prefix_len) { |
770 nodespec, origin, type, name) >= path_p->post_prefix_len) { |
1001 auto_debug_print(AUTO_DBGLVL_ERR, |
771 auto_debug_print(AUTO_DBGLVL_ERR, "ai_du_get_pkg_list: " |
1002 "ai_du_process_manual_pkg_names: " |
|
1003 "<add_drivers> manifest error:\n" |
772 "<add_drivers> manifest error:\n" |
1004 "action path buffer overflow for origin \"%s\", " |
773 "action path buffer overflow for origin \"%s\", " |
1005 "type \"%s\", name \"%s\"\n", origin, type, name); |
774 "type \"%s\", name \"%s\"\n", origin, type, name); |
1006 return (AUTO_INSTALL_FAILURE); |
775 return; |
1007 } |
776 } |
1008 |
777 |
1009 actions = ai_get_manifest_values(path_p->path_str, &actions_len); |
778 actions = ai_get_manifest_values(path_p->path_str, &actions_len); |
1010 |
779 |
1011 /* |
780 /* |
1012 * Note: action must be present and must be |
781 * Note: action must be present and must be either "install" |
1013 * either "install" or "noinstall". |
782 * or "noinstall". |
1014 */ |
783 */ |
1015 if (actions_len <= 0) { |
784 if (actions_len <= 0) { |
1016 auto_log_print(gettext("Add Drivers: " |
785 auto_log_print(gettext("ai_du_get_pkg_list: " |
1017 "<add_drivers> manifest error:\n" |
786 "<add_drivers> manifest error:\n" |
1018 "no action value for origin \"%s\", " |
787 "no action value for origin \"%s\", " |
1019 "type \"%s\", name \"%s\"\n"), origin, type, name); |
788 "type \"%s\", name \"%s\"\n"), origin, type, name); |
1020 rval = AUTO_INSTALL_FAILURE; |
789 return; |
1021 |
790 |
1022 } else if (actions_len > 1) { |
791 } else if (actions_len > 1) { |
1023 auto_log_print(gettext("Add Drivers: " |
792 auto_log_print(gettext("ai_du_get_pkg_list: " |
1024 "<add_drivers> manifest error:\n" |
793 "<add_drivers> manifest error:\n" |
1025 "multiple action values for origin \"%s\", " |
794 "multiple action values for origin \"%s\", " |
1026 "type \"%s\", name \"%s\"\n"), origin, type, name); |
795 "type \"%s\", name \"%s\"\n"), origin, type, name); |
1027 rval = AUTO_INSTALL_FAILURE; |
796 return; |
1028 |
797 |
1029 } else if (strcmp(actions[0], "install") == 0) { |
798 } else if (strcmp(actions[0], "install") == 0) { |
1030 /* |
799 /* |
1031 * If action="install" then call ai_du_process_manual_pkg with |
800 * If action="install" then call ai_du_process_manual_pkg with |
1032 * noinstall param set to empty_string, which means pkg will be |
801 * noinstall param set to empty_string, which means pkg will be |
1033 * installed in both boot env and target. |
802 * installed in both boot env and target. |
1034 */ |
803 */ |
1035 |
804 |
1036 /* Obj pointed to by pPackageList will be modified. */ |
805 /* Obj pointed to by pPackageList will be modified. */ |
1037 rval = ai_du_process_manual_pkg(py_state_p, pPackageList, |
806 ai_du_process_manual_pkg(py_state_p, pPackageList, origin, |
1038 origin, type, name, empty_string); |
807 type, name, empty_string); |
1039 } else if (strcmp(actions[0], "noinstall") == 0) { |
808 } else if (strcmp(actions[0], "noinstall") == 0) { |
1040 /* |
809 /* |
1041 * If action="noinstall" then call ai_du_process_manual_pkg with |
810 * If action="noinstall" then call ai_du_process_manual_pkg with |
1042 * noinstall param set to "true", which means pkg will only be |
811 * noinstall param set to "true", which means pkg will only be |
1043 * installed in both boot env and not in target. |
812 * installed in both boot env and not in target. |
1044 */ |
813 */ |
1045 /* Obj pointed to by pPackageList will be modified. */ |
814 /* Obj pointed to by pPackageList will be modified. */ |
1046 rval = ai_du_process_manual_pkg(py_state_p, pPackageList, |
815 ai_du_process_manual_pkg(py_state_p, pPackageList, origin, |
1047 origin, type, name, "true"); |
816 type, name, "true"); |
1048 } else { |
817 } else { |
1049 auto_log_print(gettext("Add Drivers: " |
818 auto_log_print(gettext("ai_du_get_pkg_list: " |
1050 "<add_drivers> manifest error:\n" |
819 "<add_drivers> manifest error:\n" |
1051 "action must be install or noinstall for origin \"%s\", " |
820 "action must be install or noinstall for origin \"%s\", " |
1052 "type \"%s\", name \"%s\"\n"), origin, type, name); |
821 "type \"%s\", name \"%s\"\n"), origin, type, name); |
1053 rval = AUTO_INSTALL_FAILURE; |
822 return; |
|
823 |
1054 } |
824 } |
1055 ai_free_manifest_values(actions); |
825 ai_free_manifest_values(actions); |
1056 return (rval); |
|
1057 } |
826 } |
1058 |
827 |
1059 /* |
828 /* |
1060 * ai_du_process_manual_pkg_types: |
829 * ai_du_process_manual_pkg_types: |
1061 * Do any processing of packages for which unique location and type are known. |
830 * Do any processing of packages for which unique origin and type are known. |
1062 * |
831 * |
1063 * Arguments: |
832 * Arguments: |
1064 * py_state_p: Initialized py_state_t object. |
833 * py_state_p: Initialized py_state_t object. |
1065 * pPackageList: List of packages to append the new ddu_package_object to. |
834 * pPackageList: List of packages to append the new ddu_package_object to. |
1066 * origin: directory of where package is located. |
835 * origin: directory of where package is located. |
1067 * type: type of package. |
836 * type: type of package. |
1068 * |
837 * |
1069 * Returns: |
838 * Returns: None |
1070 * AUTO_INSTALL_SUCCESS: Package processed successfully and appended to |
|
1071 * pPackageList. |
|
1072 * AUTO_INSTALL_FAILURE: An error occurred. No package appended to |
|
1073 * pPackageList. |
|
1074 * |
|
1075 * Note 1: the pPackageList will be modified. |
839 * Note 1: the pPackageList will be modified. |
1076 * Note 2: Appropriate error messages are logged/displayed. |
840 * Note 2: Appropriate error messages are logged/displayed. |
1077 */ |
841 */ |
1078 static int |
842 static void |
1079 ai_du_process_manual_pkg_types(py_state_t *py_state_p, PyObject *pPackageList, |
843 ai_du_process_manual_pkg_types(py_state_t *py_state_p, PyObject *pPackageList, |
1080 path_t *path_p, char *origin, char *type) |
844 path_t *path_p, char *origin, char *type) |
1081 { |
845 { |
1082 char **names; |
846 char **names; |
1083 char **uniq_names; |
847 char **uniq_names; |
1084 int namelen; |
848 int namelen; |
1085 int k; |
849 int k; |
1086 int rval = AUTO_INSTALL_SUCCESS; |
|
1087 |
850 |
1088 if ((strcmp(type, "P5I") != 0) && |
851 if ((strcmp(type, "P5I") != 0) && |
1089 (strcmp(type, "SVR4") != 0) && |
852 (strcmp(type, "SVR4") != 0) && |
1090 (strcmp(type, "DU") != 0)) { |
853 (strcmp(type, "DU") != 0)) { |
1091 auto_log_print(gettext("Add Drivers: " |
854 auto_log_print(gettext("ai_du_get_pkg_list: " |
1092 "<add_drivers> manifest error:\n" |
855 "<add_drivers> manifest error:\n" |
1093 "invalid type %s given for origin %s\n"), type, origin); |
856 "invalid type %s given for origin %s\n"), |
1094 return (AUTO_INSTALL_FAILURE); |
857 type, origin); |
|
858 return; |
1095 } |
859 } |
1096 |
860 |
1097 /* Get all names assocated with type and origin. */ |
861 /* Get all names assocated with type and origin. */ |
1098 |
862 |
1099 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
863 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
1100 NAME_NODEPATH, origin, type) >= path_p->post_prefix_len) { |
864 NAME_NODEPATH, origin, type) >= path_p->post_prefix_len) { |
1101 auto_debug_print(AUTO_DBGLVL_ERR, |
865 auto_debug_print(AUTO_DBGLVL_ERR, "ai_du_get_pkg_list: " |
1102 "ai_du_process_manual_pkg_types: " |
|
1103 "<add_drivers> manifest error:\n" |
866 "<add_drivers> manifest error:\n" |
1104 "name path buffer overflow for origin " |
867 "name path buffer overflow for origin " |
1105 "%s, type %s\n", origin, type); |
868 "%s, type %s\n", origin, type); |
1106 return (AUTO_INSTALL_FAILURE); |
869 return; |
1107 } |
870 } |
1108 |
871 |
1109 names = ai_get_manifest_values(path_p->path_str, &namelen); |
872 names = ai_get_manifest_values(path_p->path_str, &namelen); |
1110 uniq_names = ai_uniq_manifest_values(names, &namelen); |
873 uniq_names = ai_uniq_manifest_values(names, &namelen); |
1111 ai_free_manifest_values(names); |
874 ai_free_manifest_values(names); |
1113 |
876 |
1114 /* P5I and DU type entries don't have a "name" entry. */ |
877 /* P5I and DU type entries don't have a "name" entry. */ |
1115 if (strcmp(type, "SVR4") != 0) { |
878 if (strcmp(type, "SVR4") != 0) { |
1116 if (namelen > 0) { |
879 if (namelen > 0) { |
1117 auto_log_print(gettext( |
880 auto_log_print(gettext( |
1118 "Add Drivers: <add_drivers> " |
881 "ai_du_get_pkg_list: <add_drivers> " |
1119 "manifest error:\n" |
882 "manifest error:\n" |
1120 "name given to P5I or DU package specification at " |
883 "name given to P5I or DU pkg spec at " |
1121 "origin %s\n"), origin); |
884 "origin %s\n"), origin); |
1122 rval = AUTO_INSTALL_FAILURE; |
885 return; |
1123 } else { |
886 } else { |
1124 /* Obj pointed to by pPackageList will be modified. */ |
887 /* Obj pointed to by pPackageList will be modified. */ |
1125 rval = ai_du_process_manual_pkg_names(py_state_p, |
888 ai_du_process_manual_pkg_names(py_state_p, pPackageList, |
1126 path_p, pPackageList, origin, type, empty_string); |
889 path_p, origin, type, empty_string); |
1127 } |
890 } |
1128 |
891 |
1129 /* There must be at least one "name" entry per pkgspec for SVR4 type. */ |
892 /* |
|
893 * There must be at least one "name" entry per pkg spec |
|
894 * for SVR4 type. |
|
895 */ |
1130 } else if (namelen <= 0) { |
896 } else if (namelen <= 0) { |
1131 auto_log_print(gettext("Add Drivers: " |
897 auto_log_print(gettext("ai_du_get_pkg_list: " |
1132 "<add_drivers> manifest error:\n" |
898 "<add_drivers> manifest error:\n" |
1133 " no name given for SVR4 package specification\n" |
899 "no name given for SVR4 pkg spec at origin %s, type %s\n"), |
1134 " at origin %s, type %s\n"), origin, type); |
900 origin, type); |
1135 rval = AUTO_INSTALL_FAILURE; |
901 return; |
1136 |
902 |
1137 } else { |
903 } else { |
1138 /* Process each origin/type/name entry. */ |
904 /* Process each origin/type/name entry. */ |
1139 for (k = 0; k < namelen; k++) { |
905 for (k = 0; k < namelen; k++) { |
1140 |
906 |
1141 /* Obj pointed to by pPackageList will be modified. */ |
907 /* Obj pointed to by pPackageList will be modified. */ |
1142 int status = ai_du_process_manual_pkg_names(py_state_p, |
908 ai_du_process_manual_pkg_names(py_state_p, pPackageList, |
1143 path_p, pPackageList, origin, type, names[k]); |
909 path_p, origin, type, names[k]); |
1144 if (status == AUTO_INSTALL_FAILURE) { |
910 } |
1145 rval = AUTO_INSTALL_FAILURE; |
911 |
1146 } |
|
1147 } |
|
1148 } |
912 } |
1149 ai_free_manifest_values(names); |
913 ai_free_manifest_values(names); |
1150 return (rval); |
|
1151 } |
914 } |
1152 |
915 |
1153 /* |
916 /* |
1154 * ai_du_get_manual_pkg_list: |
917 * ai_du_get_manual_pkg_list: |
1155 * Read the AI ai.xml Manifest file and process the <software> tags under the |
918 * Read the AI ai.xml Manifest file and process the <software> under the |
1156 * <add_drivers> section. <software> represents a manual specification of a |
919 * <add_drivers> section. A <software> is a manual specification of a package |
1157 * package to install. Do error checking of the manifest as necessary, as this |
920 * to install. Do error checking of the manifest as necessary, as this function |
1158 * function reads the manifest before it is validated against a schema. |
921 * reads the manifest before it is validated against a schema. |
1159 * |
922 * |
1160 * Validates syntax and processes the following from the manifest: |
923 * Validates syntax and processes the following from the manifest: |
1161 * <add_drivers> |
924 * <add_drivers> |
1162 * <software> |
925 * <software> |
1163 * <source> |
926 * <source> |
1164 * <publisher> |
927 * <publisher> |
1165 * <origin name="location"/> |
928 * <origin name="origin"/> |
1166 * </publisher> |
929 * </publisher> |
1167 * </source> |
930 * </source> |
1168 * <software_data type="type" action="noinstall"> |
931 * <software_data type="type" action="noinstall"> |
1169 * <name>"name"</name> |
932 * <name>"name"</name> |
1170 * </software_data> |
933 * </software_data> |
1172 * </add_drivers> |
935 * </add_drivers> |
1173 * |
936 * |
1174 * type can be "SVR4", "P5I" or "DU". |
937 * type can be "SVR4", "P5I" or "DU". |
1175 * name not allowed if type is "P5I" or "DU" |
938 * name not allowed if type is "P5I" or "DU" |
1176 * |
939 * |
1177 * Always return a list. An empty list can be returned if the manifest shows |
|
1178 * there are no packages to install for Driver Update, or on some errors. |
|
1179 * |
|
1180 * Arguments: |
940 * Arguments: |
1181 * py_state_p: Initialized py_state_t object. |
941 * py_state_p: Initialized py_state_t object. |
1182 * path_p: Used to build nodepath strings for manifest checking. |
942 * path_p: Used to build nodepath strings for manifest checking. |
1183 * |
943 * |
1184 * Returns: |
944 * Returns: |
1185 * AUTO_INSTALL_SUCCESS: A complete python list of (ddu_package_object, |
945 * Success: A python list of (ddu_package_object, third_party_ok, noinstall) |
1186 * third_party_ok, noinstall) tuples suitable for input to |
946 * tuples suitable for input to ai_du_install_packages(). |
1187 * ai_du_install_packages() has been created. |
947 * NOTE: if the manifest shows no packages to install for Driver Update, |
1188 * AUTO_INSTALL_FAILURE: A python list of tuples suitable for input to |
948 * this function will return an empty list. |
1189 * ai_du_install_packages() has been created, but is missing one or more |
949 * Failure: NULL |
1190 * requested packages due to errors. These errors could be manifest |
|
1191 * parsing errors or errors in setting up the packages. |
|
1192 * |
950 * |
1193 * NOTE: check installer logfile for details of the failure. |
951 * NOTE: check installer logfile for details of the failure. |
1194 */ |
952 */ |
1195 static int |
953 static PyObject * |
1196 ai_du_get_manual_pkg_list(py_state_t *py_state_p, path_t *path_p, |
954 ai_du_get_manual_pkg_list(py_state_t *py_state_p, path_t *path_p) |
1197 PyObject **pPackageList_p) |
|
1198 { |
955 { |
|
956 PyObject *pPackageList = NULL; |
1199 char **uniq_origins = NULL; |
957 char **uniq_origins = NULL; |
1200 char **types = NULL; |
958 char **types = NULL; |
1201 int origin_len, typelen; |
959 int origin_len, typelen; |
1202 char **origins; |
960 char **origins; |
1203 char **uniq_types; |
961 char **uniq_types; |
1204 int num_pkgspecs; |
962 int num_pkg_specs; |
1205 int i, j; |
963 int i, j; |
1206 int rval = AUTO_INSTALL_SUCCESS; |
|
1207 |
|
1208 /* |
|
1209 * Initialize a zero-length list. |
|
1210 * This will be returned empty if nothing to install has been found |
|
1211 * or if an error is found early on. |
|
1212 */ |
|
1213 *pPackageList_p = PyList_New(0); |
|
1214 |
964 |
1215 /* Read manifest for specific package requests. */ |
965 /* Read manifest for specific package requests. */ |
1216 |
966 |
1217 /* Get the number of <software> package spec entries. */ |
967 /* Get the number of pkg spec entries. */ |
1218 if (strlcpy(path_p->post_prefix_start, PKGSPEC_NODEPATH, |
968 if (strlcpy(path_p->post_prefix_start, PKGSPEC_NODEPATH, |
1219 path_p->post_prefix_len) > path_p->post_prefix_len) { |
969 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1220 auto_debug_print(AUTO_DBGLVL_ERR, "ai_du_get_manual_pkg_list: " |
970 auto_debug_print(AUTO_DBGLVL_ERR, |
1221 "<software> path buffer overflow\n"); |
971 "ai_du_get_pkg_list: pkg spec path buffer overflow\n"); |
1222 return (AUTO_INSTALL_FAILURE); |
972 return (NULL); |
1223 } |
973 } |
1224 |
974 |
1225 /* Use "origins" like a dummy here. Interest only in num_pkgspecs. */ |
975 /* Use "origins" like a dummy here. Interest only in num_pkg_specs. */ |
1226 origins = ai_get_manifest_values(path_p->path_str, &num_pkgspecs); |
976 origins = ai_get_manifest_values(path_p->path_str, &num_pkg_specs); |
1227 ai_free_manifest_values(origins); |
977 ai_free_manifest_values(origins); |
1228 |
978 |
1229 /* No package specs. Return an empty list. */ |
979 /* No pkg specs. Return an empty list. */ |
1230 if (num_pkgspecs <= 0) { |
980 if (num_pkg_specs <= 0) { |
1231 return (AUTO_INSTALL_SUCCESS); |
981 return (PyList_New(0)); |
1232 } |
982 } |
1233 |
983 |
1234 /* Retrieve a list of all specific package request origins. */ |
984 /* Retrieve a list of all specific package request origins. */ |
1235 if (strlcpy(path_p->post_prefix_start, ORIGIN_NODEPATH, |
985 if (strlcpy(path_p->post_prefix_start, ORIGIN_NODEPATH, |
1236 path_p->post_prefix_len) > path_p->post_prefix_len) { |
986 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1237 auto_debug_print(AUTO_DBGLVL_ERR, |
987 auto_debug_print(AUTO_DBGLVL_ERR, |
1238 "ai_du_get_manual_pkg_list: origin path buffer overflow\n"); |
988 "ai_du_get_pkg_list: origin path buffer overflow\n"); |
1239 return (AUTO_INSTALL_FAILURE); |
989 return (NULL); |
1240 } |
990 } |
1241 |
991 |
1242 /* Get real origins list here for use below. */ |
992 /* Get real origins list here for use below. */ |
1243 origins = ai_get_manifest_values(path_p->path_str, &origin_len); |
993 origins = ai_get_manifest_values(path_p->path_str, &origin_len); |
1244 |
994 |
1245 /* |
995 /* |
1246 * Not a perfect test to validate package specs vs origins in |
996 * Not a perfect test to validate pkg specs and origins in manifest, |
1247 * manifest, but it will do... |
997 * but it will do... |
1248 */ |
998 */ |
1249 if (origin_len != num_pkgspecs) { |
999 if (origin_len != num_pkg_specs) { |
1250 auto_debug_print(AUTO_DBGLVL_ERR, |
1000 auto_debug_print(AUTO_DBGLVL_ERR, |
1251 "ai_du_get_manual_pkg_list: <add_drivers> manifest error:\n" |
1001 "ai_du_get_pkg_list: <add_drivers> manifest error:\n" |
1252 "There is not a 1-1 <origin> - <software> mapping.\n"); |
1002 "There is not a 1-1 origin to pkg spec mapping.\n"); |
1253 ai_free_manifest_values(origins); |
1003 return (NULL); |
1254 return (AUTO_INSTALL_FAILURE); |
|
1255 } |
1004 } |
1256 |
1005 |
1257 uniq_origins = ai_uniq_manifest_values(origins, &origin_len); |
1006 uniq_origins = ai_uniq_manifest_values(origins, &origin_len); |
1258 ai_free_manifest_values(origins); |
1007 ai_free_manifest_values(origins); |
1259 origins = uniq_origins; |
1008 origins = uniq_origins; |
1260 |
1009 |
1261 /* |
1010 /* |
1262 * For each origin (location), get types. Note it is possible for |
1011 * Initialize a zero-length list. |
1263 * there to be more than one type at an origin. There can also be more |
1012 * This will be returned empty if nothing to install has been found. |
1264 * than one item of a given type at an origin. |
1013 */ |
|
1014 pPackageList = PyList_New(0); |
|
1015 |
|
1016 /* |
|
1017 * For each origin, get types. Note it is possible for there to be |
|
1018 * more than one type at a origin. There can also be more than one |
|
1019 * item of a given type at a origin. |
1265 */ |
1020 */ |
1266 for (i = 0; i < origin_len; i++) { |
1021 for (i = 0; i < origin_len; i++) { |
1267 |
1022 |
1268 /* Process "type" entries. */ |
1023 /* Process "type" entries. */ |
1269 |
1024 |
1270 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
1025 if (snprintf(path_p->post_prefix_start, path_p->post_prefix_len, |
1271 TYPE_NODEPATH, origins[i]) >= path_p->post_prefix_len) { |
1026 TYPE_NODEPATH, origins[i]) >= path_p->post_prefix_len) { |
1272 auto_debug_print(AUTO_DBGLVL_ERR, |
1027 auto_debug_print(AUTO_DBGLVL_ERR, |
1273 "ai_du_get_manual_pkg_list: " |
1028 "ai_du_get_pkg_list: " |
1274 "<add_drivers> manifest error:\n" |
1029 "<add_drivers> manifest error:\n" |
1275 "type path buffer overflow for origin %s\n", |
1030 "type path buffer overflow for origin %s\n", |
1276 origins[i]); |
1031 origins[i]); |
1277 rval = AUTO_INSTALL_FAILURE; |
|
1278 continue; |
1032 continue; |
1279 } |
1033 } |
1280 |
1034 |
1281 types = ai_get_manifest_values(path_p->path_str, &typelen); |
1035 types = ai_get_manifest_values(path_p->path_str, &typelen); |
1282 if (typelen <= 0) { |
1036 if (typelen <= 0) { |
1283 auto_log_print(gettext("Add Drivers: " |
1037 auto_log_print(gettext("ai_du_get_pkg_list: " |
1284 "<add_drivers> manifest error:\n" |
1038 "<add_drivers> manifest error:\n" |
1285 "no type given for origin %s\n"), origins[i]); |
1039 "no type given for origin %s\n"), origins[i]); |
1286 rval = AUTO_INSTALL_FAILURE; |
|
1287 continue; |
1040 continue; |
1288 } |
1041 } |
1289 |
1042 |
1290 uniq_types = ai_uniq_manifest_values(types, &typelen); |
1043 uniq_types = ai_uniq_manifest_values(types, &typelen); |
1291 ai_free_manifest_values(types); |
1044 ai_free_manifest_values(types); |
1292 types = uniq_types; |
1045 types = uniq_types; |
1293 |
1046 |
1294 /* Loop for all types found at this origin... */ |
1047 /* Loop for all types found at this origin... */ |
1295 for (j = 0; j < typelen; j++) { |
1048 for (j = 0; j < typelen; j++) { |
1296 |
1049 |
1297 /* Obj *pPackageList_p points to will be modified. */ |
1050 /* Obj pointed to by pPackageList will be modified. */ |
1298 int status = ai_du_process_manual_pkg_types(py_state_p, |
1051 ai_du_process_manual_pkg_types(py_state_p, pPackageList, |
1299 *pPackageList_p, path_p, origins[i], types[j]); |
1052 path_p, origins[i], types[j]); |
1300 if (status == AUTO_INSTALL_FAILURE) { |
1053 } |
1301 rval = AUTO_INSTALL_FAILURE; |
1054 } |
1302 } |
|
1303 } |
|
1304 } |
|
1305 |
|
1306 ai_free_manifest_values(origins); |
1055 ai_free_manifest_values(origins); |
1307 ai_free_manifest_values(types); |
1056 ai_free_manifest_values(types); |
1308 return (rval); |
1057 return (pPackageList); |
1309 } |
1058 } |
1310 |
1059 |
1311 /* |
1060 /* |
1312 * ai_du_get_searched_pkg_list: |
1061 * ai_du_get_searched_pkg_list: |
1313 * Read the AI ai.xml Manifest file and process the <search_all> tag under the |
1062 * Read the AI ai.xml Manifest file and process the <search_all> tag under the |
1314 * <add_drivers> section. Do the needful to scan for missing devices and to |
1063 * <add_drivers> section. Do the needful to scan for missing devices and to |
1315 * perform package searches and installs for missing drivers. Do error |
1064 * perform package searches and installs for missing drivers. Do error |
1316 * checking of the manifest as necessary, as this function reads the manifest |
1065 * checking of the manifest as necessary, as this function reads the manifest |
1317 * before it is validated against a schema. |
1066 * before it is validated against a schema. |
1318 * |
1067 * |
1319 * Always return a list. An empty list can be returned if a search determines |
|
1320 * there are no packages to install for Driver Update (i.e. the system is |
|
1321 * missing no drivers), or on some errors. |
|
1322 * |
|
1323 * Validates syntax and processes the following from the manifest: |
1068 * Validates syntax and processes the following from the manifest: |
1324 * <add_drivers> |
1069 * <add_drivers> |
1325 * <search_all addall="false"> |
1070 * <search_all addall="false"> |
1326 * <source> |
1071 * <source> |
1327 * <publisher name="publisher"> |
1072 * <publisher name="publisher"> |
1328 * <origin name="location"/> |
1073 * <origin name="origin"/> |
1329 * </publisher> |
1074 * </publisher> |
1330 * </source> |
1075 * </source> |
1331 * </search_all> |
1076 * </search_all> |
1332 * </add_drivers> |
1077 * </add_drivers> |
1333 * |
1078 * |
1334 * publisher and origin are both optional, but if one is specified then |
1079 * publisher and origin are both optional, but if one is specified then the |
1335 * the other must also be specified. |
1080 * other must also be specified. |
1336 * |
1081 * addall is optional. Defaults to "false" if not specified. |
1337 * addall is optional. When true, it allows search_all to install third |
|
1338 * party drivers (found via the database in the given pkg(5) repository, |
|
1339 * but installed from somewhere else). Defaults to "false" if not |
|
1340 * specified. |
|
1341 * |
1082 * |
1342 * Arguments: |
1083 * Arguments: |
1343 * py_state_p: Initialized py_state_t object. |
1084 * py_state_p: Initialized py_state_t object. |
1344 * path_p: Used to build nodepath strings for manifest checking. |
1085 * path_p: Used to build nodepath strings for manifest checking. |
1345 * install_root: Root used for determining pkg publisher. |
|
1346 * pPackageList_p: A python list of (ddu_package_object, third_party_ok, |
|
1347 * noinstall) tuples suitable for input to ai_du_install_packages(). |
|
1348 * |
1086 * |
1349 * Returns: |
1087 * Returns: |
1350 * AUTO_INSTALL_SUCCESS: No errors were encountered in retrieving package |
1088 * Success: A python list of (ddu_package_object, third_party_ok, noinstall) |
1351 * information. It is also possible that the system is missing no drivers, |
1089 * tuples suitable for input to ai_du_install_packages(). |
1352 * and an empty list is returned. |
1090 * NOTE: if the system is missing no drivers, this function will return |
1353 * AUTO_INSTALL_PKG_NOT_FND: Packages for one or more missing drivers are not |
1091 * an empty list. |
1354 * available. |
1092 * Failure: NULL |
1355 * AUTO_INSTALL_FAILURE: One or more errors (other than packages which were |
|
1356 * not available) were encountered in retrieving package information. |
|
1357 * |
1093 * |
1358 * NOTE: check installer logfile for details of the failure. |
1094 * NOTE: check installer logfile for details of the failure. |
1359 */ |
1095 */ |
1360 static int |
1096 static PyObject * |
1361 ai_du_get_searched_pkg_list(py_state_t *py_state_p, path_t *path_p, |
1097 ai_du_get_searched_pkg_list(py_state_t *py_state_p, path_t *path_p) |
1362 char *install_root, PyObject **pPackageList_p) |
|
1363 { |
1098 { |
|
1099 PyObject *pPackageList = NULL; |
1364 PyObject *pDeviceList = NULL; |
1100 PyObject *pDeviceList = NULL; |
1365 PyObject *pTuple; |
1101 PyObject *pTuple; |
1366 PyObject *pRepoTupleList; |
1102 PyObject *pRepoTupleList; |
1367 int len, sublen; |
1103 int len, sublen; |
1368 PyObject *pSearchRepoList = NULL; |
1104 PyObject *pSearchRepoList = NULL; |
1371 char **searches = NULL; |
1107 char **searches = NULL; |
1372 char **search_origins = NULL; |
1108 char **search_origins = NULL; |
1373 char **search_pubs = NULL; |
1109 char **search_pubs = NULL; |
1374 char **search_addalls = NULL; |
1110 char **search_addalls = NULL; |
1375 Py_ssize_t i, listlen; |
1111 Py_ssize_t i, listlen; |
1376 int rval = AUTO_INSTALL_FAILURE; |
1112 PyObject *pRval = NULL; |
1377 |
1113 |
1378 *pPackageList_p = PyList_New(0); /* Initialize a zero-length list. */ |
1114 pPackageList = PyList_New(0); /* Initialize a zero-length list. */ |
1379 |
1115 |
1380 /* Read manifest for search requests. */ |
1116 /* Read manifest for search requests. */ |
1381 |
1117 |
1382 if (strlcpy(path_p->post_prefix_start, SEARCH_NODEPATH, |
1118 if (strlcpy(path_p->post_prefix_start, SEARCH_NODEPATH, |
1383 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1119 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1384 auto_debug_print(AUTO_DBGLVL_ERR, |
1120 auto_debug_print(AUTO_DBGLVL_ERR, |
1385 "ai_du_get_searched_pkg_list: " |
1121 "ai_du_get_searched_pkg_list: " |
1386 "search pathname buffer overflow.\n"); |
1122 "search pathname buffer overflow.\n"); |
1387 return (AUTO_INSTALL_FAILURE); |
1123 return (NULL); |
1388 } |
1124 } |
1389 |
1125 |
1390 searches = ai_get_manifest_values(path_p->path_str, &len); |
1126 searches = ai_get_manifest_values(path_p->path_str, &len); |
1391 ai_free_manifest_values(searches); |
1127 ai_free_manifest_values(searches); |
1392 if (len > 1) { |
1128 if (len > 1) { |
1393 auto_log_print(gettext("Add Drivers: " |
1129 auto_log_print(gettext("ai_du_get_searched_pkg_list: " |
1394 "Only one <search_all> entry allowed in manifest\n")); |
1130 "too many <search_all> entries in manifest\n")); |
1395 return (AUTO_INSTALL_FAILURE); |
1131 return (NULL); |
1396 } |
1132 |
1397 |
1133 } else if (len <= 0) { |
1398 if (len <= 0) { |
1134 return (pPackageList); |
1399 return (AUTO_INSTALL_SUCCESS); |
1135 } |
1400 } |
1136 |
1401 |
1137 auto_log_print(gettext("ai_du_get_searched_pkg_list: Doing a device " |
1402 auto_log_print(gettext("Add Drivers: Doing a device " |
|
1403 "scan for devices which are missing drivers...\n")); |
1138 "scan for devices which are missing drivers...\n")); |
1404 |
1139 |
1405 /* |
1140 /* |
1406 * Call ddu_devscan() to do search if requested. |
1141 * Call ddu_devscan() to do search if requested. |
1407 * The boolean value is to scan only for missing drivers. |
1142 * The boolean value is to scan only for missing drivers. |
1408 */ |
1143 */ |
1409 pDeviceList = ai_call_ddu_devscan(py_state_p, B_TRUE, "all"); |
1144 pDeviceList = ai_call_ddu_devscan(py_state_p, B_TRUE, "all"); |
1410 if (pDeviceList == NULL) { |
1145 if (pDeviceList == NULL) { |
1411 auto_debug_print(AUTO_DBGLVL_ERR, |
1146 auto_debug_print(AUTO_DBGLVL_ERR, |
1412 "ai_du_get_searched_pkg_list: " |
1147 "ai_du_get_searched_pkg_list: " |
1413 "Error scanning for missing drivers.\n"); |
1148 "Error scanning for missing devices.\n"); |
1414 return (AUTO_INSTALL_FAILURE); |
1149 return (NULL); |
1415 |
1150 |
1416 /* An empty list is perfectly acceptable here. No missing drivers. */ |
1151 /* An empty list is perfectly acceptable here. No missing drivers. */ |
1417 } else if (PyList_Size(pDeviceList) == 0) { |
1152 } else if (PyList_Size(pDeviceList) == 0) { |
1418 auto_debug_print(AUTO_DBGLVL_ERR, |
1153 return (pPackageList); |
1419 "ai_du_get_searched_pkg_list: No missing drivers found.\n"); |
1154 } |
1420 return (AUTO_INSTALL_SUCCESS); |
1155 |
1421 } |
1156 /* Get repo origin, if specified. */ |
1422 |
|
1423 /* Get repo location, if specified. */ |
|
1424 |
1157 |
1425 if (strlcpy(path_p->post_prefix_start, SEARCH_ORIGIN_NODEPATH, |
1158 if (strlcpy(path_p->post_prefix_start, SEARCH_ORIGIN_NODEPATH, |
1426 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1159 path_p->post_prefix_len) > path_p->post_prefix_len) { |
1427 auto_debug_print(AUTO_DBGLVL_ERR, |
1160 auto_debug_print(AUTO_DBGLVL_ERR, |
1428 "ai_du_get_searched_pkg_list: search repo origin path " |
1161 "ai_du_get_searched_pkg_list: search repo origin path " |
1429 "buffer overflow.\n"); |
1162 "buffer overflow.\n"); |
1430 return (AUTO_INSTALL_FAILURE); |
1163 return (NULL); |
1431 } |
1164 } |
1432 |
1165 |
1433 auto_log_print(gettext("Add Drivers: Querying manifest " |
1166 auto_log_print(gettext("ai_du_get_searched_pkg_list: Querying manifest " |
1434 "for explicit repo for getting missing driver packages...\n")); |
1167 "for explicit repo for getting missing driver packages...\n")); |
1435 |
1168 |
1436 search_origins = ai_get_manifest_values(path_p->path_str, &sublen); |
1169 search_origins = ai_get_manifest_values(path_p->path_str, &sublen); |
1437 if (sublen == 1) { |
1170 if (sublen == 1) { |
1438 search_origin = search_origins[0]; |
1171 search_origin = search_origins[0]; |
1439 } else if (sublen <= 0) { |
1172 } else if (sublen <= 0) { |
1440 search_origin = empty_string; |
1173 search_origin = empty_string; |
1441 } else { |
1174 } else { |
1442 auto_log_print(gettext("Add Drivers: " |
1175 auto_log_print(gettext("ai_du_get_searched_pkg_list: " |
1443 "<add_drivers> manifest error:\n" |
1176 "<add_drivers> manifest error:\n" |
1444 "Only one origin allowed per <search_all> entry.\n")); |
1177 "Only one origin allowed per <search_all> entry.\n")); |
1445 goto done; |
1178 goto done; |
1446 } |
1179 } |
1447 |
1180 |
1548 search_addalls = ai_get_manifest_values(path_p->path_str, &sublen); |
1260 search_addalls = ai_get_manifest_values(path_p->path_str, &sublen); |
1549 if ((sublen > 1) || |
1261 if ((sublen > 1) || |
1550 ((sublen == 1) && |
1262 ((sublen == 1) && |
1551 ((strcmp(search_addalls[0], "true") != 0) && |
1263 ((strcmp(search_addalls[0], "true") != 0) && |
1552 (strcmp(search_addalls[0], "false") != 0)))) { |
1264 (strcmp(search_addalls[0], "false") != 0)))) { |
1553 auto_log_print(gettext("Add Drivers: " |
1265 auto_log_print(gettext("ai_du_get_searched_pkg_list: " |
1554 "<add_drivers> manifest error:\n" |
1266 "<add_drivers> manifest error:\n" |
1555 "invalid addall value for <search_all> entry\n")); |
1267 "invalid addall value for <search_all> entry\n")); |
1556 goto done; |
1268 goto done; |
1557 |
1269 |
1558 /* Default to false if not provided. */ |
1270 /* Default to false if not provided. */ |
1559 } else if ((sublen <= 0) || (strcmp(search_addalls[0], "false") == 0)) { |
1271 } else if ((sublen <= 0) || (strcmp(search_addalls[0], "false") == 0)) { |
1560 Py_INCREF(Py_False); |
1272 Py_INCREF(Py_False); |
1561 py_search_addall = Py_False; |
1273 py_search_addall = Py_False; |
1562 |
1274 |
1563 } else { |
1275 } else { |
1564 auto_log_print(gettext("Add Drivers: Manifest " |
1276 auto_log_print(gettext("ai_du_get_searched_pkg_list: Manifest " |
1565 "allows adding of third-party drivers\n")); |
1277 "allows adding of third-party drivers\n")); |
1566 Py_INCREF(Py_True); |
1278 Py_INCREF(Py_True); |
1567 py_search_addall = Py_True; |
1279 py_search_addall = Py_True; |
1568 } |
1280 } |
1569 |
1281 |
1570 /* |
1282 /* |
1571 * Append packages found for missing devices, to the list of packages |
1283 * Append packages found for missing devices, to the list of packages |
1572 * to install. |
1284 * to install. |
1573 */ |
1285 */ |
1574 rval = AUTO_INSTALL_SUCCESS; |
|
1575 listlen = PyList_Size(pDeviceList); |
1286 listlen = PyList_Size(pDeviceList); |
1576 for (i = 0; i < listlen; i++) { |
1287 for (i = 0; i < listlen; i++) { |
1577 |
1288 |
1578 PyObject *pDDUPackageObject; |
1289 PyObject *pDDUPackageObject; |
1579 PyObject *pDDUDevData; |
1290 PyObject *pDDUDevData; |
1580 char *dev_type; |
1291 char *dev_type; |
1581 char *descr; |
1292 char *descr; |
1582 int lookup_err; |
|
1583 boolean_t third_party = B_FALSE; |
1293 boolean_t third_party = B_FALSE; |
1584 |
1294 |
1585 pDDUDevData = PyList_GetItem(pDeviceList, i); |
1295 pDDUDevData = PyList_GetItem(pDeviceList, i); |
1586 |
1296 |
1587 /* Find the package containing the driver for this device. */ |
1297 /* Find the package containing the driver for this device. */ |
1588 lookup_err = ai_call_ddu_package_lookup(py_state_p, |
1298 pDDUPackageObject = ai_call_ddu_package_lookup(py_state_p, |
1589 pDDUDevData, pSearchRepoList, &pDDUPackageObject); |
1299 pDDUDevData, pSearchRepoList); |
1590 |
1300 |
1591 /* Get info for display / logging purposes, and log it. */ |
1301 /* Get info for display / logging purposes, and log it. */ |
1592 if (ai_get_ddu_dev_data_values(pDDUDevData, &dev_type, &descr, |
1302 if (ai_get_ddu_dev_data_values(pDDUDevData, |
1593 NULL, NULL, NULL) != AUTO_INSTALL_SUCCESS) { |
1303 &dev_type, &descr) != AUTO_INSTALL_SUCCESS) { |
1594 auto_debug_print(AUTO_DBGLVL_ERR, |
1304 auto_debug_print(AUTO_DBGLVL_ERR, |
1595 "ai_du_get_searched_pkg_list: Error retrieving " |
1305 "ai_du_get_searched_pkg_list: Error retrieving " |
1596 "device information for display\n"); |
1306 "device information for display\n"); |
1597 dev_type = descr = empty_string; |
1307 dev_type = descr = empty_string; |
1598 } |
1308 } |
1599 |
1309 |
1600 /* Package not found is not considered an error. */ |
1310 if (pDDUPackageObject == NULL) { |
1601 if (lookup_err == AUTO_INSTALL_PKG_NOT_FND) { |
1311 auto_log_print(gettext("ai_du_get_searched_pkg_list: " |
1602 auto_log_print(gettext("Add Drivers: " |
|
1603 "Warning: Search found no package for " |
|
1604 "\"%s\" type device \"%s\".\n"), dev_type, descr); |
|
1605 /* |
|
1606 * Set marginal success status. |
|
1607 * Don't override failure status. |
|
1608 */ |
|
1609 if (rval == AUTO_INSTALL_SUCCESS) { |
|
1610 rval = AUTO_INSTALL_PKG_NOT_FND; |
|
1611 } |
|
1612 continue; |
|
1613 } else if (lookup_err != AUTO_INSTALL_SUCCESS) { |
|
1614 auto_log_print(gettext("Add Drivers: " |
|
1615 "Error retrieving package for " |
1312 "Error retrieving package for " |
1616 "\"%s\" type device \"%s\".\n"), dev_type, descr); |
1313 "\"%s\" type device \"%s\".\n"), dev_type, descr); |
1617 rval = AUTO_INSTALL_FAILURE; |
|
1618 continue; |
1314 continue; |
1619 } else { |
1315 } else { |
1620 auto_log_print(gettext("Add Drivers: " |
1316 auto_log_print(gettext("ai_du_get_searched_pkg_list: " |
1621 "DDU returned package info for " |
1317 "DDU returned package info for " |
1622 "\"%s\" type device \"%s\".\n"), dev_type, descr); |
1318 "\"%s\" type device \"%s\".\n"), dev_type, descr); |
1623 } |
1319 } |
1624 |
1320 |
1625 (void) ai_get_ddu_package_object_values(pDDUPackageObject, |
1321 (void) ai_get_ddu_package_object_values(pDDUPackageObject, |
1634 /* |
1330 /* |
1635 * NOTE: Don't decref pTuple here as PyList_Append doesn't |
1331 * NOTE: Don't decref pTuple here as PyList_Append doesn't |
1636 * steal a reference to it. |
1332 * steal a reference to it. |
1637 */ |
1333 */ |
1638 pTuple = PyTuple_New(3); |
1334 pTuple = PyTuple_New(3); |
1639 (void) PyTuple_SetItem(pTuple, 0, pDDUPackageObject); |
1335 PyTuple_SetItem(pTuple, 0, pDDUPackageObject); |
1640 Py_INCREF(py_search_addall); /* 3rd party OK */ |
1336 Py_INCREF(py_search_addall); |
1641 (void) PyTuple_SetItem(pTuple, 1, py_search_addall); |
1337 PyTuple_SetItem(pTuple, 1, py_search_addall); /* 3rd party OK */ |
1642 Py_INCREF(Py_False); /* always install */ |
1338 Py_INCREF(Py_False); |
1643 (void) PyTuple_SetItem(pTuple, 2, Py_False); |
1339 PyTuple_SetItem(pTuple, 2, Py_False); /* always install */ |
1644 (void) PyList_Append(*pPackageList_p, pTuple); |
1340 |
1645 } |
1341 PyList_Append(pPackageList, pTuple); |
|
1342 } |
|
1343 |
|
1344 /* Success. Prepare to return the package list just prepared. */ |
|
1345 pRval = pPackageList; |
|
1346 |
1646 done: |
1347 done: |
1647 /* Cleanup time, whether an error occured or not. */ |
1348 /* Cleanup time, whether an error occured or not. */ |
1648 ai_free_manifest_values(search_origins); |
1349 ai_free_manifest_values(search_origins); |
1649 ai_free_manifest_values(search_pubs); |
1350 ai_free_manifest_values(search_pubs); |
1650 Py_XDECREF(py_search_addall); |
1351 Py_XDECREF(py_search_addall); |
1651 Py_XDECREF(pSearchRepoList); |
1352 Py_XDECREF(pSearchRepoList); |
1652 Py_XDECREF(pDeviceList); |
1353 Py_XDECREF(pDeviceList); |
1653 return (rval); |
1354 return (pRval); |
1654 } |
1355 } |
1655 |
1356 |
1656 /* |
1357 /* |
1657 * ai_du_install_packages: |
1358 * ai_du_install_packages: |
1658 * Install packages provided by the pPkgTupleList. Install in the filesystem / |
1359 * Install packages provided by the pPkgTupleList. Install in the filesystem / |
1659 * tree under install_root, skipping packages with noinstall flag set if |
1360 * tree under install_root, skipping packages with noinstall flag set if |
1660 * honor_noinstall is set. |
1361 * honor_noinstall is set. |
1661 * |
|
1662 * NOTE: it is assumed that the DDU library returns successful status when |
|
1663 * attempting to install a package which is already installed. |
|
1664 * |
1362 * |
1665 * Arguments: |
1363 * Arguments: |
1666 * py_state_p: Initialized py_state_t object. |
1364 * py_state_p: Initialized py_state_t object. |
1667 * pPkgTupleList: Python list of (ddu_package_object, third_party_ok, |
1365 * pPkgTupleList: Python list of (ddu_package_object, third_party_ok, |
1668 * noinstall) tuples which define packages to add and their parameters for |
1366 * noinstall) tuples which define packages to add and their parameters for |
1703 |
1401 |
1704 PyObject *pTuple = PyList_GetItem(pPkgTupleList, i); |
1402 PyObject *pTuple = PyList_GetItem(pPkgTupleList, i); |
1705 PyObject *pDDUPackageObject = PyTuple_GetItem(pTuple, 0); |
1403 PyObject *pDDUPackageObject = PyTuple_GetItem(pTuple, 0); |
1706 PyObject *pThirdPartyOK = PyTuple_GetItem(pTuple, 1); |
1404 PyObject *pThirdPartyOK = PyTuple_GetItem(pTuple, 1); |
1707 PyObject *pNoInstall = PyTuple_GetItem(pTuple, 2); |
1405 PyObject *pNoInstall = PyTuple_GetItem(pTuple, 2); |
1708 char *type, *location, *name, *descr, *inf_link; |
1406 char *type = empty_string; |
|
1407 char *origin = empty_string; |
|
1408 char *name = empty_string; |
|
1409 char *descr = empty_string; |
|
1410 char *inf_link = empty_string; |
1709 boolean_t third_party; |
1411 boolean_t third_party; |
1710 |
1412 |
1711 if (ai_get_ddu_package_object_values(pDDUPackageObject, |
1413 if (ai_get_ddu_package_object_values(pDDUPackageObject, |
1712 &type, &location, &name, &descr, &inf_link, &third_party) != |
1414 &type, &origin, &name, &descr, &inf_link, &third_party) != |
1713 AUTO_INSTALL_SUCCESS) { |
1415 AUTO_INSTALL_SUCCESS) { |
1714 auto_debug_print(AUTO_DBGLVL_ERR, |
1416 auto_debug_print(AUTO_DBGLVL_ERR, |
1715 "ai_du_install_packages: Error extracting package " |
1417 "ai_du_install_packages: Error extracting package " |
1716 "information for ddu_package_object.\n"); |
1418 "information for ddu_package_object.\n"); |
1717 type = location = name = descr = inf_link = |
1419 type = origin = name = descr = inf_link = |
1718 empty_string; |
1420 empty_string; |
1719 third_party = B_FALSE; |
1421 third_party = B_FALSE; |
1720 } else { |
1422 } else { |
1721 if (strcmp(name, empty_string) == 0) { |
1423 if (strcmp(name, empty_string) == 0) { |
1722 auto_log_print(gettext( |
1424 auto_log_print(gettext( |
1723 " %s package at origin:%s\n"), |
1425 " %s package at origin:%s\n"), |
1724 type, location); |
1426 type, origin); |
1725 } else { |
1427 } else { |
1726 auto_log_print(gettext( |
1428 auto_log_print(gettext( |
1727 " %s package at origin:%s, name:%s\n"), |
1429 " %s package at origin:%s, name:%s\n"), |
1728 type, location, name); |
1430 type, origin, name); |
1729 } |
1431 } |
1730 } |
1432 } |
1731 |
1433 |
1732 if (PyObject_IsTrue(pNoInstall) && honor_noinstall) { |
1434 if (PyObject_IsTrue(pNoInstall) && honor_noinstall) { |
1733 auto_log_print(gettext("Add Drivers: " |
1435 auto_log_print(gettext("ai_du_install_packages: " |
1734 " honoring noinstall: skipping package.\n")); |
1436 " honoring noinstall: skipping package.\n")); |
1735 continue; |
1437 continue; |
1736 } |
1438 } |
1737 |
1439 |
1738 /* Display any third-party package errors to console. */ |
1440 /* Display any third-party package errors to console. */ |
1915 * |
1616 * |
1916 * Install all explicitly-stated packages first. Then do <search_all> last. |
1617 * Install all explicitly-stated packages first. Then do <search_all> last. |
1917 * This is to handle any explicit requests for matching a special driver to a |
1618 * This is to handle any explicit requests for matching a special driver to a |
1918 * device, before <search_all> finds the first available one. |
1619 * device, before <search_all> finds the first available one. |
1919 * |
1620 * |
1920 * If search determines that a driver is missing and cannot find a package for |
|
1921 * it, this is not reported as an error. A ddu_package_object is not created in |
|
1922 * this case, so no installation or package fetch is done for this driver. Any |
|
1923 * other kind of problem which occurs around searched packages, during the |
|
1924 * search itself or during an installation of a package found during search, is |
|
1925 * reported as an error. |
|
1926 * |
|
1927 * Any issue found around explicitly specified packages (<software>s), whether |
|
1928 * it be that the package is not found or there was an issue during |
|
1929 * installation, is reported as an error. ddu_package_objects are always |
|
1930 * created for these packages. |
|
1931 * |
|
1932 * Assumes ai_create_manifest_image() has set up the manifest data. |
1621 * Assumes ai_create_manifest_image() has set up the manifest data. |
1933 * Does not assume any data has been verified though. |
1622 * Does not assume any data has been verified though. |
1934 * |
1623 * |
1935 * Arguments: |
1624 * Arguments: |
1936 * install_root: Top of the filesystem or tree where the packages are to be |
1625 * install_root: Top of the filesystem or tree where the packages are to be |
1937 * installed. |
1626 * installed. |
1938 * honor_noinstall: When true and the noinstall flag is set in a package |
1627 * honor_noinstall: When true and the noinstall flag is set in a package |
1939 * tuple, skip installing that package. |
1628 * tuple, skip installing that package. |
1940 * update_boot_archive: When true, run the ICT to update the boot archive. |
1629 * update_boot_archive: When true, run the ICT to update the boot archive. |
1941 * num_pkgs_installed_p: Returns the number of packages installed. |
|
1942 * |
1630 * |
1943 * Returns: |
1631 * Returns: |
1944 * AUTO_INSTALL_SUCCESS: No errors found. |
1632 * The number of packages successfully processed if all are successfully |
1945 * AUTO_INSTALL_PKG_NOT_FND: At least one needed package found during search |
1633 * processed. NOTE: this can be zero if there are none to process. |
1946 * could not be found. No other errors encountered. |
1634 * -1: One or more packages could not be successfully processed. |
1947 * AUTO_INSTALL_FAILURE: An error was encountered and was different than |
|
1948 * not being able to find a package for a missing driver. |
|
1949 * |
|
1950 * Boot archive update status is not reflected in this return status. |
1635 * Boot archive update status is not reflected in this return status. |
1951 * NOTE: this routine will continue on most errors, in order to install as |
1636 * NOTE: this routine will continue on most errors, in order to install as |
1952 * many packages as possible. |
1637 * many packages as possible. |
1953 * |
1638 * |
1954 * NOTE: return status and num_pkgs_installed together tell the caller the full |
|
1955 * story. It is possible, for example, that no packages were installed because |
|
1956 * one package flagged during search could not be found. |
|
1957 * |
|
1958 * NOTE: check installer logfile for details of the failure. |
1639 * NOTE: check installer logfile for details of the failure. |
1959 * |
1640 * |
1960 * Side effects: |
1641 * Side effects: |
1961 * module global py_pkg_list is set to point to list of packages to install. |
1642 * module global py_pkg_list is set to point to list of packages to install. |
1962 */ |
1643 */ |
1963 int |
1644 int |
1964 ai_du_get_and_install(char *install_root, boolean_t honor_noinstall, |
1645 ai_du_get_and_install(char *install_root, boolean_t honor_noinstall, |
1965 boolean_t update_boot_archive, int *num_installed_pkgs_p) |
1646 boolean_t update_boot_archive) |
1966 { |
1647 { |
1967 PyObject *manual_pkg_list; |
1648 PyObject *manual_pkg_list; |
1968 PyObject *searched_pkg_list; |
1649 PyObject *searched_pkg_list; |
1969 py_state_t *py_state_p; |
1650 py_state_t *py_state_p; |
1970 path_t path; |
1651 path_t path; |
1971 char **dummy_list; |
1652 char **dummy_list; |
1972 int num_entries; |
1653 int num_entries; |
1973 int len; |
1654 int len; |
1974 Py_ssize_t manual_size = 0; |
1655 Py_ssize_t manual_size = 0; |
1975 Py_ssize_t searched_size = 0; |
1656 Py_ssize_t searched_size = 0; |
1976 int rval = AUTO_INSTALL_SUCCESS; |
1657 int rval = 0; |
1977 |
1658 int num_pkgs_installed = 0; |
1978 *num_installed_pkgs_p = 0; |
|
1979 |
1659 |
1980 /* Initialize path, post_prefix_start and post_prefix_len for later. */ |
1660 /* Initialize path, post_prefix_start and post_prefix_len for later. */ |
1981 (void) strncpy(path.path_str, AIM_PREFACE, MAX_NODEPATH_SIZE); |
1661 (void) strncpy(path.path_str, AIM_PREFACE, MAX_NODEPATH_SIZE); |
1982 len = strlen(path.path_str); |
1662 len = strlen(path.path_str); |
1983 path.post_prefix_start = &path.path_str[len]; |
1663 path.post_prefix_start = &path.path_str[len]; |
1992 } |
1672 } |
1993 |
1673 |
1994 py_pkg_list = PyList_New(0); |
1674 py_pkg_list = PyList_New(0); |
1995 |
1675 |
1996 /* |
1676 /* |
1997 * See if the manifest has at least one <software> or search_all entry. |
1677 * See if the manifest has at least one pkg spec or searchall entry. |
1998 * If not, just return success (e.g. no-op). |
1678 * If not, just return success (e.g. no-op). |
1999 */ |
1679 */ |
2000 |
1680 |
2001 /* Get the number of <software> entries. */ |
1681 /* Get the number of pkg spec entries. */ |
2002 if (strlcpy(path.post_prefix_start, PKGSPEC_NODEPATH, |
1682 if (strlcpy(path.post_prefix_start, PKGSPEC_NODEPATH, |
2003 path.post_prefix_len) > path.post_prefix_len) { |
1683 path.post_prefix_len) > path.post_prefix_len) { |
2004 auto_debug_print(AUTO_DBGLVL_ERR, |
1684 auto_debug_print(AUTO_DBGLVL_ERR, |
2005 "ai_du_get_and_install: <software> path buffer overflow\n"); |
1685 "ai_du_get_and_install: pkg spec path buffer overflow\n"); |
2006 return (AUTO_INSTALL_FAILURE); |
1686 return (-1); |
2007 } |
1687 } |
2008 |
1688 |
2009 /* Get number of <software> entries in the manifest. */ |
1689 /* Get number of pkg spec entries in the manifest. */ |
2010 dummy_list = ai_get_manifest_values(path.path_str, &num_entries); |
1690 dummy_list = ai_get_manifest_values(path.path_str, &num_entries); |
2011 ai_free_manifest_values(dummy_list); |
1691 ai_free_manifest_values(dummy_list); |
2012 |
1692 |
2013 if (num_entries <= 0) { |
1693 if (num_entries <= 0) { |
2014 /* See if there is a search_all entry in the manifest. */ |
1694 /* See if there is a searchall entry in the manifest. */ |
2015 if (strlcpy(path.post_prefix_start, SEARCH_NODEPATH, |
1695 if (strlcpy(path.post_prefix_start, SEARCH_NODEPATH, |
2016 path.post_prefix_len) > path.post_prefix_len) { |
1696 path.post_prefix_len) > path.post_prefix_len) { |
2017 auto_debug_print(AUTO_DBGLVL_ERR, |
1697 auto_debug_print(AUTO_DBGLVL_ERR, |
2018 "ai_du_get_and_install: " |
1698 "ai_du_get_and_install: " |
2019 "search path buffer overflow\n"); |
1699 "search path buffer overflow\n"); |
2020 return (AUTO_INSTALL_FAILURE); |
1700 return (-1); |
2021 } |
1701 } |
2022 |
1702 |
2023 dummy_list = ai_get_manifest_values(path.path_str, |
1703 dummy_list = ai_get_manifest_values(path.path_str, |
2024 &num_entries); |
1704 &num_entries); |
2025 ai_free_manifest_values(dummy_list); |
1705 ai_free_manifest_values(dummy_list); |
2026 if (num_entries <= 0) { |
1706 if (num_entries <= 0) { |
2027 return (AUTO_INSTALL_SUCCESS); |
1707 return (0); |
2028 } |
1708 } |
2029 } |
1709 } |
2030 |
1710 |
2031 /* |
1711 /* |
2032 * Install all explicitly specified packages first. |
1712 * Install all explicitly specified packages first. |
2038 |
1718 |
2039 if ((py_state_p = auto_ddu_lib_init()) == NULL) { |
1719 if ((py_state_p = auto_ddu_lib_init()) == NULL) { |
2040 auto_debug_print(AUTO_DBGLVL_ERR, |
1720 auto_debug_print(AUTO_DBGLVL_ERR, |
2041 "ai_du_get_and_install: " |
1721 "ai_du_get_and_install: " |
2042 "Error initializing auto_ddu_lib.\n"); |
1722 "Error initializing auto_ddu_lib.\n"); |
2043 rval = AUTO_INSTALL_FAILURE; |
1723 rval = -1; |
2044 goto done; |
1724 goto done; |
2045 } |
1725 } |
2046 |
1726 |
2047 if (ai_du_get_manual_pkg_list(py_state_p, &path, |
1727 manual_pkg_list = ai_du_get_manual_pkg_list(py_state_p, &path); |
2048 &manual_pkg_list) != AUTO_INSTALL_SUCCESS) { |
1728 if (manual_pkg_list == NULL) { |
2049 auto_debug_print(AUTO_DBGLVL_ERR, |
1729 auto_debug_print(AUTO_DBGLVL_ERR, |
2050 "ai_du_get_and_install: " |
1730 "ai_du_get_and_install: " |
2051 "Error getting <software> package specification.\n"); |
1731 "Error getting package specification.\n"); |
2052 rval = AUTO_INSTALL_FAILURE; |
1732 rval = -1; |
2053 /* Keep going. Don't abort. */ |
1733 /* Keep going. Don't abort. */ |
2054 } |
1734 } else { |
2055 |
1735 manual_size = PyList_Size(manual_pkg_list); |
2056 manual_size = PyList_Size(manual_pkg_list); |
1736 if (manual_size > 0) { |
2057 if (manual_size > 0) { |
1737 if (ai_du_install_packages(py_state_p, manual_pkg_list, |
2058 if (ai_du_install_packages(py_state_p, manual_pkg_list, |
1738 install_root, honor_noinstall, |
2059 install_root, honor_noinstall, num_installed_pkgs_p) != |
1739 &num_pkgs_installed) != AUTO_INSTALL_SUCCESS) { |
2060 AUTO_INSTALL_SUCCESS) { |
1740 auto_debug_print(AUTO_DBGLVL_ERR, |
2061 auto_debug_print(AUTO_DBGLVL_ERR, |
1741 "ai_du_get_and_install: Error installing " |
2062 "ai_du_get_and_install: Error installing at least " |
1742 "at least one package.\n"); |
2063 "one <software> package specification.\n"); |
1743 rval = -1; |
2064 rval = AUTO_INSTALL_FAILURE; |
1744 /* Keep going. Don't abort. */ |
2065 /* Keep going. Don't abort. */ |
1745 } |
2066 } |
1746 } |
2067 } |
1747 } |
2068 |
1748 |
2069 switch (ai_du_get_searched_pkg_list(py_state_p, &path, install_root, |
1749 searched_pkg_list = ai_du_get_searched_pkg_list(py_state_p, &path); |
2070 &searched_pkg_list)) { |
1750 if (searched_pkg_list == NULL) { |
2071 case AUTO_INSTALL_FAILURE: |
|
2072 rval = AUTO_INSTALL_FAILURE; |
|
2073 auto_debug_print(AUTO_DBGLVL_ERR, |
1751 auto_debug_print(AUTO_DBGLVL_ERR, |
2074 "ai_du_get_and_install: " |
1752 "ai_du_get_and_install: " |
2075 "Error searching for inoperable devices and " |
1753 "Error searching for inoperable devices and " |
2076 "missing driver packages.\n"); |
1754 "missing driver packages.\n"); |
|
1755 rval = -1; |
2077 /* Keep going. Don't abort. */ |
1756 /* Keep going. Don't abort. */ |
2078 break; |
1757 } else { |
2079 case AUTO_INSTALL_PKG_NOT_FND: |
1758 searched_size = PyList_Size(searched_pkg_list); |
2080 if (rval != AUTO_INSTALL_FAILURE) { |
1759 if (searched_size > 0) { |
2081 rval = AUTO_INSTALL_PKG_NOT_FND; |
1760 if (ai_du_install_packages(py_state_p, |
2082 } |
1761 searched_pkg_list, install_root, honor_noinstall, |
2083 break; |
1762 &num_pkgs_installed) != AUTO_INSTALL_SUCCESS) { |
2084 default: |
1763 auto_debug_print(AUTO_DBGLVL_ERR, |
2085 break; |
1764 "ai_du_get_and_install: Error installing " |
2086 } |
1765 "at least one searched package " |
2087 |
1766 "for <search_all>.\n"); |
2088 searched_size = PyList_Size(searched_pkg_list); |
1767 rval = -1; |
2089 if (searched_size > 0) { |
1768 /* Keep going. Don't abort. */ |
2090 if (ai_du_install_packages(py_state_p, searched_pkg_list, |
1769 } |
2091 install_root, honor_noinstall, num_installed_pkgs_p) != |
1770 } |
2092 AUTO_INSTALL_SUCCESS) { |
1771 } |
2093 auto_debug_print(AUTO_DBGLVL_ERR, |
1772 |
2094 "ai_du_get_and_install: Error installing at least " |
1773 if ((update_boot_archive) && (num_pkgs_installed > 0)) { |
2095 "one searched package for <search_all>.\n"); |
|
2096 rval = AUTO_INSTALL_FAILURE; |
|
2097 /* Keep going. Don't abort. */ |
|
2098 } |
|
2099 } |
|
2100 |
|
2101 if (update_boot_archive && (*num_installed_pkgs_p > 0)) { |
|
2102 if (ai_du_call_update_archive_ict(py_state_p, install_root) != |
1774 if (ai_du_call_update_archive_ict(py_state_p, install_root) != |
2103 AUTO_INSTALL_SUCCESS) { |
1775 AUTO_INSTALL_SUCCESS) { |
2104 auto_debug_print(AUTO_DBGLVL_ERR, |
1776 auto_debug_print(AUTO_DBGLVL_ERR, |
2105 "ai_du_get_and_install: Warning: could not update " |
1777 "ai_du_get_and_install: Warning: could not update " |
2106 "boot archive for %s.\n", install_root); |
1778 "boot archive for %s.\n", install_root); |
2139 * honor_noinstall argument is set, skip adding that package. |
1811 * honor_noinstall argument is set, skip adding that package. |
2140 * |
1812 * |
2141 * This routine assumes the py_pkg_list was set up via a prior call to |
1813 * This routine assumes the py_pkg_list was set up via a prior call to |
2142 * ai_du_get_and_install_packages(). |
1814 * ai_du_get_and_install_packages(). |
2143 * |
1815 * |
2144 * The availability and origin (location) of all packages to be installed is |
1816 * The availability and origin of all packages to be installed is assumed the |
2145 * assumed the same as when the py_pkg_list was built (i.e. the most recent |
1817 * same as when the py_pkg_list was built (i.e. the most recent call to |
2146 * call to ai_du_get_and_install()). |
1818 * ai_du_get_and_install()). |
2147 * |
1819 * |
2148 * Arguments: |
1820 * Arguments: |
2149 * install_root: Top of the filesystem or tree where the packages are to be |
1821 * install_root: Top of the filesystem or tree where the packages are to be |
2150 * installed. |
1822 * installed. |
2151 * honor_noinstall: When true and the noinstall flag is set in a package |
1823 * honor_noinstall: When true and the noinstall flag is set in a package |
2152 * tuple, skip installing that package. |
1824 * tuple, skip installing that package. |
2153 * update_boot_archive: When true, run the ICT to update the boot archive. |
1825 * update_boot_archive: When true, run the ICT to update the boot archive. |
2154 * num_installed_pkgs_p: Returns the number of packages successfully |
|
2155 * installed. |
|
2156 * NOTE: the modular global py_pkg_list specifies the packages to install. |
1826 * NOTE: the modular global py_pkg_list specifies the packages to install. |
2157 * |
1827 * |
2158 * Returns: |
1828 * Returns: |
2159 * AUTO_INSTALL_SUCCESS: No errors found and at least one package was |
1829 * The number of packages successfully processed if all are successfully |
2160 * installed. |
1830 * processed. NOTE: this can be zero if there are none to process. |
2161 * AUTO_INSTALL_FAILURE: An error was encountered. Some packages may have |
1831 * -1: At least one package was not able to be installed. |
2162 * been installed. |
|
2163 * |
|
2164 * Boot archive update status is not reflected in this return status. |
1832 * Boot archive update status is not reflected in this return status. |
2165 * NOTE: this routine will continue on most errors, in order to install as |
|
2166 * many packages as possible. |
|
2167 * |
|
2168 * NOTE: return status and num_pkgs_installed together tell the caller the full |
|
2169 * story. It is possible, for example, that no packages were installed because |
|
2170 * one package flagged during search could not be found. |
|
2171 * |
1833 * |
2172 * NOTE: check installer logfile for details of the failure. |
1834 * NOTE: check installer logfile for details of the failure. |
2173 */ |
1835 */ |
2174 int |
1836 int |
2175 ai_du_install(char *install_root, boolean_t honor_noinstall, |
1837 ai_du_install(char *install_root, boolean_t honor_noinstall, |
2176 boolean_t update_boot_archive, int *num_installed_pkgs_p) |
1838 boolean_t update_boot_archive) |
2177 { |
1839 { |
2178 int rval = AUTO_INSTALL_SUCCESS; |
1840 int rval = 0; |
|
1841 int num_pkgs_installed = 0; |
2179 |
1842 |
2180 py_state_t *py_state_p; |
1843 py_state_t *py_state_p; |
2181 |
|
2182 *num_installed_pkgs_p = 0; |
|
2183 |
1844 |
2184 if (py_pkg_list == NULL) { |
1845 if (py_pkg_list == NULL) { |
2185 auto_debug_print(AUTO_DBGLVL_ERR, |
1846 auto_debug_print(AUTO_DBGLVL_ERR, |
2186 "ai_du_install: ai_du_get_and_install needs to be " |
1847 "ai_du_install: ai_du_get_and_install needs to be " |
2187 "called first.\n"); |
1848 "called first.\n"); |
2188 return (AUTO_INSTALL_FAILURE); |
1849 return (-1); |
2189 |
1850 |
2190 } else if (PyList_Size(py_pkg_list) == 0) { |
1851 } else if (PyList_Size(py_pkg_list) == 0) { |
2191 return (AUTO_INSTALL_SUCCESS); |
1852 return (num_pkgs_installed); |
2192 } |
1853 } |
2193 |
1854 |
2194 if ((py_state_p = auto_ddu_lib_init()) == NULL) { |
1855 if ((py_state_p = auto_ddu_lib_init()) == NULL) { |
2195 auto_debug_print(AUTO_DBGLVL_ERR, |
1856 auto_debug_print(AUTO_DBGLVL_ERR, |
2196 "ai_du_install: " |
1857 "ai_du_install: " |
2197 "Error initializing auto_ddu_lib.\n"); |
1858 "Error initializing auto_ddu_lib.\n"); |
2198 return (AUTO_INSTALL_FAILURE); |
1859 return (-1); |
2199 } |
1860 } |
2200 |
1861 |
2201 if ((rval = ai_du_install_packages(py_state_p, py_pkg_list, |
1862 if ((rval = ai_du_install_packages(py_state_p, py_pkg_list, |
2202 install_root, honor_noinstall, num_installed_pkgs_p)) != |
1863 install_root, honor_noinstall, &num_pkgs_installed)) != |
2203 AUTO_INSTALL_SUCCESS) { |
1864 AUTO_INSTALL_SUCCESS) { |
2204 auto_debug_print(AUTO_DBGLVL_ERR, |
1865 auto_debug_print(AUTO_DBGLVL_ERR, |
2205 "ai_du_install: Error installing packages.\n"); |
1866 "ai_du_install: Error installing packages.\n"); |
2206 rval = AUTO_INSTALL_FAILURE; |
1867 rval = -1; |
2207 } |
1868 } |
2208 |
1869 |
2209 if (update_boot_archive && (*num_installed_pkgs_p > 0)) { |
1870 if (update_boot_archive && (num_pkgs_installed > 0)) { |
2210 if (ai_du_call_update_archive_ict(py_state_p, |
1871 if (ai_du_call_update_archive_ict(py_state_p, |
2211 install_root) != AUTO_INSTALL_SUCCESS) { |
1872 install_root) != AUTO_INSTALL_SUCCESS) { |
2212 auto_debug_print(AUTO_DBGLVL_ERR, |
1873 auto_debug_print(AUTO_DBGLVL_ERR, |
2213 "ai_du_install: Warning: could not update boot " |
1874 "ai_du_install: Warning: could not update boot " |
2214 "archive for %s.\n", install_root); |
1875 "archive for %s.\n", install_root); |
2215 } |
1876 } |
2216 } |
1877 } |
2217 |
1878 |
|
1879 if (rval != -1) { |
|
1880 rval = num_pkgs_installed; |
|
1881 } |
|
1882 |
2218 auto_ddu_lib_fini(py_state_p); |
1883 auto_ddu_lib_fini(py_state_p); |
2219 |
1884 |
2220 return (rval); |
1885 return (rval); |
2221 } |
1886 } |