Example #1
0
pa_database* pa_database_open(const char *fn, bool for_write) {
    GDBM_FILE f;
    int gdbm_cache_size;
    char *path;

    pa_assert(fn);

    /* We include the host identifier in the file name because gdbm
     * files are CPU dependent, and we don't want things to go wrong
     * if we are on a multiarch system. */
    path = pa_sprintf_malloc("%s."CANONICAL_HOST".gdbm", fn);
    errno = 0;

    /* We need to set the block size explicitly here, since otherwise
     * gdbm takes the native block size of the underlying file system
     * which might be incredibly large. */
    f = gdbm_open((char*) path, 1024, GDBM_NOLOCK | (for_write ? GDBM_WRCREAT : GDBM_READER), 0644, NULL);

    if (f)
        pa_log_debug("Opened GDBM database '%s'", path);

    pa_xfree(path);

    if (!f) {
        if (errno == 0)
            errno = EIO;
        return NULL;
    }

    /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
    gdbm_cache_size = 10;
    gdbm_setopt(f, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));

    return (pa_database*) f;
}
Example #2
0
LDBM
ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize )
{
	LDBM		db;
#ifdef HAVE_ST_BLKSIZE
		struct stat	st;
#endif
#ifdef HAVE_EBCDIC
	char n2[2048];

	strncpy(n2, name, sizeof(n2)-1);
	n2[sizeof(n2)-1] = '\0';
	__atoe(n2);
	name = n2;
#endif

	LDBM_WLOCK;

	if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) {
		LDBM_WUNLOCK;
		return( NULL );
	}

#ifdef HAVE_ST_BLKSIZE
	if ( dbcachesize > 0 && stat( name, &st ) == 0 ) {
		dbcachesize /= st.st_blksize;
		if( dbcachesize == 0 ) dbcachesize = 1;
		gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
	}
#else
	if ( dbcachesize > 0 ) {
		dbcachesize /= 4096;
		if( dbcachesize == 0 ) dbcachesize = 1;
		gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
	}
