static void do_expire(char *datadir) { bookkeeper_t *books; dirstat_t *dirstat, oldstat; int ret, bookkeeper_stat, do_rescan; syslog(LOG_INFO, "Run expire on '%s'", datadir); do_rescan = 0; ret = ReadStatInfo(datadir, &dirstat, CREATE_AND_LOCK); switch (ret) { case STATFILE_OK: break; case ERR_NOSTATFILE: dirstat->low_water = 95; case FORCE_REBUILD: syslog(LOG_INFO, "Force rebuild stat record"); do_rescan = 1; break; case ERR_FAIL: syslog(LOG_ERR, "expire failed: can't read stat record"); return; /* not reached */ break; default: syslog(LOG_ERR, "expire failed: unexpected return code %i reading stat record", ret); return; /* not reached */ } bookkeeper_stat = AccessBookkeeper(&books, datadir); if ( do_rescan ) { RescanDir(datadir, dirstat); if ( bookkeeper_stat == BOOKKEEPER_OK ) { ClearBooks(books, NULL); // release the books below } } if ( bookkeeper_stat == BOOKKEEPER_OK ) { bookkeeper_t tmp_books; ClearBooks(books, &tmp_books); UpdateBookStat(dirstat, &tmp_books); ReleaseBookkeeper(books, DETACH_ONLY); } else { syslog(LOG_ERR, "Error %i: can't access book keeping records", ret); } syslog(LOG_INFO, "Limits: Filesize %s, Lifetime %s, Watermark: %llu%%\n", dirstat->max_size ? ScaleValue(dirstat->max_size) : "<none>", dirstat->max_lifetime ? ScaleTime(dirstat->max_lifetime) : "<none>", (unsigned long long)dirstat->low_water); syslog(LOG_INFO, "Current size: %s, Current lifetime: %s, Number of files: %llu", ScaleValue(dirstat->filesize), ScaleTime(dirstat->last - dirstat->first), (unsigned long long)dirstat->numfiles); oldstat = *dirstat; if ( dirstat->max_size || dirstat->max_lifetime ) ExpireDir(datadir, dirstat, dirstat->max_size, dirstat->max_lifetime, 0); WriteStatInfo(dirstat); if ( (oldstat.numfiles - dirstat->numfiles) > 0 ) { syslog(LOG_INFO, "expire completed"); syslog(LOG_INFO, " expired files: %llu", (unsigned long long)(oldstat.numfiles - dirstat->numfiles)); syslog(LOG_INFO, " expired time slot: %s", ScaleTime(dirstat->first - oldstat.first)); syslog(LOG_INFO, " expired file size: %s", ScaleValue(oldstat.filesize - dirstat->filesize)); syslog(LOG_INFO, "New size: %s, New lifetime: %s, Number of files: %llu", ScaleValue(dirstat->filesize), ScaleTime(dirstat->last - dirstat->first), (unsigned long long)dirstat->numfiles); } else { syslog(LOG_INFO, "expire completed - nothing to expire."); } ReleaseStatInfo(dirstat); } // End of do_expire
channel_t *GetChannelList(char *datadir, int is_profile, int do_rescan) { channel_t **c, *channel; stringlist_t dirlist; struct stat stat_buf; int i; // Generate list of directories InitStringlist(&dirlist, 32); if ( is_profile ) { DIR *PDIR = opendir(datadir); struct dirent *entry; if ( !PDIR ) { fprintf(stderr, "Can't read profiledir '%s': %s\n",datadir, strerror(errno) ); return NULL; } while ( ( entry = readdir(PDIR)) != NULL ) { char stringbuf[MAXPATHLEN]; snprintf(stringbuf, MAXPATHLEN-1, "%s/%s", datadir, entry->d_name); stringbuf[MAXPATHLEN-1] = '\0'; if ( stat(stringbuf, &stat_buf) ) { fprintf(stderr, "Can't stat '%s': %s\n",stringbuf, strerror(errno) ); continue; } if ( !S_ISDIR(stat_buf.st_mode) ) continue; // skip all '.' entries -> make .anything invisible to nfprofile if ( entry->d_name[0] == '.' ) continue; InsertString(&dirlist, stringbuf); } closedir(PDIR); } else { InsertString(&dirlist, datadir); } channel = NULL; c = &channel; for ( i=0; i<dirlist.num_strings; i++ ) { int ret; *c = (channel_t *)malloc(sizeof(channel_t)); if ( !*c ) { LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) ); return NULL; } memset((void *)*c, 0, sizeof(channel_t)); (*c)->next = NULL; (*c)->datadir = dirlist.list[i]; (*c)->do_rescan = do_rescan; ret = ReadStatInfo((*c)->datadir, &(*c)->dirstat, CREATE_AND_LOCK); switch (ret) { case FORCE_REBUILD: printf("Force rebuild requested by stat record in %s\n", (*c)->datadir); (*c)->do_rescan = 1; // file corrupt - rescan break; case STATFILE_OK: break; case ERR_NOSTATFILE: // first rescan bevore expire, if no file exists if ( do_rescan == 0 ) { printf("Force rebuild to create stat record in %s\n", (*c)->datadir); (*c)->do_rescan = 1; } // else do_rescan is already set - do not report break; default: exit(250); } (*c)->books_stat = AccessBookkeeper(&((*c)->books), (*c)->datadir); if ( (*c)->books_stat == ERR_FAILED ) { fprintf(stderr, "Failed to access bookkeeping record.\n"); exit(250); } c = &(*c)->next; } return channel; } // End of GetChannelList