static enum agent_return do_operation(enum operation op, const char *name) { TDB_DATA k; enum agent_return ret; TDB_DATA data; enum TDB_ERROR ecode; union tdb_attribute cif; if (op != OPEN && op != OPEN_WITH_HOOK && !tdb) { diag("external: No tdb open!"); return OTHER_FAILURE; } diag("external: %s", operation_name(op)); k = tdb_mkdata(name, strlen(name)); locking_would_block = 0; switch (op) { case OPEN: if (tdb) { diag("Already have tdb %s open", tdb_name(tdb)); return OTHER_FAILURE; } tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &tap_log_attr); if (!tdb) { if (!locking_would_block) diag("Opening tdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case OPEN_WITH_HOOK: if (tdb) { diag("Already have tdb %s open", tdb_name(tdb)); return OTHER_FAILURE; } cif.openhook.base.attr = TDB_ATTRIBUTE_OPENHOOK; cif.openhook.base.next = &tap_log_attr; cif.openhook.fn = clear_if_first; tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &cif); if (!tdb) { if (!locking_would_block) diag("Opening tdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case FETCH: ecode = tdb_fetch(tdb, k, &data); if (ecode == TDB_ERR_NOEXIST) { ret = FAILED; } else if (ecode < 0) { ret = OTHER_FAILURE; } else if (!tdb_deq(data, k)) { ret = OTHER_FAILURE; external_agent_free(data.dptr); } else { ret = SUCCESS; external_agent_free(data.dptr); } break; case STORE: ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_START: ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_COMMIT: ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE; break; case NEEDS_RECOVERY: ret = external_agent_needs_rec(tdb); break; case CHECK: ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; break; case CLOSE: ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; tdb = NULL; break; case SEND_SIGNAL: /* We do this async */ ret = SUCCESS; break; default: ret = OTHER_FAILURE; } if (locking_would_block) ret = WOULD_HAVE_BLOCKED; return ret; }
static enum agent_return do_operation(enum operation op, const char *name) { NTDB_DATA k, d; enum agent_return ret; NTDB_DATA data; enum NTDB_ERROR ecode; union ntdb_attribute cif; const char *eq; if (op != OPEN && op != OPEN_WITH_HOOK && !ntdb) { diag("external: No ntdb open!"); return OTHER_FAILURE; } diag("external: %s", operation_name(op)); eq = strchr(name, '='); if (eq) { k = ntdb_mkdata(name, eq - name); d = ntdb_mkdata(eq + 1, strlen(eq+1)); } else { k = ntdb_mkdata(name, strlen(name)); d.dsize = 0; d.dptr = NULL; } locking_would_block = 0; switch (op) { case OPEN: if (ntdb) { diag("Already have ntdb %s open", ntdb_name(ntdb)); return OTHER_FAILURE; } ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &tap_log_attr); if (!ntdb) { if (!locking_would_block) diag("Opening ntdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case OPEN_WITH_HOOK: if (ntdb) { diag("Already have ntdb %s open", ntdb_name(ntdb)); return OTHER_FAILURE; } cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK; cif.openhook.base.next = &tap_log_attr; cif.openhook.fn = clear_if_first; ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &cif); if (!ntdb) { if (!locking_would_block) diag("Opening ntdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case FETCH: ecode = ntdb_fetch(ntdb, k, &data); if (ecode == NTDB_ERR_NOEXIST) { ret = FAILED; } else if (ecode < 0) { ret = OTHER_FAILURE; } else if (!ntdb_deq(data, d)) { ret = OTHER_FAILURE; external_agent_free(data.dptr); } else { ret = SUCCESS; external_agent_free(data.dptr); } break; case STORE: ret = ntdb_store(ntdb, k, d, 0) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_START: ret = ntdb_transaction_start(ntdb) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_COMMIT: ret = ntdb_transaction_commit(ntdb)==0 ? SUCCESS : OTHER_FAILURE; break; case NEEDS_RECOVERY: ret = external_agent_needs_rec(ntdb); break; case CHECK: ret = ntdb_check(ntdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; break; case CLOSE: ret = ntdb_close(ntdb) == 0 ? SUCCESS : OTHER_FAILURE; ntdb = NULL; break; case SEND_SIGNAL: /* We do this async */ ret = SUCCESS; break; default: ret = OTHER_FAILURE; } if (locking_would_block) ret = WOULD_HAVE_BLOCKED; return ret; }