#endif

	LDBM_WUNLOCK;

	return( db );
}
Example #3
0
/* perform read command */
int doread(char *name, int rnum){
  GDBM_FILE dbf;
  datum key, content;
  int i, err, optval, len;
  char buf[RECBUFSIZ];
  if(showprgr) printf("<Reading Test>\n  name=%s  rnum=%d\n\n", name, rnum);
  /* open a database */
  if(!(dbf = gdbm_open(name, 0, GDBM_READER, 00644, NULL))){
    fprintf(stderr, "gdbm_open failed\n");
    return 1;
  }
  optval = CACHESIZE;
  if(gdbm_setopt(dbf, GDBM_CACHESIZE, &optval, sizeof(int)) != 0){
    fprintf(stderr, "gdbm_setopt failed\n");
    gdbm_close(dbf);
    return 1;
  }
  err = FALSE;
  /* loop for each record */
  for(i = 1; i <= rnum; i++){
    /* retrieve a record */
    len = sprintf(buf, "%08d", i);
    key.dptr = buf;
    key.dsize = len;
    content = gdbm_fetch(dbf, key);
    if(!content.dptr){
      fprintf(stderr, "gdbm_fetch failed\n");
      err = TRUE;
      break;
    }
    free(content.dptr);
    /* print progression */
    if(showprgr && rnum > 250 && i % (rnum / 250) == 0){
      putchar('.');
      fflush(stdout);
      if(i == rnum || i % (rnum / 10) == 0){
        printf(" (%08d)\n", i);
        fflush(stdout);
      }
    }
  }
  /* close the database */
  gdbm_close(dbf);
  if(showprgr && !err) printf("ok\n\n");
  return err ? 1 : 0;
}
static rlm_rcode_t reset_db(rlm_counter_t *inst)
{
	int cache_size = inst->cache_size;
	rlm_rcode_t rcode;

	DEBUG2("rlm_counter: reset_db: Closing database");
	gdbm_close(inst->gdbm);

	/*
	 *	Open a completely new database.
	 */
	{
		char *filename;

		memcpy(&filename, &inst->filename, sizeof(filename));
		inst->gdbm = gdbm_open(filename, sizeof(int), GDBM_NEWDB | GDBM_COUNTER_OPTS, 0600, NULL);
	}
	if (!inst->gdbm) {
		ERROR("rlm_counter: Failed to open file %s: %s", inst->filename, fr_syserror(errno));
		return RLM_MODULE_FAIL;
	}
	if (gdbm_setopt(inst->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(cache_size)) == -1) {
		ERROR("rlm_counter: Failed to set cache size");
	}

	DEBUG2("rlm_counter: reset_db: Opened new database");

	/*
	 * Add defaults
	 */
	rcode = add_defaults(inst);
	if (rcode != RLM_MODULE_OK)
		return rcode;

	DEBUG2("rlm_counter: reset_db ended");

	return RLM_MODULE_OK;
}
Example #5
0
/*
*	execute the 'index' function
*/
int		sblib_func_exec(int index, int param_count, slib_par_t *params, var_t *retval)
{
	int		success = 0;

	switch ( index )	{
	case	0:	// handle <- GDBM_OPEN(file[, block_size, flags, mode])
		{
			char	*file;
			int		bsize, flags, mode;

			success = mod_parstr_ptr(0, params, param_count, &file);
			success = mod_opt_parint(1, params, param_count, &bsize, 0);
			success = mod_opt_parint(2, params, param_count, &flags, GDBM_WRCREAT);
			success = mod_opt_parint(3, params, param_count, &mode, 0666);
		
			if	( success )	{
				int		handle;

				handle = get_free_handle();
				if	( handle >= 0 )	{
					table[handle].dbf = gdbm_open(file, bsize, flags, mode, NULL);
					success = (table[handle].dbf != NULL);
					if	( success )	
						v_setint(retval, handle);
					else
						v_setstr(retval, gdbm_strerror(gdbm_errno));
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_OPEN: NO FREE HANDLES");
					}
				}
			else
				v_setstr(retval, "GDBM_OPEN: argument error");
		}
		break;

	case	1:	// handle <- GDBM_STORE(handle, key, data [, flags])
		{
			int		handle, flags;
			char	*key, *data;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parstr_ptr(1, params, param_count, &key);
			success = mod_parstr_ptr(2, params, param_count, &data);
			success = mod_opt_parint(3, params, param_count, &flags, GDBM_REPLACE);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key, dt_data;
					int		r;

					dt_key.dptr   = key;
					dt_key.dsize  = strlen(key) + 1;
					dt_data.dptr  = data;
					dt_data.dsize = strlen(data) + 1;
					
					r = gdbm_store(table[handle].dbf, dt_key, dt_data, flags);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_STORE: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_STORE: argument error");
		}
		break;

	case	2:	// data <- GDBM_FETCH(handle, key)
		{
			int		handle;
			char	*key;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parstr_ptr(1, params, param_count, &key);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key, dt_data;

					dt_key.dptr   = key;
					dt_key.dsize  = strlen(key) + 1;
					
					dt_data = gdbm_fetch(table[handle].dbf, dt_key);
					v_setstr(retval, (char *) dt_data.dptr);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_FETCH: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_FETCH: argument error");
		}
		break;

	case	3:	// status <- GDBM_DELETE(handle, key)
		{
			int		handle;
			char	*key;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parstr_ptr(1, params, param_count, &key);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key;
					int		r;

					dt_key.dptr   = key;
					dt_key.dsize  = strlen(key) + 1;
					
					r = gdbm_delete(table[handle].dbf, dt_key);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_DELETE: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_DELETE: argument error");
		}
		break;

	case	4:	// key <- GDBM_FIRSTKEY(handle)
		{
			int		handle;

			success = mod_parint    (0, params, param_count, &handle);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key;

					dt_key = gdbm_firstkey(table[handle].dbf);
					v_setstr(retval, (char *) dt_key.dptr);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_FIRSTKEY: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_FIRSTKEY: argument error");
		}
		break;

	case	5:	// key <- GDBM_NEXTKEY(handle, key)
		{
			int		handle;
			char	*key;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parstr_ptr(1, params, param_count, &key);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key;

					dt_key.dptr   = key;
					dt_key.dsize  = strlen(key) + 1;

					dt_key = gdbm_nextkey(table[handle].dbf, dt_key);
					v_setstr(retval, (char *) dt_key.dptr);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_NEXTKEY: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_NEXTKEY: argument error");
		}
		break;

	case	6:	// status <- GDBM_REORGANIZE(handle)
		{
			int		handle;

			success = mod_parint    (0, params, param_count, &handle);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					int		r;

					r = gdbm_reorganize(table[handle].dbf);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_REORGANIZE: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_REORGANIZE: argument error");
		}
		break;

	case	7:	// status <- GDBM_EXISTS(handle, key)
		{
			int		handle;
			char	*key;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parstr_ptr(1, params, param_count, &key);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					datum	dt_key;
					int		r;

					dt_key.dptr   = key;
					dt_key.dsize  = strlen(key) + 1;

					r = gdbm_exists(table[handle].dbf, dt_key);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_EXISTS: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_EXISTS: argument error");
		}
		break;

	case	8:	// str <- GDBM_STRERROR()
		v_setstr(retval, gdbm_strerror(gdbm_errno));
		break;

	case	9:	// status <- GDBM_SETOPT(handle, option, value, size)
		{
			int		handle, option, value, size;

			success = mod_parint    (0, params, param_count, &handle);
			success = mod_parint    (1, params, param_count, &option);
			success = mod_parint    (2, params, param_count, &value);
			success = mod_parint    (3, params, param_count, &size);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					int		r;

					r = gdbm_setopt(table[handle].dbf, option, &value, size);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_SETOPT: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_SETOPT: argument error");
		}
		break;

	case	10:	// status <- GDBM_FDESC(handle)
		{
			int		handle;

			success = mod_parint    (0, params, param_count, &handle);
			if	( success )	{
				if	( is_valid_handle(handle) )	{
					int		r;

					r = gdbm_fdesc(table[handle].dbf);
					v_setint(retval, r);
					success = 1;
					}
				else	{
					success = 0;
					v_setstr(retval, "GDBM_FDESC: INVALID HANDLE");
					}
				}
			else
				v_setstr(retval, "GDBM_FDESC: argument error");
		}
		break;

	default:
		v_setstr(retval, "GDBM: function does not exist!");
		}

	return success;
}
Example #6
0
/*
 *	Do any per-module initialization that is separate to each
 *	configured instance of the module.  e.g. set up connections
 *	to external databases, read configuration files, set up
 *	dictionary entries, etc.
 *
 *	If configuration information is given in the config section
 *	that must be referenced in later calls, store a handle to it
 *	in *instance otherwise put a null pointer there.
 */
