Exemple #1
0
/*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);
            }
        }
    }
}