ftp.nice.ch/pub/next/unix/communication/ft_bbs.1.0.s.tar.gz#/ft_bbs-1.0/dbase.c

This is dbase.c in view mode; [Download] [Up]

/* $Id: dbase.c,v 1.1 1995/12/19 19:30:47 eilts Exp eilts $ */
#include "bbs.h"

#ifdef NNTPNEWS
int updatenewsgroupsdb(bbsddbtyp *bbsddb, newsstattyp *newsstat,
                       const confrecordtyp *confrecord)
{
  int n;
  SIZE_T len, anz, duplicate_entries;
  char dbfile[PATH_MAX+1], *statfile, *bufp, *sp1, *sp2, *sp3, c;
#ifdef NO_DBOPEN
  char dbfile_pag[PATH_MAX+1];
#endif
  boolean bbsddbinit = FALSE;
  struct stat stats;
  DBASE_DB *db;
  DBASE_DBT dbkey, dbdata;
  static TIME_T db_mtime = (TIME_T)0;
  TIME_T lastupdate;

  strcpy(dbfile,confrecord->vardir);
#ifndef NO_DBOPEN
  strmaxcat(dbfile,"/newsgroups.db",PATH_MAX);
  statfile = dbfile;
#else
  strmaxcat(dbfile,"/newsgroups",PATH_MAX-4);
  strcpy(dbfile_pag,dbfile);
  strcat(dbfile_pag,".pag");
  statfile = dbfile_pag;
#endif
  if (db_mtime == (TIME_T)0) {
    bbsddbinit = TRUE;
    n = stat(statfile,&stats);
    if (n == 0) {
      db_mtime = stats.st_mtime;
    }
    else if (n < 0 && errno != ENOENT) {
      bgerror("updatenewsgroupsdb","stat %s: %m",statfile);
      return -1;
    }
  }
  lastupdate = time((TIME_T)0) - (TIME_T) NEWSGROUP_UPDATE_INTERVALL;
  
  if (stat(confrecord->usersfile,&stats) < 0) {
    bgerror("updatenewsgroupsdb","stat %s: %m",confrecord->usersfile);
    return -1;
  }
  if (bbsddbinit && db_mtime >= lastupdate) {
    if ((bbsddb->newsgrp_db=dbopen(dbfile,O_RDWR,0600,DB_HASH,NULL)) == NULL) {
      bgerror("updatenewsgroupsdb","dbopen %s: %m",dbfile);
      db_mtime = (TIME_T)0;
      DBASE_UNLINK(dbfile);
      return -1;
    }
    return 0;
  }
  if (db_mtime >= lastupdate)  return 0;
  
  if (! newsstat->is_connected) {
    if (nntp_connect(newsstat,confrecord) < 0)  return -1;
  }
  if (bbsddb->newsgrp_db != NULL) {
    if (bbsddb->newsgrp_db->close(bbsddb->newsgrp_db) < 0) {
      bgerror("updatenewsgroupsdb","dbclose %m");
      nntp_close(newsstat);
      return -1;
    }
  }
  if ((db=dbopen(dbfile,O_CREAT|O_TRUNC|O_RDWR,0600,DB_HASH,NULL)) == NULL) {
    bgerror("updatenewsgroupsdb","dbopen %s: %m",dbfile);
    DBASE_UNLINK(dbfile);
    nntp_close(newsstat);
    return -1;
  }
  if ((n=nntp_ask(NULL,newsstat,"LIST")) != OK_GROUPS) {
    bgerror("updatenewsgroupsdb","nntp_ask: %d",n);
    DBASE_UNLINK(dbfile);
    nntp_close(newsstat);
    return -1;
  }
  if ((bufp=nntp_copytext(&len,newsstat)) == NULL) {
    bgerror("updatenewsgroupsdb","nntp_copytext failed");
    DBASE_UNLINK(dbfile);
    nntp_close(newsstat);
    return -1;
  }
  nntp_close(newsstat);
  anz = 0;
  duplicate_entries = 0;
  sp1 = bufp;
  lowercases(sp1);
  while (*sp1) {
    for (sp2=sp1; *sp2 && *sp2!='\n' && *sp2!=' ' && *sp2!='\t'; sp2++) ;
    c = *sp2;
    if (c) {
      *sp2++ = '\0';
      for (sp3=sp2; *sp3 && *sp3!='\n'; sp3++) ;
      c = *sp3;
      *sp3 = '\0';
      DBASE_DATA(dbkey) = sp1;
      DBASE_SIZE(dbkey) = strlen(sp1) + 1;
      DBASE_DATA(dbdata) = sp2;
      DBASE_SIZE(dbdata) = strlen(sp2) + 1;
      n = db->put(db,&dbkey,&dbdata,R_NOOVERWRITE);
      anz++;
      if (n > 0) {
	duplicate_entries++;
/*
      bgerror("updatenewsgroupsdb","duplicate key %s",
      (char *)DBASE_DATA(dbkey));
*/
      }
      else if (n < 0) {
	bgerror("updatenewsgroupsdb","error at key %s: %m",
		(char *)DBASE_DATA(dbkey));
      }
    }
    if (c == '\0')  break;
    sp1 = sp3 + 1;
  }
  free(bufp);
#ifdef DEBUG
  bgerror("updatenewsgroupsdb","Newsgroups-DB: %d group entries (%d doubles)",
          anz,duplicate_entries);
#endif
  if (db->sync(db,0) < 0) {
    bgerror("updatenewsgroupsdb","dbsync %s: %m",dbfile);
    DBASE_UNLINK(dbfile);
    return -1;
  }
  bbsddb->newsgrp_db = db;
  db_mtime = lastupdate + (TIME_T) NEWSGROUP_UPDATE_INTERVALL;
  return 0;
}  
#endif


