commands/vrehash.cc
changeset 2 b3afb9f1e801
parent 0 6f7a81934006
equal deleted inserted replaced
1:30113bfbe723 2:b3afb9f1e801
     1 
       
     2 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
     1 // Copyright (C) 1999,2000 Bruce Guenter <bruceg@em.ca>
     3 //
     2 //
     4 // This program is free software; you can redistribute it and/or modify
     3 // This program is free software; you can redistribute it and/or modify
     5 // it under the terms of the GNU General Public License as published by
     4 // it under the terms of the GNU General Public License as published by
     6 // the Free Software Foundation; either version 2 of the License, or
     5 // the Free Software Foundation; either version 2 of the License, or
    23 #include "misc/autodelete.h"
    22 #include "misc/autodelete.h"
    24 #include "fdbuf/fdbuf.h"
    23 #include "fdbuf/fdbuf.h"
    25 #include "mystring/mystring.h"
    24 #include "mystring/mystring.h"
    26 #include "misc/maildir.h"
    25 #include "misc/maildir.h"
    27 #include "config/configrc.h"
    26 #include "config/configrc.h"
    28 #include "vpwentry/vpwentry.h"
       
    29 #include "vcommand.h"
    27 #include "vcommand.h"
    30 #include "misc/stat_fns.h"
    28 #include "misc/stat_fns.h"
    31 #include "cli/cli.h"
    29 #include "cli++/cli++.h"
    32 #include "cdb++/cdb++.h"
       
    33 
    30 
    34 const char* cli_program = "vrehash";
    31 const char* cli_program = "vrehash";
    35 const char* cli_help_prefix = "Reorganize users directory\n"
    32 const char* cli_help_prefix = "Reorganize users directory\n"
    36 "Renames user directories in a virtual domain to match the current\n"
    33 "Renames user directories in a virtual domain to match the current\n"
    37 "partitioning scheme\n";
    34 "partitioning scheme\n";
    72 // an error occurs.
    69 // an error occurs.
    73 // If an error occurs, you will have to check the status of the current
    70 // If an error occurs, you will have to check the status of the current
    74 // directory, the virtual password file, and all the virtual users
    71 // directory, the virtual password file, and all the virtual users
    75 // subdirectories in both C<users> and C<new.users>.
    72 // subdirectories in both C<users> and C<new.users>.
    76 
    73 
    77 static cdb_reader* in = 0;
    74 static vpwtable_reader* in = 0;
    78 static cdb_writer* out = 0;
    75 static vpwtable_writer* out = 0;
    79 static mystring cdbfilename;
       
    80 static mystring tmpfilename;
       
    81 static mystring newuserdir;
    76 static mystring newuserdir;
    82 static mystring backupdir;
    77 static mystring backupdir;
    83 
    78 
    84 mystring lock_dir()
    79 mystring lock_dir()
    85 {
    80 {
    88     return "Error stat'ing the current directory ?!?";
    83     return "Error stat'ing the current directory ?!?";
    89   if(buf.st_mode & S_ISVTX)
    84   if(buf.st_mode & S_ISVTX)
    90     return "Directory is already locked";
    85     return "Directory is already locked";
    91   if(chmod(".", buf.st_mode | S_ISVTX))
    86   if(chmod(".", buf.st_mode | S_ISVTX))
    92     return "Can't lock directory";
    87     return "Can't lock directory";
    93   cdbfilename = password_file + ".cdb";
    88 
    94   tmpfilename = cdbfilename + ".tmp";
    89   vpwtable* table = domain.table();
    95   in = new cdb_reader(cdbfilename);
    90   
       
    91   in = table->start_read();
    96   if(!*in)
    92   if(!*in)
    97     return "Could not open virtual password table";
    93     return "Could not open virtual password table";
    98   out = new cdb_writer(tmpfilename, 0600);
    94 
       
    95   out = table->start_write();
    99   if(!*out)
    96   if(!*out)
   100     return "Could not open temporary table exclusively";
    97     return "Could not open virtual password table writer";
   101   return "";
    98 
       
    99   return 0;
   102 }
   100 }
   103 
   101 
   104 mystring unlock_dir()
   102 mystring unlock_dir()
   105 {
   103 {
   106   struct stat buf;
   104   struct stat buf;
   109   if(!(buf.st_mode & S_ISVTX))
   107   if(!(buf.st_mode & S_ISVTX))
   110     return "Directory was not locked";
   108     return "Directory was not locked";
   111   if(chmod(".", buf.st_mode & ~S_ISVTX))
   109   if(chmod(".", buf.st_mode & ~S_ISVTX))
   112     return "Can't unlock directory";
   110     return "Can't unlock directory";
   113   if(out) {
   111   if(out) {
   114     if(out->end(cdbfilename)) {
   112     if(out->end()) {
   115       delete out;
   113       delete out;
   116       return "Error completing the virtual password table";
   114       return "Error completing the virtual password table";
   117     }
   115     }
   118     delete out;
   116     delete out;
   119   }
   117   }
   120   delete in;
   118   delete in;
   121   return "";
   119   return "";
   122 }
       
   123 
       
   124 bool getvpwent(vpwentry& vpw)
       
   125 {
       
   126   autodelete<datum> d = in->nextrec();
       
   127   if(!d)
       
   128     return false;
       
   129   vpw.from_record(d->key, d->data);
       
   130   return true;
       
   131 }
   120 }
   132 
   121 
   133 mystring user_dir;
   122 mystring user_dir;
   134 
   123 
   135 mystring translate_one(vpwentry& vpw)
   124 mystring translate_one(vpwentry& vpw)
   139 		  domain.userdir(vpw.name).right(user_dir.length());
   128 		  domain.userdir(vpw.name).right(user_dir.length());
   140   mystring vpwdir = "./" + domain.userdir(vpw.name);
   129   mystring vpwdir = "./" + domain.userdir(vpw.name);
   141   mystring tmpdir = newdir.left(newdir.find_last('/'));
   130   mystring tmpdir = newdir.left(newdir.find_last('/'));
   142   if(mkdirp(tmpdir.c_str(), 0755))
   131   if(mkdirp(tmpdir.c_str(), 0755))
   143     return "Error creating a user subdirectory: " + tmpdir;
   132     return "Error creating a user subdirectory: " + tmpdir;
   144   if(rename(vpw.mailbox.c_str(), newdir.c_str()))
   133   if(rename(vpw.directory.c_str(), newdir.c_str()))
   145     return "Error moving a user subdirectory." + vpw.mailbox;
   134     return "Error moving a user subdirectory." + vpw.directory;
   146   vpw.mailbox = vpwdir;
   135   vpw.directory = vpwdir;
   147   return "";
   136   return "";
   148 }
   137 }
   149 
   138 
   150 mystring translate()
   139 mystring translate()
   151 {
   140 {
   152   vpwentry vpw;
   141   vpwentry* vpw;
   153   unsigned errors = 0;
   142   unsigned errors = 0;
   154   while(getvpwent(vpw)) {
   143   while((vpw = in->get()) != 0) {
   155     if(!!vpw.mailbox) {
   144     if(vpw->has_mailbox) {
   156       mystring response = translate_one(vpw);
   145       mystring response = translate_one(*vpw);
   157       if(!!response) {
   146       if(!!response) {
   158 	ferr << "vrehash: " << response;
   147 	ferr << "vrehash: " << response;
   159 	++errors;
   148 	++errors;
   160       }
   149       }
   161     }
   150     }
   162     if(!out->put(vpw.name, vpw.to_record())) {
   151     if(!out->put(*vpw)) {
   163       return "vrehash: failed to add entry to table";
   152       return "vrehash: failed to add entry to table";
   164       ++errors;
   153       ++errors;
   165     }
   154     }
       
   155     delete vpw;
   166   }
   156   }
   167   return "";
   157   return "";
   168 }
   158 }
   169 
   159 
   170 mystring renamedirs()
   160 mystring renamedirs()