static int caching_instantiate(CONF_SECTION *conf, void **instance)
{
	rlm_caching_t *data;
	int cache_size;

	/*
	 *	Set up a storage area for instance data
	 */
	data = rad_malloc(sizeof(*data));
	if (!data) {
		radlog(L_ERR, "rlm_caching: rad_malloc() failed.");
		return -1;
	}
	memset(data, 0, sizeof(*data));

	/*
	 *	If the configuration parameters can't be parsed, then
	 *	fail.
	 */
	if (cf_section_parse(conf, data, module_config) < 0) {
		free(data);
		return -1;
	}
	cache_size = data->cache_size;

	/*
	 *	Discover the attribute number of the key.
	 */
	if (data->key == NULL) {
		radlog(L_ERR, "rlm_caching: 'key' must be set.");
		caching_detach(data);
		return -1;
	}
	if (data->cache_ttl_str == NULL) {
		radlog(L_ERR, "rlm_caching: 'cache-ttl' must be set.");
		caching_detach(data);
		return -1;
	}
	else {
		data->cache_ttl = find_ttl(data->cache_ttl_str);
		if (data->cache_ttl == 0) {
			radlog(L_ERR, "rlm_caching: 'cache-ttl' is invalid.");
			caching_detach(data);
			return -1;
		}
	}

	if (data->filename == NULL) {
		radlog(L_ERR, "rlm_caching: 'filename' must be set.");
		caching_detach(data);
		return -1;
	}
	data->gdbm = gdbm_open(data->filename, sizeof(int),
			GDBM_WRCREAT | GDBM_COUNTER_OPTS, 0600, NULL);
	if (data->gdbm == NULL) {
		radlog(L_ERR, "rlm_caching: Failed to open file %s: %s",
				data->filename, strerror(errno));
		caching_detach(data);
		return -1;
	}
	if (gdbm_setopt(data->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
		radlog(L_ERR, "rlm_caching: Failed to set cache size");

	/*
	 * Init the mutex
	 */
	pthread_mutex_init(&data->mutex, NULL);

	*instance = data;

	return 0;
}
/*
 *	Do any per-module initialization that is separate to each
 *	configured instance of the module.  e.g. set up connections
 *	to external databases, read configuration files, set up
 *	dictionary entries, etc.
 *
 *	If configuration information is given in the config section
 *	that must be referenced in later calls, store a handle to it
 *	in *instance otherwise put a null pointer there.
 */
static int mod_instantiate(CONF_SECTION *conf, void *instance)
{
	rlm_counter_t *inst = instance;
	DICT_ATTR const *da;
	DICT_VALUE *dval;
	ATTR_FLAGS flags;
	time_t now;
	int cache_size;
	int ret;
	datum key_datum;
	datum time_datum;
	char const *default1 = "DEFAULT1";
	char const *default2 = "DEFAULT2";

	cache_size = inst->cache_size;

	da = dict_attrbyname(inst->key_name);
	rad_assert(da != NULL);
	inst->key_attr = da;

	/*
	 *	Discover the attribute number of the counter.
	 */
	da = dict_attrbyname(inst->count_attribute);
	rad_assert(da != NULL);
	inst->count_attr = da;

	/*
	 * Discover the attribute number of the reply attribute.
	 */
	if (inst->reply_name != NULL) {
		da = dict_attrbyname(inst->reply_name);
		if (!da) {
			cf_log_err_cs(conf, "No such attribute %s", inst->reply_name);
			return -1;
		}
		if (da->type != PW_TYPE_INTEGER) {
			cf_log_err_cs(conf, "Reply attribute' %s' is not of type integer", inst->reply_name);
			return -1;
		}
		inst->reply_attr = da;
	} else {
		inst->reply_attr = NULL;
	}

	/*
	 *  Create a new attribute for the counter.
	 */
	rad_assert(inst->counter_name && *inst->counter_name);
	memset(&flags, 0, sizeof(flags));
	if (dict_addattr(inst->counter_name, -1, 0, PW_TYPE_INTEGER, flags) < 0) {
		ERROR("rlm_counter: Failed to create counter attribute %s: %s", inst->counter_name, fr_strerror());
		return -1;
	}

	da = dict_attrbyname(inst->counter_name);
	if (!da) {
		cf_log_err_cs(conf, "Failed to find counter attribute %s", inst->counter_name);
		return -1;
	}
	inst->dict_attr = da;
	DEBUG2("rlm_counter: Counter attribute %s is number %d", inst->counter_name, inst->dict_attr->attr);

	/*
	 * Create a new attribute for the check item.
	 */
	rad_assert(inst->check_name && *inst->check_name);
	if (dict_addattr(inst->check_name, -1, 0, PW_TYPE_INTEGER, flags) < 0) {
		ERROR("rlm_counter: Failed to create check attribute %s: %s", inst->counter_name, fr_strerror());
		return -1;

	}
	da = dict_attrbyname(inst->check_name);
	if (!da) {
		ERROR("rlm_counter: Failed to find check attribute %s", inst->counter_name);
		return -1;
	}
	inst->check_attr = da;

	/*
	 * Find the attribute for the allowed protocol
	 */
	if (inst->service_type != NULL) {
		if ((dval = dict_valbyname(PW_SERVICE_TYPE, 0, inst->service_type)) == NULL) {
			ERROR("rlm_counter: Failed to find attribute number for %s", inst->service_type);
			return -1;
		}
		inst->service_val = dval->value;
	}

	/*
	 * Find when to reset the database.
	 */
	rad_assert(inst->reset && *inst->reset);
	now = time(NULL);
	inst->reset_time = 0;
	inst->last_reset = now;

	if (find_next_reset(inst,now) == -1) {
		ERROR("rlm_counter: find_next_reset() returned -1. Exiting");
		return -1;
	}

	{
		char *filename;

		memcpy(&filename, &inst->filename, sizeof(filename));
		inst->gdbm = gdbm_open(filename, sizeof(int), GDBM_NEWDB | GDBM_COUNTER_OPTS, 0600, NULL);
	}
	if (!inst->gdbm) {
		ERROR("rlm_counter: Failed to open file %s: %s", inst->filename, fr_syserror(errno));
		return -1;
	}
	if (gdbm_setopt(inst->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(cache_size)) == -1) {
		ERROR("rlm_counter: Failed to set cache size");
	}

	/*
	 * Look for the DEFAULT1 entry. This entry if it exists contains the
	 * time of the next database reset. This time is set each time we reset
	 * the database. If next_reset < now then we reset the database.
	 * That way we can overcome the problem where radiusd is down during a database
	 * reset time. If we did not keep state information in the database then the reset
	 * would be extended and that would create problems.
	 *
	 * We also store the time of the last reset in the DEFAULT2 entry.
	 *
	 * If DEFAULT1 and DEFAULT2 do not exist (new database) we add them to the database
	 */

	memcpy(&key_datum.dptr, &default1, sizeof(key_datum.dptr));
	key_datum.dsize = strlen(key_datum.dptr);

	time_datum = gdbm_fetch(inst->gdbm, key_datum);
	if (time_datum.dptr != NULL) {
		time_t next_reset = 0;

		memcpy(&next_reset, time_datum.dptr, sizeof(time_t));
		free(time_datum.dptr);
		time_datum.dptr = NULL;
		if (next_reset && next_reset <= now) {

			inst->last_reset = now;
			ret = reset_db(inst);
			if (ret != RLM_MODULE_OK) {
				ERROR("rlm_counter: reset_db() failed");
				return -1;
			}
		} else {
			inst->reset_time = next_reset;
		}

		memcpy(&key_datum.dptr, &default2, sizeof(key_datum.dptr));
		key_datum.dsize = strlen(key_datum.dptr);

		time_datum = gdbm_fetch(inst->gdbm, key_datum);
		if (time_datum.dptr != NULL) {
			memcpy(&inst->last_reset, time_datum.dptr, sizeof(time_t));
			free(time_datum.dptr);
		}
	} else {
		ret = add_defaults(inst);
		if (ret != RLM_MODULE_OK) {
			ERROR("rlm_counter: add_defaults() failed");
			return -1;
		}
	}


	/*
	 *	Register the counter comparison operation.
	 * FIXME: move all attributes to DA
	 */
	paircompare_register(inst->dict_attr, NULL, true, counter_cmp, inst);

	/*
	 * Init the mutex
	 */
	pthread_mutex_init(&inst->mutex, NULL);

	return 0;
}
Example #8
0
int
main (int argc, char **argv)
{
  GDBM_FILE dbf = NULL;
  int rc, opt;
  char *dbname, *filename;
  FILE *fp;
  unsigned long err_line, n;
  char *end;
  int oflags = GDBM_NEWDB|GDBM_NOMMAP;
  int cache_size = 0;
  int block_size = 0;
  
#ifdef HAVE_SETLOCALE
  setlocale (LC_ALL, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  set_progname (argv[0]);

  for (opt = parseopt_first (argc, argv, optab);
       opt != EOF;
       opt = parseopt_next ())
    {
    switch (opt)
      {
      case 'b':
	block_size = get_int (optarg);
	break;
	
      case 'c':
	cache_size = get_int (optarg);
	break;

      case 'm':
	{
	  errno = 0;
	  n = strtoul (optarg, &end, 8);
	  if (*end == 0 && errno == 0)
	    {
	      mode = n & 0777;
	      meta_mask |= GDBM_META_MASK_MODE;
	    }
	  else
	    {
	      error ("%s", _("invalid octal number"));
	      exit (EXIT_USAGE);
	    }
	}
	break;

      case 'u':
	{
	  size_t len;
	  struct passwd *pw;
	  
	  len = strcspn (optarg, ".:");
	  if (optarg[len])
	    optarg[len++] = 0;
	  pw = getpwnam (optarg);
	  if (pw)
	    owner_uid = pw->pw_uid;
	  else
	    {
	      errno = 0;
	      n = strtoul (optarg, &end, 10);
	      if (*end == 0 && errno == 0)
		owner_uid = n;
	      else
		{
		  error (_("invalid user name: %s"), optarg);
		  exit (EXIT_USAGE);
		}
	    }
	  
	  if (optarg[len])
	    {
	      char *grname = optarg + len;
	      struct group *gr = getgrnam (grname);
	      if (gr)
		owner_gid = gr->gr_gid;
	      else
		{
		  errno = 0;
		  n = strtoul (grname, &end, 10);
		  if (*end == 0 && errno == 0)
		    owner_gid = n;
		  else
		    {
		      error (_("invalid group name: %s"), grname);
		      exit (EXIT_USAGE);
		    }
		}
	    }
	  else
	    {
	      if (!pw)
		{
		  pw = getpwuid (owner_uid);
		  if (!pw)
		    {
		      error (_("no such UID: %lu"), (unsigned long)owner_uid);
		      exit (EXIT_USAGE);
		    }
		}
	      owner_gid = pw->pw_gid;
	    }
	  meta_mask |= GDBM_META_MASK_OWNER;
	}
	break;
	  
      case 'r':
	replace = 1;
	break;

      case 'n':
	no_meta_option = 1;
	break;

      case 'M':
	oflags &= ~GDBM_NOMMAP;
	break;
	
      default:
	error (_("unknown option"));
	exit (EXIT_USAGE);
      }
    }

  argc -= optind;
  argv += optind;
  
  if (argc == 0)
    {
      parseopt_print_help ();
      exit (EXIT_OK);
    }

  if (argc > 2)
    {
      error (_("too many arguments; try `%s -h' for more info"), progname);
      exit (EXIT_USAGE);
    }
  
  filename = argv[0];
  if (argc == 2)
    dbname = argv[1];
  else
    dbname = NULL;

  if (strcmp (filename, "-") == 0)
    {
      filename = "<stdin>";
      fp = stdin;
    }
  else
    {
      fp = fopen (filename, "r");
      if (!fp)
	{
	  sys_perror (errno, _("cannot open %s"), filename);
	  exit (EXIT_FATAL);
	}
    }
  
  if (dbname)
    {
      dbf = gdbm_open (dbname, block_size, oflags, 0600, NULL);
      if (!dbf)
	{
	  gdbm_perror (_("gdbm_open failed"));
	  exit (EXIT_FATAL);
	}

      if (cache_size &&
	  gdbm_setopt (dbf, GDBM_SETCACHESIZE, &cache_size, sizeof (int)) == -1)
	error (_("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno));
    }
  
  rc = gdbm_load_from_file (&dbf, fp, replace,
			    no_meta_option ?
			      (GDBM_META_MASK_MODE | GDBM_META_MASK_OWNER) :
			      meta_mask,
			    &err_line);
  if (rc)
    {
      switch (gdbm_errno)
	{
	case GDBM_ERR_FILE_OWNER:
	case GDBM_ERR_FILE_MODE:
	  error (_("error restoring metadata: %s (%s)"),
		 gdbm_strerror (gdbm_errno), strerror (errno));
	  rc = EXIT_MILD;
	  break;
	  
	default:
	  if (err_line)
	    gdbm_perror ("%s:%lu", filename, err_line);
	  else
	    gdbm_perror (_("cannot load from %s"), filename);
	  rc = EXIT_FATAL;
	}
    }

  if (dbf)
    {
      if (!no_meta_option && set_meta_info (dbf))
	{
	  error (_("error restoring metadata: %s (%s)"),
		 gdbm_strerror (gdbm_errno), strerror (errno));
	  rc = EXIT_MILD;
	}
      
      if (!dbname)
	{
	  if (gdbm_setopt (dbf, GDBM_GETDBNAME, &dbname, sizeof (dbname)))
	    gdbm_perror (_("gdbm_setopt failed"));
	  else
	    {
	      printf ("%s: created %s\n", progname, dbname);
	      free (dbname);
	    }
	}
      gdbm_close (dbf);
    }
  exit (rc);
}
Example #9
0
int
main (int argc, char **argv)
{
  const char *progname = canonical_progname (argv[0]);
  const char *dbname;
  int line = 0;
  char buf[1024];
  datum key;
  datum data;
  int replace = 0;
  int flags = 0;
  int mode = GDBM_WRCREAT;
  int block_size = 0;
  GDBM_FILE dbf;
  int delim = '\t';
  int data_z = 0;
  size_t mapped_size_max = 0;
  
  while (--argc)
    {
      char *arg = *++argv;

      if (strcmp (arg, "-h") == 0)
	{
	  printf ("usage: %s [-replace] [-clear] [-blocksize=N] [-null] [-nolock] [-nommap] [-maxmap=N] [-sync] [-delim=CHR] DBFILE\n", progname);
	  exit (0);
	}
      else if (strcmp (arg, "-replace") == 0)
	replace |= GDBM_REPLACE;
      else if (strcmp (arg, "-clear") == 0)
	mode = GDBM_NEWDB;
      else if (strcmp (arg, "-null") == 0)
	data_z = 1;
      else if (strcmp (arg, "-nolock") == 0)
	flags |= GDBM_NOLOCK;
      else if (strcmp (arg, "-nommap") == 0)
	flags |= GDBM_NOMMAP;
      else if (strcmp (arg, "-sync") == 0)
	flags |= GDBM_SYNC;
      else if (strncmp (arg, "-blocksize=", 11) == 0)
	block_size = atoi (arg + 11);
      else if (strncmp (arg, "-maxmap=", 8) == 0)
	{
	  char *p;

	  errno = 0;
	  mapped_size_max = strtoul (arg + 8, &p, 10);
	  
	  if (errno)
	    {
	      fprintf (stderr, "%s: ", progname);
	      perror ("maxmap");
	      exit (1);
	    }

	  if (*p)
	    {
	      fprintf (stderr, "%s: bad maxmap\n", progname);
	      exit (1);
	    }
	}
      else if (strncmp (arg, "-delim=", 7) == 0)
	delim = arg[7];
      else if (strcmp (arg, "--") == 0)
	{
	  --argc;
	  ++argv;
	  break;
	}
      else if (arg[0] == '-')
	{
	  fprintf (stderr, "%s: unknown option %s\n", progname, arg);
	  exit (1);
	}
      else
	break;
    }

  if (argc != 1)
    {
      fprintf (stderr, "%s: wrong arguments\n", progname);
      exit (1);
    }
  dbname = *argv;
  
  dbf = gdbm_open (dbname, block_size, mode|flags, 00664, NULL);
  if (!dbf)
    {
      fprintf (stderr, "gdbm_open failed: %s\n", gdbm_strerror (gdbm_errno));
      exit (1);
    }

  if (mapped_size_max)
    {
      if (gdbm_setopt (dbf, GDBM_SETMAXMAPSIZE, &mapped_size_max,
		       sizeof (mapped_size_max)))
	{
	  fprintf (stderr, "gdbm_setopt failed: %s\n",
		   gdbm_strerror (gdbm_errno));
	  exit (1);
	}
    }  
  
  while (fgets (buf, sizeof buf, stdin))
    {
      size_t i, j;
      size_t len = strlen (buf);

      if (buf[len - 1] != '\n')
	{
	  fprintf (stderr, "%s: %d: line too long\n",
		   progname, line);
	  continue;
	}

      buf[--len] = 0;
      
      line++;

      for (i = j = 0; i < len; i++)
	{
	  if (buf[i] == '\\')
	    i++;
	  else if (buf[i] == delim)
	    break;
	  else
	    buf[j++] = buf[i];
	}

      if (buf[i] != delim)
	{
	  fprintf (stderr, "%s: %d: malformed line\n",
		   progname, line);
	  continue;
	}

      key.dptr = buf;
      key.dsize = j + data_z;
      data.dptr = buf + j + 1;
      data.dsize = strlen (buf + j + 1) + data_z;
      if (gdbm_store (dbf, key, data, replace) != 0)
	{
	  fprintf (stderr, "%s: %d: item not inserted\n",
		   progname, line);
	  exit (1);
	}
    }
  gdbm_close (dbf);
  exit (0);
}