mm_types.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <syslog.h>
#include <mms_list.h>
#include <mms_parser.h>
#include <mms_par_impl.h>
#include <libpq-fe.h>
#include <mms_trace.h>
#include <mms_strapp.h>
#include <libxml/parser.h>
#include "mm_db.h"
#include "mm.h"
#include "mm_util.h"
#include "mm_commands.h"
#include "mm_sql.h"
#include "mm_sql_impl.h"
#include "mm_task.h"
#include "mm_path.h"
static char *_SrcFile = __FILE__;
typedef struct mm_type_library mm_type_library_t;
struct mm_type_library {
mms_list_node_t mm_library_list_next;
mms_list_t mm_library_name_list;
mms_list_t mm_shape_name_list;
};
typedef struct mm_type_data mm_type_data_t;
struct mm_type_data {
int mm_error;
int mm_level;
int mm_once;
mms_list_t mm_drive_name_list;
mms_list_t mm_cart_name_list;
mms_list_t mm_library_list;
mm_type_library_t *cur_lib;
};
static void mm_check_drive_string(char *drive_name);
static void mm_check_cartridge_string(char *cartridge_name);
static void mm_check_cartridgetype_string(char *cartridge_name);
static void mm_check_library_string(char *library_name);
static void mm_check_slottype_string(char *cartridgeshape_name,
char *cur_library_name);
static int mm_verify_types(mm_type_data_t *type_data);
static int mm_parse_types(mm_type_data_t *type_data, char *fn);
static void mm_parse_type_start_elements(void *xml_type_data,
const xmlChar *xml_name, const xmlChar **xml_atts);
static void mm_parse_type_end_elements(void *xml_type_data,
const xmlChar *xml_name);
static mm_db_t *db;
static PGresult *drive_results;
static int num_drive;
static PGresult *cartridge_results;
static int num_cartridge;
static PGresult *library_results;
static int num_library;
static PGresult *slottype_results;
static int num_slottype;
static PGresult *carttype_results;
static int num_carttype;
static void
mm_library_list_destroy(mms_list_t *list) {
mm_type_library_t *lib_list;
mm_type_library_t *next_lib_list;
for (lib_list = mms_list_head(list);
lib_list != NULL;
lib_list = next_lib_list) {
mm_char_list_destroy(&lib_list->mm_library_name_list);
mm_char_list_destroy(&lib_list->mm_shape_name_list);
next_lib_list =
mms_list_next(list,
lib_list);
mms_list_remove(list,
lib_list);
free(lib_list);
}
}
static
mm_type_library_t *
mm_alloc_lib_struct() {
mm_type_library_t *lib;
lib = (mm_type_library_t *)calloc(1, sizeof (mm_type_library_t));
if (lib == NULL) {
printf("could not allocate mem for lib struct");
exit(1);
}
mms_list_create(&lib->mm_library_name_list, sizeof (mm_char_list_t),
offsetof(mm_char_list_t, mm_char_list_next));
mms_list_create(&lib->mm_shape_name_list, sizeof (mm_char_list_t),
offsetof(mm_char_list_t, mm_char_list_next));
return (lib);
}
int
mm_init_types(mm_data_t *mm_data, char *fn)
{
mm_type_data_t type_data;
mms_trace(MMS_DEVP, "types init %s", fn);
db = &mm_data->mm_db;
/* Get existing drives/carts/library/slottypes */
if (mm_db_exec(HERE, db,
"select \"DriveString\" "
"from \"DRIVELIST\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting drive strings");
mm_clear_db(&db->mm_db_results);
return (1);
} else {
drive_results = db->mm_db_results;
num_drive = PQntuples(drive_results);
}
if (mm_db_exec(HERE, db,
"select \"CartridgeString\" "
"from \"CARTRIDGELIST\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting cartridge strings");
mm_clear_db(&drive_results);
mm_clear_db(&db->mm_db_results);
return (1);
} else {
cartridge_results = db->mm_db_results;
num_cartridge = PQntuples(cartridge_results);
}
if (mm_db_exec(HERE, db,
"select \"LibraryString\" "
"from \"LIBRARYLIST\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting library strings");
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&db->mm_db_results);
return (1);
} else {
library_results = db->mm_db_results;
num_library = PQntuples(library_results);
}
if (mm_db_exec(HERE, db,
"select \"SlotTypeName\", \"CartridgeShapeName\" "
"from \"SLOTTYPE\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting slottype strings");
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&library_results);
mm_clear_db(&db->mm_db_results);
return (1);
} else {
slottype_results = db->mm_db_results;
num_slottype = PQntuples(slottype_results);
}
if (mm_db_exec(HERE, db,
"select \"CartridgeTypeName\", \"CartridgeShapeName\" "
"from \"CARTRIDGETYPE\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting CARTRIDGETYPE strings");
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&library_results);
mm_clear_db(&slottype_results);
mm_clear_db(&db->mm_db_results);
return (1);
} else {
carttype_results = db->mm_db_results;
num_carttype = PQntuples(carttype_results);
}
memset(&type_data, 0, sizeof (mm_type_data_t));
/* Create drive cart and library lists */
mms_list_create(&type_data.mm_drive_name_list, sizeof (mm_char_list_t),
offsetof(mm_char_list_t, mm_char_list_next));
mms_list_create(&type_data.mm_cart_name_list, sizeof (mm_char_list_t),
offsetof(mm_char_list_t, mm_char_list_next));
mms_list_create(&type_data.mm_library_list, sizeof (mm_type_library_t),
offsetof(mm_type_library_t, mm_library_list_next));
type_data.mm_error = 0;
if (mm_parse_types(&type_data, fn)) {
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&library_results);
mm_clear_db(&slottype_results);
mm_clear_db(&carttype_results);
mm_char_list_destroy(&type_data.mm_drive_name_list);
mm_char_list_destroy(&type_data.mm_cart_name_list);
mm_library_list_destroy(&type_data.mm_library_list);
return (1);
}
mms_trace(MMS_DEVP,
"parsing types done, verify now");
if (mm_verify_types(&type_data)) {
mms_trace(MMS_ERR,
"error verifying types");
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&library_results);
mm_clear_db(&slottype_results);
mm_clear_db(&carttype_results);
mm_char_list_destroy(&type_data.mm_drive_name_list);
mm_char_list_destroy(&type_data.mm_cart_name_list);
mm_library_list_destroy(&type_data.mm_library_list);
return (1);
}
mms_trace(MMS_DEVP,
"types verified successfully, "
"type init done");
mm_clear_db(&drive_results);
mm_clear_db(&cartridge_results);
mm_clear_db(&library_results);
mm_clear_db(&slottype_results);
mm_clear_db(&carttype_results);
mm_char_list_destroy(&type_data.mm_drive_name_list);
mm_char_list_destroy(&type_data.mm_cart_name_list);
mm_library_list_destroy(&type_data.mm_library_list);
return (0);
}
static void
mm_types_delete_drive(mm_type_data_t *type_data) {
mm_char_list_t *node;
mm_char_list_t *next;
char *buf = NULL;
int found_one = 0;
buf = mms_strapp(buf,
"delete from \"DRIVELIST\" where ");
for (node = mms_list_head(&type_data->mm_drive_name_list);
node != NULL;
node = next) {
next = mms_list_next(&type_data->mm_drive_name_list, node);
if (found_one != 0) {
buf = mms_strapp(buf, " and ");
}
found_one = 1;
buf = mms_strapp(buf, "(\"DriveString\" != '%s') ",
node->text);
}
if (found_one) {
buf = mms_strapp(buf, ";");
if (mm_db_exec(HERE, db, buf) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_types_delete_drive: "
"db error deleting from drivelist");
}
}
free(buf);
}
static void
mm_types_delete_cart(mm_type_data_t *type_data) {
mm_char_list_t *node;
mm_char_list_t *next;
char *buf = NULL;
int found_one = 0;
buf = mms_strapp(buf,
"delete from \"CARTRIDGELIST\" where ");
for (node = mms_list_head(&type_data->mm_cart_name_list);
node != NULL;
node = next) {
next = mms_list_next(&type_data->mm_cart_name_list, node);
if (found_one != 0) {
buf = mms_strapp(buf, " and ");
}
found_one = 1;
buf = mms_strapp(buf, "(\"CartridgeString\" != '%s') ",
node->text);
}
if (found_one) {
buf = mms_strapp(buf, ";");
if (mm_db_exec(HERE, db, buf) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_types_delete_cart: "
"db error deleting from cartlist");
}
}
free(buf);
}
static void
mm_types_delete_library(mm_type_data_t *type_data) {
mm_type_library_t *lib_list;
mm_type_library_t *next_lib_list;
mm_char_list_t *node;
mm_char_list_t *next;
mm_char_list_t *node2;
mm_char_list_t *next2;
char *lib_buf = NULL;
char *slottype_buf = NULL;
int found_one_lib = 0;
int found_one_slottype = 0;
lib_buf = mms_strapp(lib_buf,
"delete from \"LIBRARYLIST\" where ");
slottype_buf = mms_strapp(slottype_buf,
"delete from \"SLOTTYPE\" where ");
for (lib_list = mms_list_head(&type_data->mm_library_list);
lib_list != NULL;
lib_list = next_lib_list) {
next_lib_list =
mms_list_next(&type_data->mm_library_list,
lib_list);
for (node = mms_list_head(&lib_list->mm_library_name_list);
node != NULL;
node = next) {
next = mms_list_next(&lib_list->
mm_library_name_list,
node);
if (found_one_lib != 0) {
lib_buf = mms_strapp(lib_buf, " and ");
}
found_one_lib = 1;
lib_buf = mms_strapp(lib_buf,
"(\"LibraryString\" != '%s') ",
node->text);
for (node2 = mms_list_head(&lib_list->
mm_shape_name_list);
node2 != NULL;
node2 = next2) {
next2 = mms_list_next(&lib_list->
mm_shape_name_list, node2);
if (found_one_slottype != 0) {
slottype_buf =
mms_strapp(slottype_buf, " and ");
}
found_one_slottype = 1;
slottype_buf = mms_strapp(slottype_buf,
"((\"SlotTypeName\" != '%s') and "
"(\"CartridgeShapeName\" != '%s')) ",
node->text,
node2->text);
}
}
}
if (found_one_lib) {
lib_buf = mms_strapp(lib_buf, ";");
if (mm_db_exec(HERE, db, lib_buf) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_types_delete_library: "
"db error deleting from librarylist");
}
}
if (found_one_slottype) {
slottype_buf = mms_strapp(slottype_buf, ";");
if (mm_db_exec(HERE, db, slottype_buf) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_types_delete_library: "
"db error deleting from slottype");
}
}
free(lib_buf);
free(slottype_buf);
}
static int
mm_verify_types(mm_type_data_t *type_data)
{
mm_type_library_t *lib_list;
mm_type_library_t *next_lib_list;
mm_char_list_t *node;
mm_char_list_t *next;
mm_char_list_t *node2;
mm_char_list_t *next2;
int print = 0;
/* Print out what we have in the lists */
if (print) {
mms_trace(MMS_DEVP,
"Drive Strings:");
mm_print_char_list(&type_data->
mm_drive_name_list);
}
for (node = mms_list_head(&type_data->mm_drive_name_list);
node != NULL;
node = next) {
next = mms_list_next(&type_data->mm_drive_name_list, node);
mm_check_drive_string(node->text);
}
if (print) {
mms_trace(MMS_DEVP,
"Cartridge Strings:");
mm_print_char_list(&type_data->
mm_cart_name_list);
}
for (node = mms_list_head(&type_data->mm_cart_name_list);
node != NULL;
node = next) {
next = mms_list_next(&type_data->mm_cart_name_list, node);
mm_check_cartridge_string(node->text);
}
for (lib_list = mms_list_head(&type_data->mm_library_list);
lib_list != NULL;
lib_list = next_lib_list) {
next_lib_list =
mms_list_next(&type_data->mm_library_list,
lib_list);
if (print) {
mms_trace(MMS_DEVP,
"Library Strings:");
mm_print_char_list(&lib_list->
mm_library_name_list);
mms_trace(MMS_DEVP,
"Slottype Strings:");
mm_print_char_list(&lib_list->
mm_shape_name_list);
}
for (node = mms_list_head(&lib_list->mm_library_name_list);
node != NULL;
node = next) {
next = mms_list_next(&lib_list->
mm_library_name_list,
node);
mm_check_library_string(node->text);
for (node2 = mms_list_head(&lib_list->
mm_shape_name_list);
node2 != NULL;
node2 = next2) {
next2 = mms_list_next(&lib_list->
mm_shape_name_list, node2);
mm_check_slottype_string(node2->text,
node->text);
}
}
}
/* Create the Side1Name column for default types */
if (mm_db_exec(HERE, db,
"ALTER TABLE \"CARTRIDGETYPE\" "
"ADD \"Side1Name\" text;") != MM_DB_OK) {
/* If there is an error ignore it */
mm_clear_db(&db->mm_db_results);
}
for (node = mms_list_head(&type_data->mm_cart_name_list);
node != NULL;
node = next) {
next = mms_list_next(&type_data->mm_cart_name_list, node);
mm_check_cartridgetype_string(node->text);
}
/* All strings in xml are now in db */
/* now delete any strings that are not in the xml */
mm_types_delete_drive(type_data);
mm_types_delete_cart(type_data);
mm_types_delete_library(type_data);
return (0);
}
static int
mm_parse_types(mm_type_data_t *type_data, char *fn)
{
xmlSAXHandler handler;
memset(&handler, 0, sizeof (xmlSAXHandler));
handler.startElement = mm_parse_type_start_elements;
handler.endElement = mm_parse_type_end_elements;
xmlDefaultSAXHandlerInit();
xmlSAXUserParseFile(&handler, type_data, fn);
if (type_data->mm_once == 0) {
type_data->mm_error = __LINE__;
}
if (type_data->mm_error) {
mms_trace(MMS_ERR, "%s parse - error %d level %d",
fn,
type_data->mm_error,
type_data->mm_level);
}
return (type_data->mm_error);
}
static void
mm_check_drive_string(char *drive_name) {
int i;
char *cur_drive;
int matched_drive = 0;
for (i = 0; i < num_drive; i++) {
cur_drive = PQgetvalue(drive_results,
i, 0);
if (strcmp(drive_name, cur_drive) == 0) {
/* already have this drive name */
matched_drive = 1;
}
}
if (matched_drive == 0) {
/* Need to add this drive to drive list */
if (mm_db_exec(HERE, db,
"insert into \"DRIVELIST\" "
"(\"DriveString\") values('%s');",
drive_name) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error inserting %s "
"into DRIVELIST",
drive_name);
mm_clear_db(&db->mm_db_results);
}
}
}
static void
mm_check_cartridge_string(char *cartridge_name) {
int i;
char *cur_cartridge;
int matched_cartridge = 0;
for (i = 0; i < num_cartridge; i++) {
cur_cartridge = PQgetvalue(cartridge_results,
i, 0);
if (strcmp(cartridge_name, cur_cartridge) == 0) {
/* already have this cartridge name */
matched_cartridge = 1;
}
}
if (matched_cartridge == 0) {
/* Need to add this cartridge to cartridge list */
if (mm_db_exec(HERE, db,
"insert into \"CARTRIDGELIST\" "
"(\"CartridgeString\") values('%s');",
cartridge_name) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error inserting %s "
"into CARTRIDGELIST",
cartridge_name);
mm_clear_db(&db->mm_db_results);
}
}
}
static void
mm_check_cartridgetype_string(char *cartridgeshape_name) {
int i;
char *cur_carttype;
char *cur_cartshape;
int matched_cartridge = 0;
for (i = 0; i < num_carttype; i++) {
cur_carttype = PQgetvalue(carttype_results,
i, 0);
cur_cartshape = PQgetvalue(carttype_results,
i, 1);
if ((strcmp(cartridgeshape_name, cur_carttype) == 0) &&
(strcmp(cartridgeshape_name, cur_cartshape) == 0)) {
/* already have this cartridge name */
matched_cartridge = 1;
}
}
if (matched_cartridge == 0) {
/* Need to add this cartridge to cartridge list */
if (mm_db_exec(HERE, db,
"insert into \"CARTRIDGETYPE\" "
"(\"CartridgeTypeName\", "
"\"CartridgeShapeName\", "
"\"Side1Name\", "
"\"CartridgeTypeMediaType\") values('%s',"
"'%s', 'side 1', 'data');",
cartridgeshape_name,
cartridgeshape_name) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error inserting %s "
"into CARTRIDGETYPE",
cartridgeshape_name);
mm_clear_db(&db->mm_db_results);
}
}
}
static void
mm_check_library_string(char *library_name) {
int i;
char *cur_library;
int matched_library = 0;
for (i = 0; i < num_library; i++) {
cur_library = PQgetvalue(library_results,
i, 0);
if (strcmp(library_name, cur_library) == 0) {
/* already have this library name */
matched_library = 1;
}
}
if (matched_library == 0) {
/* Need to add this library to library list */
if (mm_db_exec(HERE, db,
"insert into \"LIBRARYLIST\" "
"(\"LibraryString\") values('%s');",
library_name) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error inserting %s "
"into LIBRARYLIST",
library_name);
mm_clear_db(&db->mm_db_results);
}
}
}
static void
mm_check_slottype_string(char *cartridgeshape_name,
char *cur_library_name) {
int i;
char *cur_slottype;
char *cur_cartridgeshape;
int matched_slottype = 0;
for (i = 0; i < num_slottype; i++) {
cur_slottype = PQgetvalue(slottype_results,
i, 0);
cur_cartridgeshape = PQgetvalue(slottype_results,
i, 1);
if ((strcmp(cur_library_name, cur_slottype) == 0) &&
(strcmp(cartridgeshape_name, cur_cartridgeshape) == 0)) {
/* already have this slottype name */
matched_slottype = 1;
}
}
if (matched_slottype == 0) {
/* Need to add this slottype to slottype list */
if (mm_db_exec(HERE, db,
"insert into \"SLOTTYPE\" "
"(\"SlotTypeName\", \"CartridgeShapeName\") "
"values('%s', '%s');",
cur_library_name,
cartridgeshape_name) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error inserting %s, %s "
"into SLOTTYPE",
cur_library_name,
cartridgeshape_name);
}
}
}
static void
mm_parse_type_start_elements(void *xml_type_data, const xmlChar *xml_name,
const xmlChar **xml_atts)
{
mm_type_data_t *type_data = (mm_type_data_t *)xml_type_data;
char *name = (char *)xml_name;
char **atts = (char **)xml_atts;
mm_type_library_t *new_lib;
if (type_data->mm_error) {
return;
}
if (type_data->mm_once == 0) {
type_data->mm_once = 1;
}
if (type_data->mm_level == 0 &&
strcmp(name, "mm_types") == 0) {
type_data->mm_level = 1;
return;
}
if (type_data->mm_level == 1 &&
strcmp(name, "mm_drive_list") == 0) {
type_data->mm_level = 2;
return;
}
if (type_data->mm_level == 1 &&
strcmp(name, "mm_cartridge_list") == 0) {
type_data->mm_level = 2;
return;
}
if (type_data->mm_level == 1 &&
strcmp(name, "mm_library_list") == 0) {
type_data->mm_level = 2;
return;
}
if (type_data->mm_level == 2 &&
strcmp(name, "mm_library") == 0) {
type_data->mm_level = 3;
new_lib = mm_alloc_lib_struct();
mms_list_insert_tail(&type_data->mm_library_list,
new_lib);
type_data->cur_lib = new_lib;
return;
}
if (type_data->mm_level == 3 &&
strcmp(name, "mm_slottype_list") == 0) {
type_data->mm_level = 4;
return;
}
if (type_data->mm_level == 3 &&
strcmp(name, "mm_cartridgeshape_list") == 0) {
type_data->mm_level = 4;
return;
}
if (type_data->mm_level == 2 &&
strcmp(name, "mm_drive_string") == 0) {
if (atts[0] == NULL || strcmp(atts[0], "value") != 0) {
type_data->mm_error = __LINE__;
} else if (atts[1] != NULL) {
mms_trace(MMS_DEVP,
" mm_drive_string=%s",
atts[1]);
if (mm_add_char(atts[1],
&type_data->mm_drive_name_list)) {
mms_trace(MMS_ERR,
"mm_parse_type_start_elements: "
"out of mem adding to drive list");
}
}
return;
}
if (type_data->mm_level == 2 &&
strcmp(name, "mm_cartridge_string") == 0) {
if (atts[0] == NULL || strcmp(atts[0], "value") != 0) {
type_data->mm_error = __LINE__;
} else if (atts[1] != NULL) {
mms_trace(MMS_DEVP,
" mm_cartridge_string=%s",
atts[1]);
if (mm_add_char(atts[1],
&type_data->mm_cart_name_list)) {
mms_trace(MMS_ERR,
"mm_parse_type_start_elements: "
"out of mem adding to cart list");
}
}
return;
}
if (type_data->mm_level == 4 &&
strcmp(name, "mm_slottype") == 0) {
if (atts[0] == NULL || strcmp(atts[0], "name") != 0) {
type_data->mm_error = __LINE__;
} else if (atts[1] != NULL) {
mms_trace(MMS_DEVP,
" mm_slottype name=%s",
atts[1]);
if (mm_add_char(atts[1],
&type_data->cur_lib->mm_library_name_list)) {
mms_trace(MMS_ERR,
"mm_parse_type_start_elements: "
"out of mem adding to library list");
}
}
return;
}
if (type_data->mm_level == 4 &&
strcmp(name, "mm_cartridgeshape") == 0) {
if (atts[0] == NULL || strcmp(atts[0], "name") != 0) {
type_data->mm_error = __LINE__;
} else if (atts[1] != NULL) {
mms_trace(MMS_DEVP,
" mm_cartridgeshape name=%s",
atts[1]);
if (mm_add_char(atts[1],
&type_data->cur_lib->mm_shape_name_list)) {
mms_trace(MMS_ERR,
"mm_parse_type_start_elements: "
"out of mem adding to shape list");
}
}
return;
}
type_data->mm_error = __LINE__;
}
static void
mm_parse_type_end_elements(void *xml_type_data, const xmlChar *xml_name)
{
mm_type_data_t *type_data = (mm_type_data_t *)xml_type_data;
char *name = (char *)xml_name;
if (type_data->mm_level == 2 &&
strcmp(name, "mm_drive_list") == 0) {
type_data->mm_level = 1;
return;
}
if (type_data->mm_level == 2 &&
strcmp(name, "mm_cartridge_list") == 0) {
type_data->mm_level = 1;
return;
}
if (type_data->mm_level == 2 &&
strcmp(name, "mm_library_list") == 0) {
type_data->mm_level = 1;
return;
}
if (type_data->mm_level == 3 &&
strcmp(name, "mm_library") == 0) {
type_data->mm_level = 2;
type_data->cur_lib = NULL;
return;
}
if (type_data->mm_level == 4 &&
strcmp(name, "mm_slottype_list") == 0) {
type_data->mm_level = 3;
return;
}
if (type_data->mm_level == 4 &&
strcmp(name, "mm_cartridgeshape_list") == 0) {
type_data->mm_level = 3;
return;
}
}