static int myopen(const char *fname, int flags, struct dbengine **ret, struct txn **mytid) { struct dbengine *db; struct stat sbuf; assert(fname && ret); db = find_db(fname); if (db) goto out; /* new reference to existing db */ db = (struct dbengine *) xzmalloc(sizeof(struct dbengine)); db->fd = open(fname, O_RDWR, 0644); if (db->fd == -1 && errno == ENOENT) { if (!(flags & CYRUSDB_CREATE)) { free_db(db); return CYRUSDB_NOTFOUND; } if (cyrus_mkdir(fname, 0755) == -1) { free_db(db); return CYRUSDB_IOERROR; } db->fd = open(fname, O_RDWR | O_CREAT, 0644); } if (db->fd == -1) { syslog(LOG_ERR, "IOERROR: opening %s: %m", fname); free_db(db); return CYRUSDB_IOERROR; } if (fstat(db->fd, &sbuf) == -1) { syslog(LOG_ERR, "IOERROR: fstat on %s: %m", fname); close(db->fd); free_db(db); return CYRUSDB_IOERROR; } db->ino = sbuf.st_ino; map_refresh(db->fd, 0, &db->base, &db->len, sbuf.st_size, fname, 0); db->size = sbuf.st_size; db->fname = xstrdup(fname); db->refcount = 1; /* prepend to the list */ db->next = alldbs; alldbs = db; if (mytid) { int r = starttxn_or_refetch(db, mytid); if (r) return r; } out: *ret = db; return 0; }
/*-------------------------------------------------------------------------*/ Bool sl_close (object_t *ob) /* For object <ob>, find and close the database connection. * Return TRUE on success, FALSE if there wasn't one. */ { sqlite_dbs_t *db = find_db(ob); ob->open_sqlite_db = MY_FALSE; if (!db) return MY_FALSE; sqlite3_close(db->db); remove_db(db); return MY_TRUE; } /* sl_close() */
/*-------------------------------------------------------------------------*/ svalue_t * f_sl_insert_id (svalue_t * sp) /* EFUN sl_insert_id() * * int sl_insert_id() * * After inserting a line into a table with an AUTO_INCREMENT field, * this efun can be used to return the (new) value of the AUTO_INCREMENT * field. */ { sqlite_dbs_t *db = find_db(current_object); int id; if (!db) errorf("The current object doesn't have a database open.\n"); id=sqlite3_last_insert_rowid(db->db); sp++; put_number(sp,id); return sp; } /* f_sl_insert_id() */
static krb5_error_code KRB5_CALLCONV hdb_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal principal, krb5_kvno kvno, krb5_enctype enctype, krb5_keytab_entry *entry) { hdb_entry_ex ent; krb5_error_code ret; struct hdb_data *d = id->data; const char *dbname = d->dbname; const char *mkey = d->mkey; char *fdbname = NULL, *fmkey = NULL; HDB *db; int i; memset(&ent, 0, sizeof(ent)); if (dbname == NULL) { ret = find_db(context, &fdbname, &fmkey, principal); if (ret) return ret; dbname = fdbname; mkey = fmkey; } ret = hdb_create (context, &db, dbname); if (ret) goto out2; ret = hdb_set_master_keyfile (context, db, mkey); if (ret) { (*db->hdb_destroy)(context, db); goto out2; } ret = (*db->hdb_open)(context, db, O_RDONLY, 0); if (ret) { (*db->hdb_destroy)(context, db); goto out2; } ret = (*db->hdb_fetch_kvno)(context, db, principal, HDB_F_DECRYPT|HDB_F_KVNO_SPECIFIED| HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, kvno, &ent); if(ret == HDB_ERR_NOENTRY) { ret = KRB5_KT_NOTFOUND; goto out; }else if(ret) goto out; if(kvno && ent.entry.kvno != kvno) { hdb_free_entry(context, &ent); ret = KRB5_KT_NOTFOUND; goto out; } if(enctype == 0) if(ent.entry.keys.len > 0) enctype = ent.entry.keys.val[0].key.keytype; ret = KRB5_KT_NOTFOUND; for(i = 0; i < ent.entry.keys.len; i++) { if(ent.entry.keys.val[i].key.keytype == enctype) { krb5_copy_principal(context, principal, &entry->principal); entry->vno = ent.entry.kvno; krb5_copy_keyblock_contents(context, &ent.entry.keys.val[i].key, &entry->keyblock); ret = 0; break; } } hdb_free_entry(context, &ent); out: (*db->hdb_close)(context, db); (*db->hdb_destroy)(context, db); out2: free(fdbname); free(fmkey); return ret; }
/*-------------------------------------------------------------------------*/ svalue_t * v_sl_exec (svalue_t * sp, int num_arg) /* EFUN sl_exec() * * mixed* sl_exec(string statement, ...) * * Executes the SQL statement <statement> for the current * SQLite database. The SQL statement may contain wildcards like * '?' and '?nnn', where 'nnn' is an integer. These wildcards * can be given as further parameters to sl_exec. With '?nnn' * the number of a specific parameter can be given, the first * parameter has number 1. * * If the statement returns data, sl_exec returns an array * with each row (which is itself an array of columns) as * an element. */ { svalue_t *argp; sqlite_dbs_t *db; sqlite3_stmt *stmt; const char* tail; int err, rows, cols, num; struct sl_exec_cleanup_s * rec_data; vector_t * result; argp = sp - num_arg + 1; /* First argument: the SQL query */ db = find_db (current_object); if (!db) errorf("The current object doesn't have a database open.\n"); err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str), &stmt, &tail); if(err) { const char* msg = sqlite3_errmsg(db->db); if(stmt) sqlite3_finalize(stmt); errorf("sl_exec: %s\n", msg); /* NOTREACHED */ } /* Now bind all parameters. */ for(argp++, num=1; argp <= sp; argp++, num++) { switch(argp->type) { default: sqlite3_finalize(stmt); errorf("Bad argument %d to sl_exec(): type %s\n", num+1, typename(argp->type)); break; /* NOTREACHED */ case T_FLOAT: sqlite3_bind_double(stmt, num, READ_DOUBLE(argp)); break; case T_NUMBER: if (sizeof(argp->u.number) > 4) sqlite3_bind_int64(stmt, num, argp->u.number); else sqlite3_bind_int(stmt, num, argp->u.number); break; case T_STRING: sqlite3_bind_text(stmt, num, get_txt(argp->u.str), mstrsize(argp->u.str), SQLITE_STATIC); break; } } rows = 0; cols = sqlite3_column_count(stmt); rec_data = xalloc(sizeof(*rec_data)); if(!rec_data) { sqlite3_finalize(stmt); errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n", (unsigned long) sizeof(*rec_data)); } rec_data->rows = NULL; rec_data->stmt = stmt; sp = push_error_handler(sl_exec_cleanup, &(rec_data->head)); while((err = sqlite3_step(stmt)) == SQLITE_ROW) { int col; sqlite_rows_t *this_row; rows++; this_row = pxalloc(sizeof(*this_row)); if(!this_row) errorf("(sl_exec) Out of memory: (%lu bytes)\n", (unsigned long) sizeof(*this_row)); this_row->last = rec_data->rows; rec_data->rows = this_row; this_row->row = NULL; /* Because allocate_array may throw an error. */ this_row->row = allocate_array(cols); if(!this_row->row) errorf("(sl_exec) Out of memory: row vector\n"); for(col = 0; col < cols; col++) { svalue_t * entry; STORE_DOUBLE_USED; entry = this_row->row->item + col; switch(sqlite3_column_type(stmt, col)) { default: errorf( "sl_exec: Unknown type %d.\n" , sqlite3_column_type(stmt, col)); break; case SQLITE_BLOB: errorf("sl_exec: Blob columns are not supported.\n"); break; case SQLITE_INTEGER: if (sizeof(entry->u.number) >= 8) put_number(entry, sqlite3_column_int64(stmt, col)); else put_number(entry, sqlite3_column_int(stmt, col)); break; case SQLITE_FLOAT: entry->type = T_FLOAT; STORE_DOUBLE(entry, sqlite3_column_double(stmt, col)); break; case SQLITE_TEXT: put_c_n_string( entry , (char *)sqlite3_column_text(stmt, col) , sqlite3_column_bytes(stmt, col)); break; case SQLITE_NULL: /* All elements from this_row->row are initialized to 0. */ break; } } } sqlite3_finalize(stmt); rec_data->stmt = NULL; switch(err) { default: errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err); break; case SQLITE_BUSY: errorf("sl_exec: Database is locked.\n"); break; case SQLITE_ERROR: errorf("sl_exec: %s\n", sqlite3_errmsg(db->db)); break; case SQLITE_MISUSE: errorf("sl_exec: sqlite3_step was called inappropriately.\n"); break; case SQLITE_DONE: break; } if(rows) { sqlite_rows_t *this_row; result = allocate_array(rows); if(!result) errorf("(sl_exec) Out of memory: result vector\n"); this_row = rec_data->rows; while(rows--) { put_array(result->item + rows, this_row->row); this_row->row = NULL; this_row = this_row->last; } } else result = NULL; // Pop arguments and our error handler. // Our error handler gets called and cleans the row stuff. sp = pop_n_elems(num_arg + 1, sp) + 1; if(rows) put_array(sp,result); else put_number(sp, 0); return sp; } /* v_sl_exec() */
/*-------------------------------------------------------------------------*/ svalue_t * f_sl_open (svalue_t *sp) /* EFUN sl_open * * int sl_open(string filename) * * Opens the file <filename> for use as a SQLite database. * If the file doesn't exists it will be created. * Only one open file per object is allowed. On success this * function returns 1, otherwise usually an error is thrown. */ { string_t *file; sqlite3 *db; sqlite_dbs_t *tmp; int err; file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE); if (!file) errorf("Illegal use of sl_open('%s')\n", get_txt(sp->u.str)); tmp = find_db (current_object); if (tmp) { free_mstring(file); errorf("The current object already has a database open.\n"); } err = sqlite3_open (get_txt(file), &db); free_mstring(file); if (err) { const char* msg = sqlite3_errmsg(db); sqlite3_close(db); errorf("sl_open: %s\n", msg ); /* NOTREACHED */ } /* create a new chain link and hang on the old chain */ tmp = new_db(); if(!tmp) { sqlite3_close(db); errorf("(sl_open) Out of memory: (%lu bytes)\n", (unsigned long) sizeof(*tmp)); } tmp->db = db; tmp->obj = current_object; current_object->open_sqlite_db = MY_TRUE; /* Synchronous is damn slow. Forget it. */ sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, NULL); sqlite3_set_authorizer(db, my_sqlite3_authorizer, NULL); free_string_svalue (sp); put_number (sp, 1); return sp; } /* f_sl_open() */
int nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) { FILE *fp; char *line, *cp, *entry, *arg1, *arg2; size_t len; int cnt; const unsigned int initial_error_message_count = error_message_count; /* Open the configuration file. */ fp = fopen (fname, "r"); if (fp == NULL) return -1; /* The stream is not used by more than one thread. */ (void) __fsetlocking (fp, FSETLOCKING_BYCALLER); line = NULL; len = 0; do { ssize_t n = getline (&line, &len, fp); if (n < 0) break; if (line[n - 1] == '\n') line[n - 1] = '\0'; /* Because the file format does not know any form of quoting we can search forward for the next '#' character and if found make it terminating the line. */ *strchrnul (line, '#') = '\0'; /* If the line is blank it is ignored. */ if (line[0] == '\0') continue; entry = line; while (isspace (*entry) && *entry != '\0') ++entry; cp = entry; while (!isspace (*cp) && *cp != '\0') ++cp; arg1 = cp; ++arg1; *cp = '\0'; if (strlen (entry) == 0) error (0, 0, _("Parse error: %s"), line); while (isspace (*arg1) && *arg1 != '\0') ++arg1; cp = arg1; while (!isspace (*cp) && *cp != '\0') ++cp; arg2 = cp; ++arg2; *cp = '\0'; if (strlen (arg2) > 0) { while (isspace (*arg2) && *arg2 != '\0') ++arg2; cp = arg2; while (!isspace (*cp) && *cp != '\0') ++cp; *cp = '\0'; } if (strcmp (entry, "positive-time-to-live") == 0) { int idx = find_db (arg1); if (idx >= 0) dbs[idx].postimeout = atol (arg2); } else if (strcmp (entry, "negative-time-to-live") == 0) { int idx = find_db (arg1); if (idx >= 0) dbs[idx].negtimeout = atol (arg2); } else if (strcmp (entry, "suggested-size") == 0) { int idx = find_db (arg1); if (idx >= 0) dbs[idx].suggested_module = atol (arg2) ?: DEFAULT_SUGGESTED_MODULE; } else if (strcmp (entry, "enable-cache") == 0) { int idx = find_db (arg1); if (idx >= 0) { if (strcmp (arg2, "no") == 0) dbs[idx].enabled = 0; else if (strcmp (arg2, "yes") == 0) dbs[idx].enabled = 1; } } else if (strcmp (entry, "check-files") == 0) { int idx = find_db (arg1); if (idx >= 0) { if (strcmp (arg2, "no") == 0) dbs[idx].check_file = 0; else if (strcmp (arg2, "yes") == 0) dbs[idx].check_file = 1; } } else if (strcmp (entry, "max-db-size") == 0) { int idx = find_db (arg1); if (idx >= 0) dbs[idx].max_db_size = atol (arg2) ?: DEFAULT_MAX_DB_SIZE; }
void replication_run(void) { if (!session) { return; } jsonrpc_session_run(session); for (int i = 0; jsonrpc_session_is_connected(session) && i < 50; i++) { struct jsonrpc_msg *msg; unsigned int seqno; seqno = jsonrpc_session_get_seqno(session); if (seqno != session_seqno || state == RPL_S_INIT) { session_seqno = seqno; request_ids_clear(); struct jsonrpc_msg *request; request = jsonrpc_create_request("list_dbs", json_array_create_empty(), NULL); request_ids_add(request->id, NULL); jsonrpc_session_send(session, request); replication_dbs_destroy(); replication_dbs = replication_db_clone(&local_dbs); state = RPL_S_DB_REQUESTED; VLOG_DBG("Send list_dbs request"); } msg = jsonrpc_session_recv(session); if (!msg) { continue; } if (msg->type == JSONRPC_NOTIFY && state != RPL_S_ERR && !strcmp(msg->method, "update")) { if (msg->params->type == JSON_ARRAY && msg->params->u.array.n == 2 && msg->params->u.array.elems[0]->type == JSON_STRING) { char *db_name = msg->params->u.array.elems[0]->u.string; struct ovsdb *db = find_db(db_name); if (db) { struct ovsdb_error *error; error = process_notification(msg->params->u.array.elems[1], db); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } } } } else if (msg->type == JSONRPC_REPLY) { struct ovsdb *db; if (!request_ids_lookup_and_free(msg->id, &db)) { VLOG_WARN("received unexpected reply"); goto next; } switch (state) { case RPL_S_DB_REQUESTED: if (msg->result->type != JSON_ARRAY) { struct ovsdb_error *error; error = ovsdb_error("list-dbs failed", "list_dbs response is not array"); ovsdb_error_assert(error); state = RPL_S_ERR; } else { size_t i; for (i = 0; i < msg->result->u.array.n; i++) { const struct json *name = msg->result->u.array.elems[i]; if (name->type == JSON_STRING) { /* Send one schema request for each remote DB. */ const char *db_name = json_string(name); struct ovsdb *db = find_db(db_name); if (db) { struct jsonrpc_msg *request = jsonrpc_create_request( "get_schema", json_array_create_1( json_string_create(db_name)), NULL); request_ids_add(request->id, db); jsonrpc_session_send(session, request); } } } VLOG_DBG("Send schema requests"); state = RPL_S_SCHEMA_REQUESTED; } break; case RPL_S_SCHEMA_REQUESTED: { struct ovsdb_schema *schema; struct ovsdb_error *error; error = ovsdb_schema_from_json(msg->result, &schema); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } if (db != find_db(schema->name)) { /* Unexpected schema. */ VLOG_WARN("unexpected schema %s", schema->name); state = RPL_S_ERR; } else if (!ovsdb_schema_equal(schema, db->schema)) { /* Schmea version mismatch. */ VLOG_INFO("Schema version mismatch, %s not replicated", schema->name); shash_find_and_delete(replication_dbs, schema->name); } ovsdb_schema_destroy(schema); /* After receiving schemas, reset the local databases that * will be monitored and send out monitor requests for them. */ if (hmap_is_empty(&request_ids)) { struct shash_node *node, *next; SHASH_FOR_EACH_SAFE (node, next, replication_dbs) { db = node->data; struct ovsdb_error *error = reset_database(db); if (error) { const char *db_name = db->schema->name; shash_find_and_delete(replication_dbs, db_name); ovsdb_error_assert(error); VLOG_WARN("Failed to reset database, " "%s not replicated.", db_name); } } if (shash_is_empty(replication_dbs)) { VLOG_WARN("Nothing to replicate."); state = RPL_S_ERR; } else { SHASH_FOR_EACH (node, replication_dbs) { db = node->data; struct ovsdb *db = node->data; struct jsonrpc_msg *request = create_monitor_request(db); request_ids_add(request->id, db); jsonrpc_session_send(session, request); VLOG_DBG("Send monitor requests"); state = RPL_S_MONITOR_REQUESTED; } } } break; } case RPL_S_MONITOR_REQUESTED: { /* Reply to monitor requests. */ struct ovsdb_error *error; error = process_notification(msg->result, db); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } else { /* Transition to replicating state after receiving * all replies of "monitor" requests. */ if (hmap_is_empty(&request_ids)) { VLOG_DBG("Listening to monitor updates"); state = RPL_S_REPLICATING; } } break; } case RPL_S_ERR: /* Ignore all messages */ break; case RPL_S_INIT: case RPL_S_REPLICATING: default: OVS_NOT_REACHED(); } }
int main(int argc, char* argv[]) { int i; char* arg; char db_file[512]; // Setup default configuration for the execution opts.cmd = LAST_N; opts.c_recs = 10; opts.sleep = 1 * 1000; opts.verbose = FALSE; opts.db_file = db_file; opts.db = 0; opts._last_row_id = -1; trap_signals(); if(! find_db(db_file) ) error("Failed to find cislogs.sdb, set the " ENV_VAR " environment variable to the location to the file"); // Command line parsing for(i=1; i<argc; i++){ arg = argv[i]; if( arg[0] == '-' ) { arg++; if( strlen(arg) == 0 ) { continue; } else if( arg[0] == 'h' || arg[0] == '?' ) { usage(); } else if( isdigits(arg) ) { opts.c_recs = atoi(arg); } else if( strcmp("f",arg)==0 ) { opts.cmd = FOLLOW; } else if( strcmp("a",arg)==0 ) { opts.cmd = ALL; } else if( strcmp("v",arg)==0 ) { opts.verbose = TRUE; } else if( strcmp("V",arg)==0 ) { printf("Version: " VERSION "\n"); terminate(0); } else if( strcmp("s",arg)==0 ) { if( i+1 < argc) { arg = argv[++i]; if( !isdigits(arg) ) { error("sleep interval must be numeric"); } opts.sleep = atoi(arg) * 1000; if( opts.sleep <= 0 ) { error("sleep interval must be larger than zero"); } } else { error("Option \"-s N\" must have number of seconds as an argument"); } } else { error("Invalid option: %s", argv[i]); } } else { error("Invalid argument: %s", argv[i]); } } // END command line parsing if(opts.verbose) { printf("Using firewall db file: %s\n\n", opts.db_file); } tail(); terminate(0); }