int updatebbsddb(bbsddbtyp *bbsddb, const confrecordtyp *confrecord)
{
  int z, n;
  char zeile[STRLEN+1], dbfile[PATH_MAX+1], emailpath[PATH_MAX+1],
       user[S_STRLEN+1], *key, *arg, *statfile;
#ifdef NO_DBOPEN
  char dbfile_pag[PATH_MAX+1];
#endif
  boolean realnamefound, bbsddbinit = FALSE;
  FILE *fd, *emailfd = NULL;
  struct stat stats;
  DBASE_DB *db;
  DBASE_DBT dbkey, dbdata;
  static TIME_T db_mtime = (TIME_T)0;

  strcpy(dbfile,confrecord->vardir);
#ifndef NO_DBOPEN
  strmaxcat(dbfile,"/users.db",PATH_MAX);
  statfile = dbfile;
#else
  strmaxcat(dbfile,"/users",PATH_MAX-4);
  strcpy(dbfile_pag,dbfile);
  strcat(dbfile_pag,".pag");
  statfile = dbfile_pag;
#endif
  if (db_mtime == (TIME_T)0) {
    bbsddbinit = TRUE;
    n = stat(statfile,&stats);
    if (n == 0) {
      db_mtime = stats.st_mtime;
    }
    else if (n < 0 && errno != ENOENT) {
      bgerror("updatebbsddb","stat %s: %m",statfile);
      return -1;
    }
  }
  if (stat(confrecord->usersfile,&stats) < 0) {
    bgerror("updatebbsddb","stat %s: %m",confrecord->usersfile);
    return -1;
  }
  if (bbsddbinit && db_mtime >= stats.st_mtime) {
    if ((bbsddb->u_db=dbopen(dbfile,O_RDWR,0600,DB_HASH,NULL)) == NULL) {
      bgerror("updatebbsddb","dbopen %s: %m",dbfile);
      db_mtime = (TIME_T)0;
      DBASE_UNLINK(dbfile);
      return -1;
    }
    return 0;
  }
  if (db_mtime >= stats.st_mtime)  return 0;
  
  if ((fd=fopen(confrecord->usersfile,"r")) == NULL) {
    bgerror("updatebbsddb","fopen %s: %m",confrecord->usersfile);
    return -1;
  }
  if (bbsddb->u_db != NULL) {
    if (bbsddb->u_db->close(bbsddb->u_db) < 0) {
      bgerror("updatebbsddb","dbclose %m");
      return -1;
    }
  }
  strcpy(emailpath,confrecord->vardir);
  strmaxcat(emailpath,"/bbsusernames",PATH_MAX);
  if (access(emailpath,W_OK) == 0 || access(emailpath,F_OK) < 0) {
    if ((emailfd=fopen(emailpath,"w")) == NULL) {
      bgerror("updatebbsddb","fopen %s: %m",emailpath);
      return -1;
    }
    chmod(emailpath,0644);
  }
  if ((db=dbopen(dbfile,O_CREAT|O_TRUNC|O_RDWR,0600,DB_HASH,NULL)) == NULL) {
    bgerror("updatebbsddb","dbopen %s: %m",dbfile);
    DBASE_UNLINK(dbfile);
    return -1;
  }
  do {
    z = fgetnln(zeile,S_STRLEN,fd);
    if (z > 0 && zeile[0] != '#') {
      split2key_arg(zeile,&key,&arg);
      lowercases(key);
      if (strncmp("user",key,4) != 0) {
        bgerror("updatebbsddb","'User:' must be first entry in any record");
        DBASE_UNLINK(dbfile);
	return -1;
      }
      strmaxcpy(user,arg,S_STRLEN);
      DBASE_DATA(dbkey) = user;
      DBASE_SIZE(dbkey) = strlen(user) + 1;
      if (emailfd != NULL)  fprintf(emailfd,"%s\n",arg);
      realnamefound = FALSE;
      do {
        z = fgetnln(zeile,STRLEN,fd);
        if (z > 0 && z < STRLEN) {
          split2key_arg(zeile,&key,&arg);
          lowercases(key);
          if (strncmp("real",key,4) == 0) {
            DBASE_DATA(dbdata) = arg;
            DBASE_SIZE(dbdata) = strlen(arg) + 1;
	    n = db->put(db,&dbkey,&dbdata,R_NOOVERWRITE);
            realnamefound = TRUE;
	    break;
          }
        }
      } while (z >= 0 && zeile[0] != '$');
      while (z >= 0 && zeile[0] != '$') {
        z = fgetnln(zeile,2,fd);
      }
      if (! realnamefound) {
        DBASE_DATA(dbdata) = "";
        DBASE_SIZE(dbdata) = 1;
        n = db->put(db,&dbkey,&dbdata,R_NOOVERWRITE);
      }
      if (n > 0) {
         bgerror("updatebbsddb","duplicate key %s",(char *)DBASE_DATA(dbkey));
      }
      else if (n < 0) {
         bgerror("updatebbsddb","error at key %s: %m",(char *)DBASE_DATA(dbkey));
      }
    }
  } while (z >= 0);
  if (emailfd != NULL)  fclose(emailfd);
  fclose(fd);

  if (db->sync(db,0) < 0) {
    bgerror("updatebbsddb","dbsync %s: %m",dbfile);
    DBASE_UNLINK(dbfile);
    return -1;
  }
  bbsddb->u_db = db;
  db_mtime = stats.st_mtime;
  return 0;
}


