예제 #1
0
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;
}
예제 #2
0
파일: pkg-sqlite.c 프로젝트: Fuchur/ldmud
/*-------------------------------------------------------------------------*/
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() */
예제 #3
0
파일: pkg-sqlite.c 프로젝트: Fuchur/ldmud
/*-------------------------------------------------------------------------*/
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() */
예제 #4
0
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;
}
예제 #5
0
파일: pkg-sqlite.c 프로젝트: Fuchur/ldmud
/*-------------------------------------------------------------------------*/
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() */
예제 #6
0
파일: pkg-sqlite.c 프로젝트: Fuchur/ldmud
/*-------------------------------------------------------------------------*/
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() */
예제 #7
0
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;
	}
예제 #8
0
파일: replication.c 프로젝트: exuuwen/study
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();
            }
        }
예제 #9
0
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);
}