daemon/autoresponse.cc
changeset 0 6f7a81934006
child 2 b3afb9f1e801
equal deleted inserted replaced
-1:000000000000 0:6f7a81934006
       
     1 // Copyright (C) 2000 Mike Bell <mike@mikebell.org>,
       
     2 // Bruce Guenter <bruceg@em.ca>
       
     3 //
       
     4 // 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
       
     6 // the Free Software Foundation; either version 2 of the License, or
       
     7 // (at your option) any later version.
       
     8 //
       
     9 // This program is distributed in the hope that it will be useful,
       
    10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 // GNU General Public License for more details.
       
    13 //
       
    14 // You should have received a copy of the GNU General Public License
       
    15 // along with this program; if not, write to the Free Software
       
    16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    17 
       
    18 #include <config.h>
       
    19 #include <stdlib.h>
       
    20 #include <sys/stat.h>
       
    21 #include <stdio.h>
       
    22 #include "daemon.h"
       
    23 #include "config/configrc.h"
       
    24 #include "misc/response.h"
       
    25 #include "misc/lookup.h"
       
    26 #include "misc/maildir.h"
       
    27 #include "misc/pwentry_table.h"
       
    28 #include "misc/stat_fns.h"
       
    29 
       
    30 response autoresponse_write(const mystring& directory,
       
    31 			    const mystring& location,
       
    32 			    const mystring& disabled,
       
    33 			    const mystring& msg)
       
    34 {
       
    35   mystring tmpfile = location + ".lock";
       
    36 
       
    37   if(!is_dir(directory.c_str())) {
       
    38     if(mkdir(directory.c_str(), 0755))
       
    39       RETURN(err, "Could not create autoresponse directory");
       
    40   }
       
    41   
       
    42   if(is_exist(tmpfile.c_str()))
       
    43     RETURN(err, "Temporary autoresponse file already exists");
       
    44 
       
    45   if(is_exist(disabled.c_str()))
       
    46     RETURN(err, "Autoresponse is disabled, reenable it before writing a new message");
       
    47   
       
    48   fdobuf out(tmpfile.c_str(), fdobuf::create | fdobuf::excl, 0644);
       
    49   if(!out)
       
    50     RETURN(err, "Unable to open temporary autoresponse file for writing");
       
    51 
       
    52   out << msg;
       
    53   if(!out.flush() || !out.close()) {
       
    54     unlink(tmpfile.c_str());
       
    55     RETURN(err, "Unable to write message to file");
       
    56   }
       
    57   if(rename(tmpfile.c_str(), location.c_str())) {
       
    58     unlink(tmpfile.c_str());
       
    59     RETURN(err, "Unable to rename temporary autoresponse file");
       
    60   }
       
    61 
       
    62   RETURN(ok, "Message successfully written to autoresponse file");
       
    63 }
       
    64 
       
    65 response autoresponse_disable(const mystring& location,
       
    66 			      const mystring& disabled)
       
    67 {
       
    68   if(!is_exist(location.c_str()))
       
    69     RETURN(ok, "Autoresponse file did not exist");
       
    70   if(is_exist(disabled.c_str()))
       
    71     RETURN(err, "Disabled autoresponse file already exists");
       
    72   if(rename(location.c_str(), disabled.c_str()))
       
    73     RETURN(err, "Unable to rename autoresponse file");
       
    74   RETURN(ok, "Autoresponse file sucessfully disabled");
       
    75 }  
       
    76 
       
    77 response autoresponse_enable(const mystring& location,
       
    78 			     const mystring& disabled)
       
    79 {
       
    80   if(is_exist(location.c_str()))
       
    81     RETURN(ok, "Autoresponse is already enabled");
       
    82   if(!is_exist(disabled.c_str()))
       
    83     RETURN(err, "Disabled autoresponse file did not exist");
       
    84   if(rename(disabled.c_str(), location.c_str()))
       
    85     RETURN(err, "Unable to rename previously disabled autoresponse file");
       
    86   RETURN(ok, "Autoresponse file sucessfully restored");
       
    87 }  
       
    88 
       
    89 static bool read_file(const mystring& filename, mystring& out)
       
    90 {
       
    91   fdibuf in(filename.c_str());
       
    92   if(!in)
       
    93     return false;
       
    94   char contents[65536];
       
    95   unsigned contentlen;
       
    96   in.read(contents, 65536);
       
    97   contentlen = in.last_count();
       
    98   out = mystring(contents, contentlen);
       
    99   return true;
       
   100 }
       
   101 
       
   102 response autoresponse_read(const mystring& location,
       
   103 			   const mystring& disabled, int fd)
       
   104 {
       
   105   mystring line;
       
   106   if(!is_exist(location.c_str()) &&
       
   107      !is_exist(disabled.c_str()))
       
   108     RETURN(err, "Autoresponder file does not exist");
       
   109 
       
   110   mystring contents;
       
   111   if(!read_file(location, contents) &&
       
   112      !read_file(disabled, contents))
       
   113     RETURN(err, "Unable to read data from autoresponse file");
       
   114   response resp(response::ok, contents);
       
   115   resp.write(fd);
       
   116   RETURN(ok, "Retrieved autoresponse file");
       
   117 }
       
   118 
       
   119 response autoresponse_delete(const mystring& directory)
       
   120 {
       
   121   if(!is_dir(directory.c_str()))
       
   122     RETURN(err, "Autoresponse directory does not exist.");
       
   123   if(!delete_directory(directory))
       
   124     RETURN(err, "Could not delete autoresponse directory.");
       
   125   RETURN(ok, "Autoresponse directory deleted.");
       
   126 }
       
   127 
       
   128 response autoresponse_status(const mystring& directory,
       
   129 			     const mystring& location,
       
   130 			     const mystring& disabled)
       
   131 {
       
   132   const char* msg;
       
   133   if(is_exist(location.c_str()))
       
   134     msg = "enabled";
       
   135   else if(is_exist(disabled.c_str()))
       
   136     msg = "disabled";
       
   137   else if(is_dir(directory.c_str()))
       
   138     msg = "missing message file";
       
   139   else
       
   140     msg = "nonexistant";
       
   141   RETURN(ok, msg);
       
   142 }
       
   143 
       
   144 CMD_FD(autoresponse)
       
   145   // Usage: autoresponse baseuser-virtuser pass action [autorespmessage]
       
   146 {
       
   147 
       
   148   mystring user = args[0];
       
   149   mystring pass = args[1];
       
   150   args[1] = LOG_PASSWORD;
       
   151   mystring action = args[2];
       
   152   mystring message;
       
   153   if(args.count() == 4) {
       
   154     message = args[3];
       
   155     args[3] = LOG_MESSAGE;
       
   156   }
       
   157   logcommand(args);
       
   158 
       
   159   pwentry* pw;
       
   160   vpwentry* vpw;
       
   161   OK_RESPONSE(lookup_and_validate(user, pw, vpw, pass, true, true));
       
   162 
       
   163   const mystring directory = vpw->mailbox + "/" + config->autoresponse_dir();
       
   164   const mystring filename = directory + "/" + config->autoresponse_file();
       
   165   const mystring disabled = filename + ".disabled";
       
   166   
       
   167   if(action == "disable")
       
   168     return autoresponse_disable(filename, disabled);
       
   169   else if(action == "enable")
       
   170     return autoresponse_enable(filename, disabled);
       
   171   else if(action == "read")
       
   172     return autoresponse_read(filename, disabled, fd);
       
   173   else if(action == "write")
       
   174     if(!message)
       
   175       RETURN(bad, "Missing autoresponse message argument");
       
   176     else
       
   177       return autoresponse_write(directory, filename, disabled, message);
       
   178   else if(action == "delete")
       
   179     return autoresponse_delete(directory);
       
   180   else if(action == "status")
       
   181     return autoresponse_status(directory, filename, disabled);
       
   182   
       
   183   RETURN(err, "Unrecognized command");
       
   184 }