Esempio n. 1
0
void RotateFile (pcapfile_t *pcapfile, time_t t_CloseRename, int live)
{
	struct pcap_stat p_stat;
	void *_b;

	dbg_printf ("RotateFile() time: %s\n", UNIX2ISO (t_CloseRename));
	// make sure, alternate buffer is already flushed
	pthread_mutex_lock (&pcapfile->m_pbuff);
	while (pcapfile->alternate_size) {
		pthread_cond_wait (&pcapfile->c_pbuff, &pcapfile->m_pbuff);
	}

	// swap buffers
	_b = pcapfile->data_buffer;
	pcapfile->data_buffer = pcapfile->alternate_buffer;
	pcapfile->data_ptr = pcapfile->data_buffer;
	pcapfile->alternate_buffer = _b;
	pcapfile->alternate_size = pcapfile->data_size;
	pcapfile->t_CloseRename = t_CloseRename;

	// release mutex and signal thread
	pthread_mutex_unlock (&pcapfile->m_pbuff);
	pthread_cond_signal (&pcapfile->c_pbuff);

	pcapfile->data_size = 0;

	if (live) {
		// not a capture file
		if (pcap_stats (pcapfile->p, &p_stat) < 0) {
			LogError ("pcap_stats() failed: %s", pcap_geterr (pcapfile->p));
		} else {
			LogInfo ("Packets received: %u, dropped: %u, dropped by interface: %u ",
			         p_stat.ps_recv, p_stat.ps_drop, p_stat.ps_ifdrop);
		}
	}

} // End of RotateFile
Esempio n. 2
0
void ExpireProfile(channel_t *channel, dirstat_t *current_stat, uint64_t maxsize, uint64_t maxlife, uint32_t runtime ) {
int  		size_done, lifetime_done, done;
char 		*expire_timelimit = "";
time_t		now = time(NULL);
uint64_t	sizelimit, num_expired;

	if ( !channel ) 
		return;

	done = 0;
	SetupSignalHandler();

	if ( maxlife ) {
//		time_t t_expire = now - maxlife;
		// build an appropriate string for comparing
		time_t t_watermark = now - (time_t)((maxlife * current_stat->low_water)/100);

//	printf("Expire files before %s", ctime(&t_expire));
		expire_timelimit = strdup(UNIX2ISO(t_watermark));
//	printf("down to %s", ctime(&t_watermark));
//	printf("Diff: %i\n", t_watermark - t_expire );

	}

	size_done 		= maxsize == 0 || current_stat->filesize < maxsize;
	sizelimit 		= (current_stat->low_water * maxsize)/100;
	lifetime_done 	= maxlife == 0 || ( now - current_stat->first ) < maxlife;

	num_expired = 0;

	PrepareDirLists(channel);
	if ( runtime )
		alarm(runtime);
	while ( !done ) {
		char *p;
		int file_removed;

		// search for the channel with oldest file. If all channel have same age, 
		// get the last in the list
		channel_t *expire_channel  = channel;
		channel_t *compare_channel = expire_channel->next;
		while ( compare_channel ) {
			if ( expire_channel->ftsent == NULL ) {
				expire_channel = compare_channel;
			}
			if ( compare_channel->ftsent == NULL ) {
				compare_channel = compare_channel->next;
				continue;
			}
			// at this point expire_channel and current_channel fts entries are valid
			if ( strcmp(expire_channel->ftsent->fts_name, compare_channel->ftsent->fts_name) >= 0 ) {
				expire_channel = compare_channel;
			}
			compare_channel = compare_channel->next;
		}
		if ( !expire_channel->ftsent ) {
			// no more entries in any channel - we are done
			done = 1;
			continue;
		}

		// flag is file got removed
		file_removed = 0;

		// expire_channel now points to the channel with oldest file
		// do expire
		p = &(expire_channel->ftsent->fts_name[7]);
//	printf("File: %s\n", expire_channel->ftsent->fts_path);

		if ( !size_done ) {
			// expire size-wise if needed
//	printf("	Size expire %llu %llu\n", current_stat->filesize, sizelimit);
			if ( current_stat->filesize > sizelimit ) {
				// need to delete this file
				if ( unlink(expire_channel->ftsent->fts_path) == 0 ) {
					// Update profile stat
					current_stat->filesize 			  -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					current_stat->numfiles--;

					// Update channel stat
					expire_channel->dirstat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					expire_channel->dirstat->numfiles--;

					// decrement number of files seen in this directory
					expire_channel->ftsent->fts_number--;

					file_removed = 1;
					num_expired++;
				} else {
					LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
				}
			} else {
				// we are done size-wise
				// time of first file not expired = start time of channel/profile
				expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
				size_done = 1;
			}
		} else if ( !lifetime_done ) {
//	printf("	Time expire \n");
			// expire time-wise if needed
			// this part of the code is executed only when size-wise is already fullfilled
			if ( strcmp(p, expire_timelimit) < 0  ) {
				// need to delete this file
				if ( unlink(expire_channel->ftsent->fts_path) == 0 ) {
					// Update profile stat
					current_stat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					current_stat->numfiles--;

					// Update channel stat
					expire_channel->dirstat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					expire_channel->dirstat->numfiles--;

					// decrement number of files seen in this directory
					expire_channel->ftsent->fts_number--;

					file_removed = 1;
					num_expired++;
				} else {
					LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
				}
			} else {
				// we are done time-wise
				// time of first file not expired = start time of channel/profile
				expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
				lifetime_done = 1;
			}
		} else 
			// all done
			done = 1;
		if ( timeout ) 
			done = 1;

		// advance fts entry in expire channel to next file, if file was removed
		if ( file_removed ) {
			expire_channel->ftsent = fts_read(expire_channel->fts);
			while ( expire_channel->ftsent ) {
				if ( expire_channel->ftsent->fts_info == FTS_F ) { // entry is a file
					expire_channel->ftsent->fts_number++;
					if ( expire_channel->ftsent->fts_namelen == 19 && 
					 	strncmp(expire_channel->ftsent->fts_name, "nfcapd.", 7) == 0 ) {
						// if ftsent points to next valid file
						char *p = &(expire_channel->ftsent->fts_name[7]);
						// next file is first (oldest) for channel and for profile - update first mark
						expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
						break;
					}
				} else {
	
					switch (expire_channel->ftsent->fts_info) {
						case FTS_D:	// entry is a directory
							// set number of files seen in this directory = 0
							expire_channel->ftsent->fts_number = 0;
							// skip all '.' entries as well as hidden directories
							if ( expire_channel->ftsent->fts_level > 0 && expire_channel->ftsent->fts_name[0] == '.' ) 
								fts_set(expire_channel->fts, expire_channel->ftsent, FTS_SKIP);
							// any valid directory needs to start with a digit ( %Y -> year )
							if ( expire_channel->ftsent->fts_level > 0 && !isdigit(expire_channel->ftsent->fts_name[0]) ) 
								fts_set(expire_channel->fts, expire_channel->ftsent, FTS_SKIP);
							break;
						case FTS_DP:
							// do not delete base data directory ( level == 0 )
							if ( expire_channel->ftsent->fts_number == 0 && expire_channel->ftsent->fts_level > 0 ) {
								// directory is empty and can be deleted
//	printf("Will remove directory %s\n", expire_channel->ftsent->fts_path);
								if ( rmdir(expire_channel->ftsent->fts_path) != 0 ) {
									LogError( "rmdir() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
								}
							}
							break;
					}
				}
				// otherwise loop
				expire_channel->ftsent = fts_read(expire_channel->fts);
			} // end advance fts entry
			file_removed = 0;
		}

		if ( expire_channel->ftsent == NULL ) {
			// this channel has no more files now
			expire_channel->dirstat->first 			= expire_channel->dirstat->last;
			if ( expire_channel->dirstat->numfiles ) {	
				// if channel is empty, no files must be reported, but rebuild is done anyway
				LogError( "Inconsitency detected in channel %s. Will rebuild automatically.\n", expire_channel->datadir);
				LogError( "No more files found, but %llu expected.\n", expire_channel->dirstat->numfiles);
			}
			expire_channel->dirstat->numfiles 	= 0;
			expire_channel->dirstat->status		= FORCE_REBUILD;
		}
	} // while ( !done )

	if ( runtime )
		alarm(0);
	if ( timeout ) {
		LogError( "Maximum execution time reached! Interrupt expire.\n");
	}

} // End of ExpireProfile
Esempio n. 3
0
void ExpireDir(char *dir, dirstat_t *dirstat, uint64_t maxsize, uint64_t maxlife, uint32_t runtime ) {
FTS 		*fts;
FTSENT 		*ftsent;
uint64_t	sizelimit, num_expired;
int			done, size_done, lifetime_done, dir_files;
char *const path[] = { dir, NULL };
char		*expire_timelimit = NULL;
time_t 		now = time(NULL);

	dir_files = 0;
	if ( dirstat->low_water == 0 )
		dirstat->low_water = 95;

	if ( runtime ) {
		SetupSignalHandler();
		alarm(runtime);
	}

	if ( maxlife ) {
		// build an appropriate string for comparing
		time_t t_expire = now - maxlife;
		
		time_t t_watermark = now - (time_t)((maxlife * dirstat->low_water)/100);

// printf("Expire files before %s", ctime(&t_expire));
		expire_timelimit = strdup(UNIX2ISO(t_watermark));
// printf("down to %s", ctime(&t_watermark));
// printf("Diff: %i\n", t_watermark - t_expire );

		if ( dirstat->last < t_expire && (isatty(STDIN_FILENO) ) ) {
			// this means all files will get expired - are you sure ?
			char *s, s1[32], s2[32];
			time_t	t;
			struct tm *when;

			t = t_expire;
			when = localtime(&t);
			strftime(s1, 31, "%Y-%m-%d %H:%M:%S", when);
			s1[31] = '\0';
			
			t = dirstat->last;
			when = localtime(&t);
			strftime(s2, 31, "%Y-%m-%d %H:%M:%S", when);
			s2[31] = '\0';
			
			printf("Your max lifetime of %s will expire all file before %s\n", ScaleTime(maxlife), s1);
			printf("Your latest files are dated %s. This means all files will be deleted!\n", s2);
			printf("Are you sure? yes/[no] ");
			s = fgets(s1, 31, stdin);
			s1[31] = '\0';
			if ( s && strncasecmp(s1, "yes\n", 31) == 0 ) {
				printf("Ok - you've beeen warned!\n");
			} else {
				printf("Expire canceled!\n");
				return;
			}
		}
	}

	done 		  = 0;
	size_done 	  = maxsize == 0 || dirstat->filesize < maxsize;
	lifetime_done = maxlife == 0 || ( now - dirstat->first ) < maxlife;
	sizelimit = (dirstat->low_water * maxsize)/100;
	num_expired = 0;
	fts = fts_open(path, FTS_LOGICAL,  compare);
	while ( !done && ((ftsent = fts_read(fts)) != NULL) ) {
		if ( ftsent->fts_info == FTS_F ) {
			dir_files++;	// count files in directories
			if ( ftsent->fts_namelen == 19 && strncmp(ftsent->fts_name, "nfcapd.", 7) == 0 ) {
				// nfcapd.200604301200 strlen = 19
				char *s, *p = &(ftsent->fts_name[7]);
	
				// process only nfcapd. files
				// make sure it's really an nfcapd. file and we have 
				// only digits in the rest of the file name
				s = p;
				while ( *s ) {
					if ( *s < '0' || *s > '9' ) 
						break;
					s++;
				}
				// otherwise skip
				if ( *s )
					continue;

				// expire size-wise if needed
				if ( !size_done ) {
					if ( dirstat->filesize > sizelimit ) {
						if ( unlink(ftsent->fts_path) == 0 ) {
							dirstat->filesize -= 512 * ftsent->fts_statp->st_blocks;
							num_expired++;
							dir_files--;
						} else {
							LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
						continue;	// next file if file was unlinked
					} else {
						dirstat->first = ISO2UNIX(p);	// time of first file not expired
						size_done = 1;
					}
				}

				// expire time-wise if needed
				// this part of the code is executed only when size-wise is fullfilled
				if ( !lifetime_done ) {
					if ( expire_timelimit && strcmp(p, expire_timelimit) < 0  ) {
						if ( unlink(ftsent->fts_path) == 0 ) {
							dirstat->filesize -= 512 * ftsent->fts_statp->st_blocks;
							num_expired++;
							dir_files--;
						} else {
							LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
						lifetime_done = 0;
					} else {
						dirstat->first = ISO2UNIX(p);	// time of first file not expired
						lifetime_done = 1;
					}
				}
				done = (size_done && lifetime_done) || timeout;

			}
		} else {
			switch (ftsent->fts_info) {
				case FTS_D:
					// set pre-order flag
					dir_files = 0;
					// skip all '.' entries as well as hidden directories
					if ( ftsent->fts_level > 0 && ftsent->fts_name[0] == '.' ) 
						fts_set(fts, ftsent, FTS_SKIP);
					// any valid directory needs to start with a digit ( %Y -> year )
					if ( ftsent->fts_level > 0 && !isdigit(ftsent->fts_name[0]) ) 
						fts_set(fts, ftsent, FTS_SKIP);
					break;
				case FTS_DP:
					// do not delete base data directory ( level == 0 )
					if ( dir_files == 0 && ftsent->fts_level > 0 ) {
						// directory is empty and can be deleted
// printf("Will remove directory %s\n", ftsent->fts_path);
						if ( rmdir(ftsent->fts_path) != 0 ) {
							LogError( "rmdir() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
					}
					break;
			}
		}
	}
	fts_close(fts);
	if ( !done ) {
		// all files expired and limits not reached
		// this may be possible, when files get time-wise expired and
		// the time limit is shorter than the latest file
		dirstat->first = dirstat->last;
	}
	if ( runtime )
		alarm(0);
	if ( timeout ) {
		LogError( "Maximum execution time reached! Interrupt expire.\n");
	}
	if ( num_expired > dirstat->numfiles ) {
		LogError( "Error updating stat record: Number of files inconsistent!\n");
		LogError( "Will automatically rebuild this directory next time\n");
		dirstat->numfiles = 0;
		dirstat->status = FORCE_REBUILD;
	} else {
		dirstat->numfiles -= num_expired;
	}
	if ( dirstat->numfiles == 0 ) {
		dirstat->first  = dirstat->last = time(NULL);
		dirstat->status = FORCE_REBUILD;
	}

	free(expire_timelimit);

} // End of ExpireDir