Exemple #1
0
static VALUE
minidb_close(VALUE self)
{
    DEPOT *db;
    Data_Get_Struct(self, DEPOT, db);
    dpclose(db);
    DATA_PTR(self) = 0;
    return Qnil;
}
Exemple #2
0
/* Close a database handle. */
void gdbm_close(GDBM_FILE dbf){
  assert(dbf);
  if(dbf->depot){
    if(dbf->syncmode) dpsync(dbf->depot);
    dpclose(dbf->depot);
  } else {
    if(dbf->syncmode) crsync(dbf->curia);
    crclose(dbf->curia);
  }
  free(dbf);
}
Exemple #3
0
/* perform export command */
int doexport(const char *name, int bin){
  DEPOT *depot;
  char *kbuf, *vbuf, *tmp;
  int err, ksiz, vsiz;
  /* open a database */
  if(!(depot = dpopen(name, DP_OREADER, -1))){
    pdperror(name);
    return 1;
  }
  /* initialize the iterator */
  dpiterinit(depot);
  /* loop for each key */
  err = FALSE;
  while((kbuf = dpiternext(depot, &ksiz)) != NULL){
    /* retrieve a value with a key */
    if(!(vbuf = dpget(depot, kbuf, ksiz, 0, -1, &vsiz))){
      pdperror(name);
      free(kbuf);
      err = TRUE;
      break;
    }
    /* output data */
    if(bin){
      tmp = cbbaseencode(kbuf, ksiz);
      printf("%s\t", tmp);
      free(tmp);
      tmp = cbbaseencode(vbuf, vsiz);
      printf("%s\n", tmp);
      free(tmp);
    } else {
      printf("%s\t%s\n", kbuf, vbuf);
    }
    /* free resources */
    free(vbuf);
    free(kbuf);
  }
  /* check whether all records were retrieved */
  if(dpecode != DP_ENOITEM){
    pdperror(name);
    err = TRUE;
  }
  /* close the database */
  if(!dpclose(depot)){
    pdperror(name);
    return 1;
  }
  return err ? 1 : 0;
}
Exemple #4
0
/* perform import command */
int doimport(const char *name, int bnum, int bin){
  DEPOT *depot;
  char *buf, *kbuf, *vbuf, *ktmp, *vtmp;
  int i, err, ktsiz, vtsiz;
  /* open a database */
  if(!(depot = dpopen(name, DP_OWRITER | DP_OCREAT, bnum))){
    pdperror(name);
    return 1;
  }
  /* loop for each line */
  err = FALSE;
  for(i = 1; (buf = getl()) != NULL; i++){
    kbuf = buf;
    if((vbuf = strchr(buf, '\t')) != NULL){
      *vbuf = '\0';
      vbuf++;
      /* store a record */
      if(bin){
        ktmp = cbbasedecode(kbuf, &ktsiz);
        vtmp = cbbasedecode(vbuf, &vtsiz);
        if(!dpput(depot, ktmp, ktsiz, vtmp, vtsiz, DP_DOVER)){
          pdperror(name);
          err = TRUE;
        }
        free(vtmp);
        free(ktmp);
      } else {
        if(!dpput(depot, kbuf, -1, vbuf, -1, DP_DOVER)){
          pdperror(name);
          err = TRUE;
        }
      }
    } else {
      fprintf(stderr, "%s: %s: invalid format in line %d\n", progname, name, i);
    }
    free(buf);
    if(err) break;
  }
  /* close the database */
  if(!dpclose(depot)){
    pdperror(name);
    return 1;
  }
  return err ? 1 : 0;
}
Exemple #5
0
void DBPrivCloseDB(DBPriv *db)
{
    int ret;

    if ((ret = pthread_mutex_destroy(&db->lock)) != 0)
    {
        errno = ret;
        Log(LOG_LEVEL_ERR, "Lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr());
    }

    if ((ret = pthread_mutex_destroy(&db->cursor_lock)) != 0)
    {
        errno = ret;
        Log(LOG_LEVEL_ERR, "Cursor lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr());
    }

    if (!dpclose(db->depot))
    {
        Log(LOG_LEVEL_ERR, "Unable to close QDBM database. (dpclose: %s)", dperrmsg(dpecode));
    }

    free(db);
}
/* Initialize the root directory. */
int master_init(const char *rootdir){
  DEPOT *depot;
  FILE *ofp;
  char path[URIBUFSIZ];
  int err;
  assert(rootdir);
  if(est_mkdir(rootdir) == -1 && errno != EEXIST) return FALSE;
  err = FALSE;
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, METAFILE);
  if((depot = dpopen(path, DP_OWRITER | DP_OCREAT | DP_OTRUNC, MINIBNUM))){
    if(!dpput(depot, MMKMAGIC, -1, MMKMAGVAL, -1, DP_DKEEP)) err = TRUE;
    if(!dpclose(depot)) err = TRUE;
  } else {
    err = TRUE;
  }
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, CONFFILE);
  if((ofp = fopen(path, "wb")) != NULL){
    fprintf(ofp, "# binding address of TCP (0.0.0.0 means every address)\n");
    fprintf(ofp, "bindaddr: 0.0.0.0\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# port number of TCP\n");
    fprintf(ofp, "portnum: 1978\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# public URL (absolute URL)\n");
    fprintf(ofp, "publicurl:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# running mode (1:normal, 2:readonly)\n");
    fprintf(ofp, "runmode: 1\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# authorization mode (1:none, 2:admin, 3:all)\n");
    fprintf(ofp, "authmode: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum length of data to receive (in kilobytes)\n");
    fprintf(ofp, "recvmax: 1024\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of connections at the same time\n");
    fprintf(ofp, "maxconn: 30\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# idle time to start flushing (in seconds)\n");
    fprintf(ofp, "idleflush: 20\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# idle time to start synchronizing (in seconds)\n");
    fprintf(ofp, "idlesync: 300\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# timeout of a session (in seconds)\n");
    fprintf(ofp, "sessiontimeout: 600\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# timeout of search (in seconds)\n");
    fprintf(ofp, "searchtimeout: 15\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of documents to send\n");
    fprintf(ofp, "searchmax: 1000\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum depth of meta search\n");
    fprintf(ofp, "searchdepth: 5\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# whether to rate URI for scoring (0:no, 1:yes)\n");
    fprintf(ofp, "rateuri: 1\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# merge method of meta search (1:score, 2:score and rank, 3:rank)\n");
    fprintf(ofp, "mergemethod: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# host name of the proxy\n");
    fprintf(ofp, "proxyhost:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# port number of the proxy\n");
    fprintf(ofp, "proxyport:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# path of the log file (relative path or absolute path)\n");
    fprintf(ofp, "logfile: %s\n", LOGFILE);
    fprintf(ofp, "\n");
    fprintf(ofp, "# logging level (1:debug, 2:information, 3:warning, 4:error, 5:none)\n");
    fprintf(ofp, "loglevel: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# command for backup (absolute path of a command)\n");
    fprintf(ofp, "backupcmd:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# scale prediction (1:small, 2:medium, 3:large, 4:huge)\n");
    fprintf(ofp, "scalepred: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# score expression (1:void, 2:char, 3:int, 4:asis)\n");
    fprintf(ofp, "scoreexpr: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# attribute indexes (attribute name and data type)\n");
    fprintf(ofp, "attrindex: @mdate{{!}}seq\n");
    fprintf(ofp, "attrindex: @title{{!}}str\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# document root directory (absolute path of a directory to be public)\n");
    fprintf(ofp, "docroot:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# index file (name of directory index files)\n");
    fprintf(ofp, "indexfile:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# decimal IP addresses of trusted nodes\n");
    fprintf(ofp, "trustednode:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# whether to deny all nodes except for trusted nodes (0:no, 1:yes)\n");
    fprintf(ofp, "denyuntrusted: 0\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum size of the index cache (in megabytes)\n");
    fprintf(ofp, "cachesize: 64\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of cached records for document attributes\n");
    fprintf(ofp, "cacheanum: 8192\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of cached records for document texts\n");
    fprintf(ofp, "cachetnum: 1024\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of cached records for occurrence results\n");
    fprintf(ofp, "cachernum: 256\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# name of the attribute of the special cache\n");
    fprintf(ofp, "specialcache:\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# lower limit of cache usage to use the helper\n");
    fprintf(ofp, "helpershift: 0.9\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# maximum number of expansion of wild cards\n");
    fprintf(ofp, "wildmax: 256\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# text size limitation of indexing documents (in kilobytes)\n");
    fprintf(ofp, "limittextsize: 128\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# whole width of the snippet of each shown document\n");
    fprintf(ofp, "snipwwidth: 480\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# width of strings picked up from the beginning of the text\n");
    fprintf(ofp, "sniphwidth: 96\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# width of strings picked up around each highlighted word\n");
    fprintf(ofp, "snipawidth: 96\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# whether to check documents by scanning (0:no, 1:yes)\n");
    fprintf(ofp, "scancheck: 1\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# number of keywords for similarity search (0 means disabled)\n");
    fprintf(ofp, "smlrvnum: 32\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# number of documents for delay of keyword extraction\n");
    fprintf(ofp, "extdelay: 4096\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# e-mail address of the administrator\n");
    fprintf(ofp, "adminemail: [email protected]\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# expressions to replace the URI of each document\n");
    fprintf(ofp, "uireplace: ^file:///home/mikio/public_html/{{!}}http://localhost/\n");
    fprintf(ofp, "uireplace: /index\\.html?${{!}}/\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# extra attributes to be shown\n");
    fprintf(ofp, "uiextattr: @author|Author\n");
    fprintf(ofp, "uiextattr: @mdate|Modification Date\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# mode of phrase form"
            " (1:usual, 2:simplified, 3:rough, 4:union: 5:intersection)\n");
    fprintf(ofp, "uiphraseform: 2\n");
    fprintf(ofp, "\n");
    fprintf(ofp, "# tuning parameters for similarity search\n");
    fprintf(ofp, "uismlrtune: 16 1024 4096\n");
    fprintf(ofp, "\n");
    if(fclose(ofp) == EOF) err = TRUE;
  } else {
    err = TRUE;
  }
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, PIDFILE);
  unlink(path);
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, STOPFILE);
  unlink(path);
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, USERFILE);
  if((ofp = fopen(path, "wb")) != NULL){
    if(fclose(ofp) == EOF) err = TRUE;
  } else {
    err = TRUE;
  }
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, LOGFILE);
  if((ofp = fopen(path, "wb")) != NULL){
    if(fclose(ofp) == EOF) err = TRUE;
  } else {
    err = TRUE;
  }
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, NODEDIR);
  est_rmdir_rec(path);
  if(est_mkdir(path) == -1) err = TRUE;
  sprintf(path, "%s%c%s", rootdir, ESTPATHCHR, SESSDIR);
  est_rmdir_rec(path);
  if(est_mkdir(path) == -1) err = TRUE;
  return err ? FALSE : TRUE;
}
Exemple #7
0
/* Get a database handle after the fashion of GDBM. */
GDBM_FILE gdbm_open(char *name, int block_size, int read_write, int mode, void (*fatal_func)()){
  GDBM_FILE dbf;
  int dpomode;
  DEPOT *depot;
  int flags, fd;
  assert(name);
  dpomode = DP_OREADER;
  flags = O_RDONLY;
  if(read_write & GDBM_READER){
    dpomode = GDBM_READER;
    if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK;
    if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB;
    flags = O_RDONLY;
  } else if(read_write & GDBM_WRITER){
    dpomode = DP_OWRITER;
    if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK;
    if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB;
    flags = O_RDWR;
  } else if(read_write & GDBM_WRCREAT){
    dpomode = DP_OWRITER | DP_OCREAT;
    if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK;
    if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB;
    if(read_write & GDBM_SPARSE) dpomode |= DP_OSPARSE;
    flags = O_RDWR | O_CREAT;
  } else if(read_write & GDBM_NEWDB){
    dpomode = DP_OWRITER | DP_OCREAT | DP_OTRUNC;
    if(read_write & GDBM_NOLOCK) dpomode |= DP_ONOLCK;
    if(read_write & GDBM_LOCKNB) dpomode |= DP_OLCKNB;
    if(read_write & GDBM_SPARSE) dpomode |= DP_OSPARSE;
    flags = O_RDWR | O_CREAT | O_TRUNC;
  } else {
    gdbm_errno = GDBM_ILLEGAL_DATA;
    return NULL;
  }
  mode |= 00600;
  if((fd = open(name, flags, mode)) == -1 || close(fd) == -1){
    gdbm_errno = GDBM_FILE_OPEN_ERROR;
    return NULL;
  }
  if(!(depot = dpopen(name, dpomode, HV_INITBNUM))){
    gdbm_errno = gdbm_geterrno(dpecode);
    if(dpecode == DP_ESTAT) gdbm_errno = GDBM_FILE_OPEN_ERROR;
    return NULL;
  }
  if(dpomode & DP_OWRITER){
    if(!dpsetalign(depot, HV_ALIGNSIZ)){
      gdbm_errno = gdbm_geterrno(dpecode);
      dpclose(depot);
    }
  }
  if((dpomode & DP_OWRITER) && (read_write & GDBM_SYNC)){
    if(!dpsync(depot)){
      gdbm_errno = gdbm_geterrno(dpecode);
      dpclose(depot);
    }
  }
  if(!(dbf = malloc(sizeof(GDBM)))){
    gdbm_errno = GDBM_MALLOC_ERROR;
    dpclose(depot);
    return NULL;
  }
  dbf->depot = depot;
  dbf->curia = NULL;
  dbf->syncmode = (dpomode & DP_OWRITER) && (read_write & GDBM_SYNC) ? TRUE : FALSE;
  return dbf;
}
Exemple #8
0
/* Get a database handle after the fashion of QDBM. */
GDBM_FILE gdbm_open2(char *name, int read_write, int mode, int bnum, int dnum, int align){
  GDBM_FILE dbf;
  int dpomode, cromode, flags, fd;
  struct stat sbuf;
  DEPOT *depot;
  CURIA *curia;
  assert(name);
  dpomode = DP_OREADER;
  cromode = CR_OREADER;
  flags = O_RDONLY;
  if(read_write & GDBM_READER){
    dpomode = DP_OREADER;
    cromode = CR_OREADER;
    if(read_write & GDBM_NOLOCK){
      dpomode |= DP_ONOLCK;
      cromode |= CR_ONOLCK;
    }
    if(read_write & GDBM_LOCKNB){
      dpomode |= DP_OLCKNB;
      cromode |= CR_OLCKNB;
    }
    flags = O_RDONLY;
  } else if(read_write & GDBM_WRITER){
    dpomode = DP_OWRITER;
    cromode = CR_OWRITER;
    if(read_write & GDBM_NOLOCK){
      dpomode |= DP_ONOLCK;
      cromode |= CR_ONOLCK;
    }
    if(read_write & GDBM_LOCKNB){
      dpomode |= DP_OLCKNB;
      cromode |= CR_OLCKNB;
    }
    flags = O_RDWR;
  } else if(read_write & GDBM_WRCREAT){
    dpomode = DP_OWRITER | DP_OCREAT;
    cromode = CR_OWRITER | CR_OCREAT;
    if(read_write & GDBM_NOLOCK){
      dpomode |= DP_ONOLCK;
      cromode |= CR_ONOLCK;
    }
    if(read_write & GDBM_LOCKNB){
      dpomode |= DP_OLCKNB;
      cromode |= CR_OLCKNB;
    }
    if(read_write & GDBM_SPARSE){
      dpomode |= DP_OSPARSE;
      cromode |= CR_OSPARSE;
    }
    flags = O_RDWR | O_CREAT;
  } else if(read_write & GDBM_NEWDB){
    dpomode = DP_OWRITER | DP_OCREAT | DP_OTRUNC;
    cromode = CR_OWRITER | CR_OCREAT | CR_OTRUNC;
    if(read_write & GDBM_NOLOCK){
      dpomode |= DP_ONOLCK;
      cromode |= CR_ONOLCK;
    }
    if(read_write & GDBM_LOCKNB){
      dpomode |= DP_OLCKNB;
      cromode |= CR_OLCKNB;
    }
    if(read_write & GDBM_SPARSE){
      dpomode |= DP_OSPARSE;
      cromode |= CR_OSPARSE;
    }
    flags = O_RDWR | O_CREAT | O_TRUNC;
  } else {
    gdbm_errno = GDBM_ILLEGAL_DATA;
    return NULL;
  }
  if(lstat(name, &sbuf) != -1){
    if(S_ISDIR(sbuf.st_mode)){
      if(dnum < 1) dnum = 1;
    } else {
      dnum = 0;
    }
  }
  depot = NULL;
  curia = NULL;
  if(dnum > 0){
    mode |= 00700;
    if((cromode & CR_OCREAT)){
      if(mkdir(name, mode) == -1 && errno != EEXIST){
        gdbm_errno = GDBM_FILE_OPEN_ERROR;
        return NULL;
      }
    }
    if(!(curia = cropen(name, cromode, bnum, dnum))){
      gdbm_errno = gdbm_geterrno(dpecode);
      return NULL;
    }
    if(cromode & CR_OWRITER) crsetalign(curia, align);
    if((cromode & CR_OWRITER) && (read_write & GDBM_SYNC)) crsync(curia);
  } else {
    mode |= 00600;
    if(dpomode & DP_OWRITER){
      if((fd = open(name, flags, mode)) == -1 || close(fd) == -1){
        gdbm_errno = GDBM_FILE_OPEN_ERROR;
        return NULL;
      }
    }
    if(!(depot = dpopen(name, dpomode, bnum))){
      gdbm_errno = gdbm_geterrno(dpecode);
      return NULL;
    }
    if(dpomode & DP_OWRITER) dpsetalign(depot, align);
    if((dpomode & DP_OWRITER) && (read_write & GDBM_SYNC)) dpsync(depot);
  }
  if(!(dbf = malloc(sizeof(GDBM)))){
    gdbm_errno = GDBM_MALLOC_ERROR;
    if(depot) dpclose(depot);
    if(curia) crclose(curia);
    return NULL;
  }
  dbf->depot = depot;
  dbf->curia = curia;
  dbf->syncmode = (dpomode & DP_OWRITER) && (read_write & GDBM_SYNC) ? TRUE : FALSE;
  return dbf;
}
int main(int argc, char *argv[])
{
   DEPOT            *dbmap = NULL;
   char             *str_prefix = "dbbm_key_prefix_";
   char             *key, keystr[24];
   unsigned long    i;
   int              rc = 0;
   PDUMMY_DATA      datap;
   
   if (argc < 3) {
      fprintf(stderr, "Usage : <prog> <dbpath> <datasize>\n");
      exit(1);
   }

   dbmap = dpopen(argv[1], DP_OWRITER|DP_OCREAT|DP_OSPARSE|DP_ONOLCK, -1);
   if (!dbmap) {
      fprintf(stderr, "Unable to open the dbbm file \n");
      exit(1);
   }

   datap = (PDUMMY_DATA) malloc(sizeof(DUMMY_DATA));
   if (!datap) {
      fprintf(stderr, "Malloc error %s\n", strerror(errno));
      exit(1);
   }

   unsigned long datasize = strtoul(argv[2], NULL, 10);
   // push data 
   for (i = 0; i < datasize; i++) {
      asprintf(keystr, "%s%lu", str_prefix, i);
      datap->x = i;
      datap->y = i+1;
      datap->z = i+2;
      if (!dpput(dbmap, keystr, strlen(keystr), (char *) datap, sizeof(DUMMY_DATA), 
            DP_DOVER)) {
         fprintf(stderr, "Unable to insert to qdbm\n");
      };
   }

   if(!dpclose(dbmap)){
      fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode));
      return 1;
   }

   //read data 
   dbmap = dpopen(argv[1], DP_OREADER, -1); 
   if (!dbmap) {
      fprintf(stderr, "Unable to open the dbbm file \n");
      exit(1);
   }

   fprintf(stdout, "Starting read of the database sequentially\n");

   if(!dpiterinit(dbmap)){
      fprintf(stderr, "dpiterinit: %s\n", dperrmsg(dpecode));
   }
   
   /* scan with the iterator */
   while ((key = dpiternext(dbmap, NULL)) != NULL) {
      if (!(datap = (PDUMMY_DATA) dpget(dbmap, key, -1, 0, sizeof(DUMMY_DATA), NULL))) {
         fprintf(stderr, "Value is not found for key %s\n", key);
         fprintf(stderr, "dpget: %s\n", dperrmsg(dpecode));
         free(key);
         break;
      }
/*      fprintf(stdout, "Data read for dbm : x=%lu y=%lu z=%lu\n", 
            datap->x, datap->y, datap->z);*/
      free(datap);
   }
   
   fprintf(stdout, "End of the database reached\n");
   
   if(!dpclose(dbmap)){
      fprintf(stderr, "dpclose: %s\n", dperrmsg(dpecode));
      return 1;
   }

   return 0;
}
static int auth_ticket_assert(struct link *link, time_t stoptime)
{
	/* FIXME need to save errno ? */
	char line[AUTH_LINE_MAX];
	char **tickets = client_tickets;

	if(tickets) {
		char *ticket;
		char digest[DIGEST_LENGTH];

		for (ticket = *tickets; ticket; ticket = *(++tickets)) {
			if (access(ticket, R_OK) == -1) {
				debug(D_AUTH, "could not access ticket %s: %s", ticket, strerror(errno));
				continue;
			}

			/* load the digest */
			/* WARNING: openssl is *very* bad at giving sensible output. Use the last
			 * 32 non-space characters as the MD5 sum.
			 */
			char command[PATH_MAX * 2 + 4096];
			sprintf(command, "openssl rsa -in '%s' -pubout 2> /dev/null | openssl md5 2> /dev/null | tr -d '[:space:]' | tail -c 32", ticket);
			FILE *digestf = popen(command, "r");
			if(full_fread(digestf, digest, DIGEST_LENGTH) < DIGEST_LENGTH) {
				pclose(digestf);
				return 0;
			}
			pclose(digestf);
			debug(D_AUTH, "trying ticket %.*s", DIGEST_LENGTH, digest);
			if(link_putlstring(link, digest, DIGEST_LENGTH, stoptime) <= 0)
				return 0;
			if(link_putliteral(link, "\n", stoptime) <= 0)
				return 0;

			if(link_readline(link, line, sizeof(line), stoptime) <= 0)
				return 0;
			if(strcmp(line, "declined") == 0)
				continue;

			unsigned long length = strtoul(line, NULL, 10);
			if(errno == ERANGE || errno == EINVAL)
				return 0;	/* not a number? */
			debug(D_AUTH, "receiving challenge of %d bytes", length);

			FILE *in, *out;
			static const char command_template[] = "T1=`mktemp`\n"	/* signed challenge */
				"T2=`mktemp`\n"	/* private key without comments */
				"sed '/^\\s*#/d' < '%s' > \"$T2\"\n" "openssl rsautl -inkey \"$T2\" -sign > \"$T1\" 2> /dev/null\n" "R=\"$?\"\n" "if [ \"$R\" -ne 0 ]; then\n" "  rm -f \"$T1\" \"$T2\"\n" "  exit \"$R\"\n" "fi\n"
				"ls -l \"$T1\" | awk '{ print $5 }'\n" "cat \"$T1\"\n" "rm -f \"$T1\" \"$T2\"\n";
			sprintf(command, command_template, ticket);
			pid_t pid = dpopen(command, &in, &out);
			if(pid == 0)
				return 0;
			if(link_stream_to_file(link, in, length, stoptime) <= 0) {
				dpclose(in, out, pid);
				debug(D_AUTH, "openssl failed, your keysize may be too small");
				debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\"");
				return 0;
			}
			fclose(in);
			in = NULL;
			if(link_stream_from_file(link, out, 1 << 20, stoptime) <= 0) {
				dpclose(in, out, pid);
				debug(D_AUTH, "openssl failed, your keysize may be too small");
				debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\"");
				return 0;
			}
			dpclose(in, out, pid);

			if(link_readline(link, line, sizeof(line), stoptime) <= 0)
				return 0;
			if(strcmp(line, "success") == 0) {
				debug(D_AUTH, "succeeded challenge for %.*s\n", DIGEST_LENGTH, digest);
				return 1;
			} else if(strcmp(line, "failure") == 0) {
				debug(D_AUTH, "failed challenge for %.*s\n", DIGEST_LENGTH, digest);
				errno = EINVAL;
				return 0;
			} else {
				debug(D_AUTH, "received bad response: '%s'", line);
				errno = EINVAL;
				return 0;
			}
		}
	}
	link_putliteral(link, "==\n", stoptime);

	return 0;
}
static int auth_ticket_accept(struct link *link, char **subject, time_t stoptime)
{
	int serrno = errno;
	int status = 0;
	char line[AUTH_LINE_MAX];
	char ticket_subject[AUTH_LINE_MAX];
	char *ticket = NULL;

	errno = 0;

	debug(D_AUTH, "ticket: waiting for tickets");

	while(1) {
		if(link_readline(link, line, sizeof(line), stoptime) > 0) {
			if(strcmp(line, "==") == 0) {
				debug(D_AUTH, "ticket: exhausted all ticket challenges");
				break;
			} else if(strlen(line) == DIGEST_LENGTH) {
				char ticket_digest[DIGEST_LENGTH + 1];
				strcpy(ticket_digest, line);
				strcpy(ticket_subject, line);
				debug(D_AUTH, "ticket: read ticket digest: %s", ticket_digest);
				if(server_callback) {
					free(ticket); /* free previously allocated ticket string or NULL (noop) */
					ticket = server_callback(ticket_digest);
					if(ticket) {
						static const char command_template[] = "T1=`mktemp`\n"	/* The RSA Public Key */
							"T2=`mktemp`\n"	/* The Challenge */
							"T3=`mktemp`\n"	/* The Signed Challenge */
							"T4=`mktemp`\n"	/* The Decrypted (verified) Signed Challenge */
							"echo -n '%s' > \"$T1\"\n" "dd if=/dev/urandom of=\"$T2\" bs=%u count=1 > /dev/null 2> /dev/null\n" "cat \"$T2\"\n"	/* to stdout */
							"cat > \"$T3\"\n"	/* from stdin */
							"openssl rsautl -inkey \"$T1\" -pubin -verify < \"$T3\" > \"$T4\" 2> /dev/null\n" "cmp \"$T2\" \"$T4\" > /dev/null 2> /dev/null\n" "R=\"$?\"\n"
							"rm -f \"$T1\" \"$T2\" \"$T3\" \"$T4\" > /dev/null 2> /dev/null\n" "exit \"$R\"\n";

						char *command = xxmalloc(sizeof(command_template) + strlen(ticket) + 64);
						sprintf(command, command_template, ticket, CHALLENGE_LENGTH);

						FILE *in, *out;
						pid_t pid = dpopen(command, &in, &out);
						free(command);
						if(pid == 0)
							break;

						if(!link_putfstring(link, "%zu\n", stoptime, CHALLENGE_LENGTH))
							break;
						if(!link_stream_from_file(link, out, CHALLENGE_LENGTH, stoptime))
							break;

						if(link_readline(link, line, sizeof(line), stoptime) <= 0)
							break;
						unsigned long length = strtoul(line, NULL, 10);
						if(errno == ERANGE || errno == EINVAL)
							break;	/* not a number? */
						if(!link_stream_to_file(link, in, length, stoptime))
							break;

						int result = dpclose(in, out, pid);

						if(result == 0) {
							debug(D_AUTH, "succeeded challenge for %s\n", ticket_digest);
							link_putliteral(link, "success\n", stoptime);
							status = 1;
							break;
						} else {
							debug(D_AUTH, "failed challenge for %s\n", ticket_digest);
							link_putliteral(link, "failure\n", stoptime);
							break;
						}
					} else {
						debug(D_AUTH, "declining key %s", ticket_digest);
						link_putliteral(link, "declined\n", stoptime);
					}
				} else {
					debug(D_AUTH, "declining key %s", ticket_digest);
					link_putliteral(link, "declined\n", stoptime);
				}
			} else {
				debug(D_AUTH, "ticket: bad response");
				break;
			}
		} else {
			break;
		}
	}

	if(status) {
		*subject = xxmalloc(AUTH_LINE_MAX);
		strcpy(*subject, ticket_subject);
	}
	free(ticket); /* free previously allocated ticket string or NULL (noop) */
	errno = serrno;
	return status;
}
Exemple #12
0
static void
minidb_free(DEPOT *db) {
    if (db)  {
        dpclose(db);
    }
}