static int _fill_base_msg(entry_list_t *elist, mc_msg_t* base, _parse_info_t* parse_info) { FBI_ASSERT(elist && base && parse_info); uint64_t i; int numDoubles = 0; parse_info->reqid = 0; parse_info->key_idx = -1; parse_info->value_idx = -1; #ifndef LIBMC_FBTRACE_DISABLE parse_info->fbtrace_idx = -1; #endif parse_info->stats_count = 0; uint64_t field_mask = 0; for (i = 0; i < elist->nentries; i++) { uint16_t tag = ntoh16(elist->entries[i].tag); uint64_t val = ntoh64(elist->entries[i].data.val); // No dup fields (except for stats and double) if ((tag & field_mask) && (tag != msg_stats && tag != msg_double)) { dbg_error("Duplicate field: field_mask = 0x%lX, field = 0x%X\n", field_mask, tag); return -1; } field_mask |= tag; switch (tag) { case msg_op: if (val >= UM_NOPS) { return -1; } base->op = umbrella_op_to_mc[val]; if (base->op == mc_nops) { return -1; } break; case msg_result: if (val >= mc_nres) { return -1; } base->result = umbrella_res_to_mc[val]; break; case msg_reqid: if (val == 0) { return -1; } parse_info->reqid = val; break; case msg_err_code: base->err_code = val; break; case msg_flags: base->flags = val; break; case msg_exptime: base->exptime = val; break; case msg_number: base->number = val; break; case msg_delta: base->delta = val; break; case msg_lease_id: base->lease_id = val; break; case msg_cas: base->cas = val; break; case msg_double: if (numDoubles == 0 ) { memcpy(&base->lowval, &val, sizeof(double)); } else if (numDoubles == 1) { memcpy(&base->highval, &val, sizeof(double)); } else { return -1; } numDoubles++; break; case msg_key: if (parse_info->key_idx == -1) { parse_info->key_idx = i; } break; case msg_value: if (parse_info->value_idx != -1) { return -1; } parse_info->value_idx = i; break; case msg_stats: parse_info->stats_count++; break; #ifndef LIBMC_FBTRACE_DISABLE case msg_fbtrace: if (parse_info->fbtrace_idx != -1) { return -1; } parse_info->fbtrace_idx = i; break; #endif default: return -1; } } if (parse_info->reqid == 0) { return -1; } if (parse_info->key_idx >= (int64_t)elist->nentries) { return -1; } if (parse_info->value_idx >= (int64_t)elist->nentries) { return -1; } if (!valid_msg(base->op, field_mask)) { dbg_error("Invalid message"); return -1; } return 0; }
/* * __gtxt(catname, id, dflt): Return a pointer to a message. * catname is the name of the catalog. If null, the default catalog is * used. * id is the numeric id of the message in the catalogue * dflt is the default message. * * Information about non-existent catalogues is kept in db_info, in * such a way that subsequent calls with the same catalogue do not * try to open the catalogue again. */ const char * __gtxt(const char *catname, int id, const char *dflt) { char *curloc; struct db_info *db; int err; /* Check for invalid message id */ if (id < 0) return (not_found); if (id == 0) return ((dflt && *dflt) ? dflt : not_found); /* * If catalogue is unspecified, use default catalogue. * No catalogue at all is an error */ if (!catname || !*catname) { lrw_rdlock(&_rw_cur_cat); if (cur_cat == NULL || !*cur_cat) { lrw_unlock(&_rw_cur_cat); return (not_found); } catname = cur_cat; lrw_unlock(&_rw_cur_cat); } curloc = setlocale(LC_MESSAGES, NULL); /* First look up the cache */ db = lookup_cache(NULL, curloc, catname); if (db != NULL) { /* * The catalog has been loaded, and if id seems valid, * then just return. */ if (valid_msg(db, id)) return (msg(db, id)); /* * seems given id is out of bound or does not exist. In this * case, we need to look up a message for the "C" locale as * documented in the man page. */ db = lookup_cache(NULL, def_locale, catname); if (db == NULL) { /* * Even the message catalog for the "C" has not been * loaded. */ db = load_db(def_locale, catname, &err); if (err) return (not_found); } if (valid_msg(db, id)) return (msg(db, id)); /* no message found */ return ((dflt && *dflt) ? dflt : not_found); } /* * The catalog has not been loaded or even has not * attempted to be loaded, invalidate all caches related to * the catname for possibly different locale. */ db = NULL; while ((db = lookup_cache(db, NULL, catname)) != NULL) unload_db(db); /* * load a message catalog for the requested locale. */ db = load_db(curloc, catname, &err); if (err) return (not_found); if (valid_msg(db, id)) return (msg(db, id)); /* * If the requested catalog is either not exist or message * id is invalid, then try to load from "C" locale. */ db = load_db(def_locale, catname, &err); if (err) return (not_found); if (valid_msg(db, id)) return (msg(db, id)); /* no message found */ return ((dflt && *dflt) ? dflt : not_found); }