Exemplo n.º 1
0
/* Closes the filedb. Also removes the lock and updates the
 * timestamp.
 */
static void filedb_close(FILE *fdb)
{
    filedb_timestamp(fdb);
    fseek(fdb, 0L, SEEK_END);
    count--;
    unlockfile(fdb);
    fclose(fdb);
}
Exemplo n.º 2
0
/* Updates the specified filedb in several ways:
 *
 * 1. Adds all new files from the directory to the db.
 * 2. Removes all stale entries from the db.
 * 3. Optimises the db.
 */
static void filedb_update(char *path, FILE *fdb, int sort)
{
    struct dirent *dd = NULL;
    struct stat st;
    filedb_entry *fdbe = NULL;
    DIR *dir = NULL;
    long where = 0;
    char *name = NULL, *s = NULL;

    /*
     * FIRST: make sure every real file is in the database
     */
    dir = opendir(path);
    if (dir == NULL) {
        putlog(LOG_MISC, "*", FILES_NOUPDATE);
        return;
    }
    dd = readdir(dir);
    while (dd != NULL) {
        malloc_strcpy(name, dd->d_name);
        if (name[0] != '.') {
            s = nmalloc(strlen(path) + strlen(name) + 2);
            sprintf(s, "%s/%s", path, name);
            stat(s, &st);
            my_free(s);
            filedb_readtop(fdb, NULL);
            fdbe = filedb_matchfile(fdb, ftell(fdb), name);
            if (!fdbe) {
                /* new file! */
                fdbe = malloc_fdbe();
                malloc_strcpy(fdbe->filename, name);
                malloc_strcpy(fdbe->uploader, botnetnick);
                fdbe->uploaded = now;
                fdbe->size = st.st_size;
                if (S_ISDIR(st.st_mode))
                    fdbe->stat |= FILE_DIR;
                filedb_addfile(fdb, fdbe);
            } else if (fdbe->size != st.st_size) {
                /* update size if needed */
                fdbe->size = st.st_size;
                filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
            }
            free_fdbe(&fdbe);
        }
        dd = readdir(dir);
    }
    if (name)
        my_free(name);
    closedir(dir);

    /*
     * SECOND: make sure every db file is real
     */
    filedb_readtop(fdb, NULL);
    fdbe = filedb_getfile(fdb, ftell(fdb), GET_FILENAME);
    while (fdbe) {
        where = ftell(fdb);
        if (!(fdbe->stat & FILE_UNUSED) && !(fdbe->stat & FILE_ISLINK) &&
                fdbe->filename) {
            s = nmalloc(strlen(path) + 1 + strlen(fdbe->filename) + 1);
            sprintf(s, "%s/%s", path, fdbe->filename);
            if (stat(s, &st) != 0)
                /* gone file */
                filedb_delfile(fdb, fdbe->pos);
            my_free(s);
        }
        free_fdbe(&fdbe);
        fdbe = filedb_getfile(fdb, where, GET_FILENAME);
    }

    /*
     * THIRD: optimise database
     *
     * Instead of sorting, we only clean up the db, because sorting is now
     * done on-the-fly when we display the file list.
     */
    if (sort)
        filedb_cleanup(fdb);        /* Cleanup DB           */
    filedb_timestamp(fdb);        /* Write new timestamp  */
}
Exemplo n.º 3
0
static void filedb_update(char *path, FILE * f, int sort)
{
  struct dirent *dd;
  DIR *dir;
  filedb fdb[2];
  char name[61];
  long where, oldwhere;
  struct stat st;
  char s[512];
  int ret;

  /* FIRST: make sure every real file is in the database */
  dir = opendir(path);
  if (dir == NULL) {
    putlog(LOG_MISC, "*", FILES_NOUPDATE);
    return;
  }
  dd = readdir(dir);
  while (dd != NULL) {
    strncpy(name, dd->d_name, 60);
    name[60] = 0;
    if (NAMLEN(dd) <= 60)
      name[NAMLEN(dd)] = 0;
    else {
      /* truncate name on disk */
      char s1[512], s2[256];

      strcpy(s1, path);
      strcat(s1, "/");
      strncat(s1, dd->d_name, NAMLEN(dd));
      s1[strlen(path) + NAMLEN(dd) + 1] = 0;
      sprintf(s2, "%s/%s", path, name);
      movefile(s1, s2);
    }
    if (name[0] != '.') {
      sprintf(s, "%s/%s", path, name);
      stat(s, &st);
      where = 0;
      ret = findmatch(f, name, &where, &fdb[0]);
      if (!ret) {
	/* new file! */
	where = findempty(f);
	fseek(f, where, SEEK_SET);
	fdb[0].version = FILEVERSION;
	fdb[0].stat = 0;	/* by default, visible regular file */
	strcpy(fdb[0].filename, name);
	fdb[0].desc[0] = 0;
	strcpy(fdb[0].uploader, botnetnick);
	fdb[0].gots = 0;
	fdb[0].flags_req[0] = 0;
	fdb[0].uploaded = now;
	fdb[0].size = st.st_size;
	fdb[0].sharelink[0] = 0;
	if (S_ISDIR(st.st_mode))
	  fdb[0].stat |= FILE_DIR;
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      } else if (fdb[0].version < FILEVERSION) {
	/* old version filedb, do the dirty */
	if (fdb[0].version == FILEVERSION_OLD) {
	  filedb_old *fdbo = (filedb_old *) & fdb[0];

	  fdb[0].desc[185] = 0;	/* truncate it */
	  fdb[0].chname[0] = 0;	/* new entry */
	  strcpy(fdb[0].uploader, fdbo->uploader);	/* moved forward
							 * a few bytes */
	  strcpy(fdb[0].flags_req, fdbo->flags_req);	/* and again */
	  fdb[0].version = FILEVERSION;
	  fdb[0].size = st.st_size;
	  fseek(f, where, SEEK_SET);
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	} else {
	  putlog(LOG_MISC, "*", "!!! Unknown filedb type !");
	}
      } else {
	/* update size if needed */
	fdb[0].size = st.st_size;
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      }
    }
    dd = readdir(dir);
  }
  closedir(dir);
  /* SECOND: make sure every db file is real, and sort as we go,
   * if we're sorting */
  rewind(f);
  while (!feof(f)) {
    where = ftell(f);
    fread(&fdb[0], sizeof(filedb), 1, f);
    if (!feof(f)) {
      if (!(fdb[0].stat & FILE_UNUSED) && !fdb[0].sharelink[0]) {
	sprintf(s, "%s/%s", path, fdb[0].filename);
	if (stat(s, &st) != 0) {
	  /* gone file */
	  fseek(f, where, SEEK_SET);
	  fdb[0].stat |= FILE_UNUSED;
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	  /* sunos and others will puke bloody chunks if you write the
	   * last record in a file and then attempt to read to EOF: */
	  fseek(f, where, SEEK_SET);
	  continue;		/* cycle to next one */
	}
      }
      if (sort && !(fdb[0].stat & FILE_UNUSED)) {
	rewind(f);
	oldwhere = ftell(f);
	ret = 0;
	while (!feof(f) && (oldwhere < where)) {
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  if (!feof(f)) {
	    if ((fdb[0].stat & FILE_UNUSED) ||
		(strcasecmp(fdb[ret].filename,
			    fdb[1 - ret].filename) < 0)) {
	      /* our current is < the checked one, insert here */
	      fseek(f, oldwhere, SEEK_SET);
	      fwrite(&fdb[ret], sizeof(filedb), 1, f);
	      ret = 1 - ret;
	      /* and fall out */
	    }
	    /* otherwise read next entry */
	    oldwhere = ftell(f);
	  }
	}
	/* here, either we've found a place to insert, or got to
	 * the end of the list */
	/* if we've got to the end of the current list oldwhere == where
	 * so we fall through ret will point to the current valid one */
	while (!feof(f) && (oldwhere < where)) {
	  /* need to move this entry up 1 .. */
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  oldwhere = ftell(f);
	  /* write lower record here */
	  fseek(f, oldwhere, SEEK_SET);
	  fwrite(&fdb[ret], sizeof(filedb), 1, f);
	  ret = 1 - ret;
	}
	/* when we get here fdb[ret] holds the last record,
	 * which needs  to be written where we first grabbed the
	 * record from */
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[ret], sizeof(filedb), 1, f);
      }
    }
  }
  /* write new timestamp */
  filedb_timestamp(f);
}