Exemplo n.º 1
0
vsdb_ret_t vsdb_set(vsdb_t vsdb, const char *key, size_t key_length,
                                 const void *value, size_t value_size)
{
  DB *db;
  DBT kt, dt;
  int ret;

  if ((db = getdb(vsdb)) == NULL)
    goto failed;
  if (key == NULL)
    goto failed;
  if (key_length == SIZE_T_MAX)
    key_length = strlen(key);
  if (key_length == 0)
    goto failed;

  kt.data = (void *)key;
  kt.size = key_length;

  if (value != NULL) {
    dt.data = (void *)value;
    dt.size = value_size;

    lockdb(vsdb);
    ret = db->put(db, &kt, &dt, 0);
    unlockdb(vsdb);

    if (ret != 0) {
      goto failed;
    }
  }
  else {
    lockdb(vsdb);
    ret = db->del(db, &kt, 0);
    unlockdb(vsdb);

    if (ret != 0) {
      goto failed;
    }
  }

  return vsdb_okay;

failed:
  return vsdb_failed;
}
Exemplo n.º 2
0
int writedb(const char *iface, const char *dirname, int newdb)
{
	FILE *db;
	char file[512], backup[512];

	snprintf(file, 512, "%s/%s", dirname, iface);
	snprintf(backup, 512, "%s/.%s", dirname, iface);

	/* try to make backup of old data if this isn't a new database */
	if (!newdb && !backupdb(file, backup)) {
		snprintf(errorstring, 512, "Unable to create database backup \"%s\".", backup);
		printe(PT_Error);
		return 0;
	}

	/* make sure version stays correct */
	data.version=DBVERSION;

	if ((db=fopen(file,"w"))==NULL) {
		snprintf(errorstring, 512, "Unable to open database \"%s\" for writing: %s", file, strerror(errno));
		printe(PT_Error);
		return 0;
	}

	/* lock file */
	if (!lockdb(fileno(db), 1)) {
		fclose(db);
		return 0;
	}

	/* update timestamp when not merging */
	if (newdb!=2) {
		data.lastupdated=time(NULL);
	}

	if (fwrite(&data,sizeof(DATA),1,db)==0) {
		snprintf(errorstring, 512, "Unable to write database \"%s\": %s", file, strerror(errno));
		printe(PT_Error);
		fclose(db);
		return 0;
	} else {
		if (debug) {
			printf("db: Database \"%s\" saved.\n", file);
		}
		fclose(db);
		if ((newdb) && (noexit==0)) {
			snprintf(errorstring, 512, "-> A new database has been created.");
			printe(PT_Info);
		}
	}

	return 1;
}
Exemplo n.º 3
0
vsdb_ret_t vsdb_sync(vsdb_t vsdb)
{
  DB *db;
  int ret;

  if ((db = getdb(vsdb)) != NULL) {
    lockdb(vsdb);
    ret = db->sync(db, 0);
    unlockdb(vsdb);

    if (ret == 0) {
      return vsdb_okay;
    }
  }

  return vsdb_failed;
}
Exemplo n.º 4
0
vsdb_ret_t vsdb_get(vsdb_t vsdb, const char *key, size_t key_length,
                                 const void **value, size_t *value_size)
{
  DB *db;
  DBT kt, dt;
  DBT newdt;
  int ret;

  if ((db = getdb(vsdb)) == NULL)
    goto failed;
  if (key == NULL || value == NULL || value_size == NULL)
    goto failed;
  if (key_length == SIZE_T_MAX)
    key_length = strlen(key);
  if (key_length == 0)
    goto failed;

  kt.data = (void *)key;
  kt.size = key_length;

  lockdb(vsdb);
  ret = db->get(db, &kt, &dt, 0);
  unlockdb(vsdb);

  if (ret == 0) {
    dup_dbt(&newdt, &dt);
    *value = newdt.data;
    *value_size = newdt.size;
    return vsdb_okay;
  }

failed:
  if (value != NULL)
    *value = NULL;
  if (value_size != NULL)
    *value_size = 0;
  return vsdb_failed;
}
Exemplo n.º 5
0
int readdb(const char *iface, const char *dirname)
{
	FILE *db;
	char file[512], backup[512];
	int newdb=0;

	snprintf(file, 512, "%s/%s", dirname, iface);
	snprintf(backup, 512, "%s/.%s", dirname, iface);

	if ((db=fopen(file,"r"))!=NULL) {

		/* lock file */
		if (!lockdb(fileno(db), 0)) {
			return -1;
		}

		if (fread(&data,sizeof(DATA),1,db)==0) {
			data.version=-1;
			if (debug) {
				printf("db: Database read failed for file \"%s\".\n", file);
			}
		} else {
			if (debug) {
				printf("db: Database loaded for interface \"%s\"...\n", data.interface);
			}
		}

		/* convert old database to new format if necessary */
		if (data.version<DBVERSION) {
			if (data.version!=-1) {
				snprintf(errorstring, 512, "Trying to convert database \"%s\" (v%d) to current db format", file, data.version);
				printe(PT_Info);
			}

			if ((data.version==-1) || (!convertdb(db))) {

				/* close current db and try using backup if database conversion failed */
				fclose(db);
				if ((db=fopen(backup,"r"))!=NULL) {

					/* lock file */
					if (!lockdb(fileno(db), 0)) {
						fclose(db);
						return -1;
					}

					if (fread(&data,sizeof(DATA),1,db)==0) {
						snprintf(errorstring, 512, "Database load failed even when using backup. Aborting.");
						printe(PT_Error);
						fclose(db);

						if (noexit) {
							return -1;
						} else {
							exit(EXIT_FAILURE);
						}
					} else {
						if (debug) {
							printf("db: Database loaded for interface \"%s\"...\n", data.interface);
						}
					}

					if (data.version!=DBVERSION) {
						if (!convertdb(db)) {
							snprintf(errorstring, 512, "Unable to use backup database.");
							printe(PT_Error);
							fclose(db);

							if (noexit) {
								return -1;
							} else {
								exit(EXIT_FAILURE);
							}
						}
					}
					snprintf(errorstring, 512, "Database possibly corrupted, using backup instead.");
					printe(PT_Info);
				} else {
					snprintf(errorstring, 512, "Unable to open backup database \"%s\".", backup);
					printe(PT_Error);
					if (noexit) {
						return -1;
					} else {
						exit(EXIT_FAILURE);
					}
				}
			}

		} else if (data.version>DBVERSION) {
			snprintf(errorstring, 512, "Downgrading database \"%s\" (v%d) is not supported.", file, data.version);
			printe(PT_Error);
			fclose(db);

			if (noexit) {
				return -1;
			} else {
				exit(EXIT_FAILURE);
			}		
		}

		fclose(db);

		if (strcmp(data.interface,iface)) {
			snprintf(errorstring, 512, "Warning:\nThe previous interface for this file was \"%s\".",data.interface);
			printe(PT_Multiline);
			snprintf(errorstring, 512, "It has now been replaced with \"%s\".",iface);
			printe(PT_Multiline);
			snprintf(errorstring, 512, "You can ignore this message if you renamed the filename.");
			printe(PT_Multiline);
			snprintf(errorstring, 512, "Interface name mismatch, renamed \"%s\" -> \"%s\"", data.interface, iface);
			printe(PT_ShortMultiline);
			if (strcmp(data.interface, data.nick)==0) {
				strncpy(data.nick, iface, 32);
			}
			strncpy(data.interface, iface, 32);
		}
	} else {
		snprintf(errorstring, 512, "Unable to read database \"%s\".",file);
		printe(PT_Error);

		newdb=1;
		initdb();
		strncpy(data.interface, iface, 32);
		strncpy(data.nick, data.interface, 32);
	}
	return newdb;
}
Exemplo n.º 6
0
vsdb_ret_t vsdb_glob(vsdb_t vsdb, const char *glob, size_t glob_length,
                                  const char ***keys, size_t **key_lengths,
                                  const void ***values, size_t **value_sizes,
                                  size_t *count)
{
  DB *db;
  DBT kt, dt;
  vsdb_ret_t vsdb_ret;
  int ret;
  size_t i;
  struct {
    DBT *kts, *dts;
    size_t count;
    size_t capacity;
  } buf;

  vsdb_ret = vsdb_okay;
  bzero(&buf, sizeof(buf));
  lockdb(vsdb);

  if ((db = getdb(vsdb)) == NULL)
    goto failed;
  if (glob == NULL)
    goto failed;
  if (glob_length == SIZE_T_MAX)
    glob_length = strlen(glob);
  if (glob_length == 0)
    goto failed;
  if (keys == NULL || key_lengths == NULL || values == NULL || value_sizes == NULL)
    goto failed;
  if (count == NULL)
    goto failed;

  if (glob_length == 1 && glob[0] == '*') {
    if ((ret = db->seq(db, &kt, &dt, R_FIRST)) < 0) {
      goto failed;
    }
    else if (ret == 0) {
      do {
        if (buf.count == buf.capacity) {
          if (buf.capacity == 0) {
            buf.capacity = 16;
            buf.kts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
          }
          else {
            buf.capacity <<= 1;
            buf.kts = (DBT *)realloc(buf.kts, sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)realloc(buf.dts, sizeof(DBT) * buf.capacity);
          }
        }

        dup_dbt(&buf.kts[buf.count], &kt);
        dup_dbt(&buf.dts[buf.count], &dt);
        buf.count++;
      } while ((ret = db->seq(db, &kt, &dt, R_NEXT)) == 0);

      if (ret < 0) {
        goto failed;
      }
    }
  }
  else if (glob_length > 0 && glob[glob_length - 1] == '*') {
    kt.data = (void *)glob;
    kt.size = glob_length - 1;

    if ((ret = db->seq(db, &kt, &dt, R_CURSOR)) < 0) {
      goto failed;
    }
    else if (ret == 0) {
      do {
        if (buf.count == buf.capacity) {
          if (buf.capacity == 0) {
            buf.capacity = 16;
            buf.kts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
          }
          else {
            buf.capacity <<= 1;
            buf.kts = (DBT *)realloc(buf.kts, sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)realloc(buf.dts, sizeof(DBT) * buf.capacity);
          }
        }

        if (strncmp((const char *)kt.data, glob, ((glob_length - 1) < kt.size) ? (glob_length - 1) : kt.size) != 0) {
          break;
        }

        dup_dbt(&buf.kts[buf.count], &kt);
        dup_dbt(&buf.dts[buf.count], &dt);
        buf.count++;
      } while ((ret = db->seq(db, &kt, &dt, R_NEXT)) == 0);

      if (ret < 0) {
        goto failed;
      }
    }
  }
  else {
    goto failed;
  }

  if (buf.count > 0) {
    *keys = (const char **)malloc(sizeof(const char *) * buf.count);
    *key_lengths = (size_t *)malloc(sizeof(size_t) * buf.count);
    *values = (const void **)malloc(sizeof(const void *) * buf.count);
    *value_sizes = (size_t *)malloc(sizeof(size_t) * buf.count);
    *count = buf.count;
    
    for (i = 0; i < buf.count; i++) {
      (*keys)[i] = (const char *)buf.kts[i].data;
      (*key_lengths)[i] = buf.kts[i].size;
      (*values)[i] = buf.dts[i].data;
      (*value_sizes)[i] = buf.dts[i].size;
    }

    goto cleanup;
  }
  else {
    goto reset;
  }

failed:
  vsdb_ret = vsdb_failed;
reset:
  if (keys != NULL)
    *keys = NULL;
  if (key_lengths != NULL)
    *key_lengths = NULL;
  if (values != NULL)
    *values = NULL;
  if (value_sizes != NULL)
    *value_sizes = NULL;
  if (count != NULL)
    *count = 0;
cleanup:
  unlockdb(vsdb);
  if (buf.capacity > 0) {
    free(buf.kts);
    free(buf.dts);
  }
  return vsdb_ret;
}