/*Insert the given value into the given btree and place it at the tail of the associated queue.*/ static void insert_newest(int v, btree *t) { register node *n, *p; if((t->tail+2)%(THRESH_FILTER_LEN+1) == t->head) { fprintf(stderr, "insert_newest: queue is full; deleting oldest to make room\n"); delete_oldest(t); } t->tail = (t->tail+1)%(THRESH_FILTER_LEN+1); p = NULLTREE; n = t->tree; while((n != NULLTREE) && (n->value != v)) /*inv: 'p' is the parent of 'n'. All 'subtree_ref_count' fields on the path from 't->tree' to 'p' have been incremented. The proper location for the new value 'v' lies somewhere in the subtree rooted at 'n'.*/ { n->subtree_ref_count++; p = n; n = (v<n->value? n->left_child: n->right_child); } if(n == NULLTREE) { register node **graft_site; graft_site = (p==NULLTREE? &(t->tree): v<p->value? &(p->left_child): &(p->right_child) ); *graft_site = create_node(v, 1, 1, p, NULLTREE, NULLTREE); t->queue[t->tail] = *graft_site; } else { n->ref_count++; n->subtree_ref_count++; t->queue[t->tail] = n; } }
int main(int argc, char * const argv[]) { std::string dir("/var/log/messages"); size_t max_dir_size = 2000*1024; size_t max_file_size = 200*1024; if(max_dir_size < max_file_size) throw std::logic_error("Files size are inconsistant. max_dir must be > max_file"); size_t boot_count = 0; bool boot_count_set = false; bool single_rotate_mode = false; bool output_filename_mode = false; int opt; const char * opts = "O:s:d:n:fg"; while((opt = getopt(argc, argv, opts)) != -1) { switch(opt) { case 'O': dir = std::string(optarg); break; case 's': max_file_size = std::stoi(optarg)*1024; break; case 'd': max_dir_size = std::stoi(optarg)*1024; case 'n': boot_count = std::stoi(optarg); boot_count_set = true; break; case 'f': single_rotate_mode = true; break; case 'g': output_filename_mode = true; break; default: help(std::cerr); exit(EXIT_FAILURE); break; } } if(!boot_count_set) { std::cerr << "Invalid configuration.\n"; help(std::cerr); exit(EXIT_FAILURE); } log_pattern default_log; default_log.boot_count = boot_count; default_log.prefix = "log"; std::stringstream ss; ss << dir << '/' << default_log.active_name(); std::string const full_path = ss.str(); if(single_rotate_mode) { rotate(dir, boot_count); } else if(output_filename_mode) { std::cout << full_path << '\n'; } else { std::cout << "Managing " << full_path << " in dir " << dir << " with maxsize " << max_file_size << " and " << max_dir_size << '\n'; while(1) { { //Open a new scope for RAII. We want the ifd destructor to close the file descriptors. inotify_fd ifd(full_path, IN_CLOSE); ifd.wait(); } if(file_size(full_path) > max_file_size) { std::cout << "File is too big. Rotating\n"; rotate(dir, boot_count); } while(dir_size(dir) > max_dir_size) { std::cout << "Directory is too big. Rotating\n"; delete_oldest(dir); } } } }