On Mon, Jul 20, 2009 at 10:11:15PM -0600, lee wrote:
> 
> Here's the program. Let me know how you like it :)

Hn, one small adjustment: The recursion level is irrelevant, but I
forgot to remove the counter.



// check a directory hierachy for maildir directories recursively; print
// mailbox commands that can be used for mutt
// error messages are printed to stdout
// print a warning to stderr when there are other directories
//   than cur, new, tmp found in a maildir
//
// (c) H. Wilmer, Mon Jul 20 17:17:45 MDT 2009
// l...@yun.yagibdah.de
// licensed under the GNU GENERAL PUBLIC LICENSE
// use at your own risk
//
// to compile: # gcc mutt-mb.c -o mutt-mb -O2
//
// version 0.2
//
// mutt-mb.c
//   returns !0 on error


#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>


// proto
int main(int argc, char *argv[] );
extern void usage();
int weed_out_nondirectories(const struct dirent *);
int scan_directory(char *dirp);



void usage() {
  fputs("usage: mutt-mb [directory]\n", stderr);
  fflush(stderr);
}


// filter function, see man 3 scandir
int weed_out_nondirectories(const struct dirent *de) {
  // weed out non-directories
  if(de->d_type != DT_DIR) {
    return 0;
  }
  // weed out directory pointers
  if( !strcmp(de->d_name, ".") ) {
    return 0;
  }
  if( !strcmp(de->d_name, "..") ) {
    return 0;
  }
  // it's a directory
  return 1;
}


int scan_directory(char *dirp) {
  struct dirent **namelist;
  int scan = -1, check = 0;
  int ret = 0;
  int cwd = -1;
  char *this;
  int found_cur;
  int found_new;
  int found_tmp;
  int found_other;

  // change into the directory
  cwd = chdir(dirp);
  if(cwd < 0) {
    fputs(dirp, stderr);
    perror("chdir");
    return 2;
  }
  // and find out where we are
  this = getcwd(NULL, 0);
  if(this == NULL) {
    perror("getcwd");
    // this shouldn't happen, so rather exit
    return -1;
  }

  // scan this directory
  check = scan = scandir(this, &namelist, weed_out_nondirectories, alphasort);
  if(scan < 0) {
    perror("scandir");
    free(this);
    return 1;
  }

  // check if this is a maildir
  found_cur = 1;
  found_new = 1;
  found_tmp = 1;
  found_other = 0;
  while(check--) {
    //    printf("check %s/%s\n", this, namelist[check]->d_name);

    if(found_cur) {
      found_cur = strcmp("cur", namelist[check]->d_name);
    } else {
      found_other++;
    }
    if(found_new) {
      found_new = strcmp("new", namelist[check]->d_name);
    } else {
      found_other++;
    }
    if(found_tmp) {
      found_tmp = strcmp("tmp", namelist[check]->d_name);
    } else {
      found_other++;
    }

    if( !found_cur && !found_new && !found_tmp) {
      // it's a maildir
      printf("mailboxes = %s\n", this);
      found_other -= 3;
      if(found_other) {
        fprintf(stderr, "warning: %5d strange directory/-ies found in %s\n", \
                found_other, this);
      }
    }
  }

  free(this);

  // for each directory in this, look for subdirectories
  while(scan--) {
    ret = scan_directory(namelist[scan]->d_name);
    switch(ret) {
    case 0:
      // means ok
      // there shouldn't be any errors ...
      break;
    case 2:
      fputs("couldn't change into subdirectory\n", stderr);
      fflush(stderr);
      return 2;
      break;
    case -1:
      fputs("coulnd't find out what the current directory is\n", stderr);
      fflush(stderr);
      return -1;
      break;
    case 1:
      fputs("couldn't scan a directory\n", stderr);
      fflush(stderr);
      return 1;
      break;
    case -2:
      fputs("couldn't change back to directory above\n", stderr);
      fflush(stderr);
      return -2;
      break;
    }
    free(namelist[scan]);
  }
  free(namelist);

  cwd = chdir("..");
  if(cwd < 0) {
    perror("chdir");
    // shouldn't happen
    return -2;
  }

  return 0;
}


int main(int argc, char *argv[] ) {
  int ret = 0;
  // check args
  if(argc != 2) {
    usage();
    exit(1);
  }

  // scan the directory

  ret = scan_directory(argv[1]);
  if(ret) {
    fprintf(stderr, "error: %d\n", ret);
    exit(ret);
  }

  exit(0);
}

Reply via email to