int lookupbbsddb(const bbsddbtyp *bbsddb, const void *key,
                 const SIZE_T keysize, const int keytyp,
                 void *data, SIZE_T *datasize,
                 const confrecordtyp *confrecord)
{
  int n;
  DBASE_DB *db;
  DBASE_DBT dbkey, dbval;

  DBASE_SIZE(dbkey) = keysize;
  if (keysize == 0) {
    DBASE_SIZE(dbkey) = strlen((char *)key) + 1;
  }
  if ((DBASE_DATA(dbkey) = malloc(DBASE_SIZE(dbkey))) == NULL) {
    bgerror("lookupbbsddb","malloc: %m");
    return -1;
  }
  memcpy(DBASE_DATA(dbkey),key,DBASE_SIZE(dbkey));
  if (data != NULL) {
    *datasize = 0;
    BZERO(data,1);
  }
  switch (keytyp) {
  case USERNAME_DB:
    db = bbsddb->u_db;
    n = db->get(db,&dbkey,&dbval,0);
    if (n > 0) {
      bgerror("lookupbbsddb","user %s not found",(char *)key);
    }
    else if (n < 0) {
      bgerror("lookupbbsddb","user %s: %m",(char *)key);
    }
    else if (n == 0 && data != NULL) {
      *datasize = DBASE_SIZE(dbval);
      memcpy(data,DBASE_DATA(dbval),*datasize);
    }
    break;
  case NEWSGROUPS_DB:
    db = bbsddb->newsgrp_db;
    n = db->get(db,&dbkey,&dbval,0);
    if (n > 0) {
      /* */
    }
    else if (n < 0) {
      bgerror("lookupbbsddb","group %s: %m",(char *)key);
    }
    else if (n == 0 && data != NULL) {
      *datasize = DBASE_SIZE(dbval);
      memcpy(data,DBASE_DATA(dbval),*datasize);
    }
    break;
  default:
    bgerror("lookupbbsddb","unknown keytyp");
    n = -1;
    break;
  }
  free(DBASE_DATA(dbkey));
  return n;
}


int getkeysbbsddb(const bbsddbtyp *bbsddb, const int keytyp, void *key,
                  SIZE_T *keysize, void *data, SIZE_T *datasize,
		  const confrecordtyp *confrecord)
{
  int n;
  static boolean start = TRUE;
  DBASE_DB *db;
  DBASE_DBT dbkey, dbdata;

  switch (keytyp) {
  case USERNAME_DB:
    db = bbsddb->u_db;
    break;
  case NEWSGROUPS_DB:
    db = bbsddb->newsgrp_db;
    break;
  default:
    bgerror("getkeysbbsddb","unknown keytyp");
    return -1;
  }
  n = db->seq(db,&dbkey,&dbdata,start ? R_FIRST : R_NEXT);
  if (n == 0) {
    start = FALSE;
    memcpy(key,DBASE_DATA(dbkey),DBASE_SIZE(dbkey));
    *keysize = DBASE_SIZE(dbkey);
    memcpy(data,DBASE_DATA(dbdata),DBASE_SIZE(dbdata));
    *datasize = DBASE_SIZE(dbdata);
  }
  else if (n == 1) {
    start = TRUE;
  }
  else {
    bgerror("getkeysbbsddb","seq: %m");
  }
  return n;
}


int closebbsddb(const bbsddbtyp *bbsddb)
{
  if (bbsddb->u_db->close(bbsddb->u_db) < 0) {
    bgerror("closebbsddb","dbclose: %m");
    return -1;
  }
  return 0;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.