--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/daemon/autoresponse.cc Wed Jan 16 22:39:43 2008 +0100
@@ -0,0 +1,184 @@
+// Copyright (C) 2000 Mike Bell <mike@mikebell.org>,
+// Bruce Guenter <bruceg@em.ca>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include <config.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include "daemon.h"
+#include "config/configrc.h"
+#include "misc/response.h"
+#include "misc/lookup.h"
+#include "misc/maildir.h"
+#include "misc/pwentry_table.h"
+#include "misc/stat_fns.h"
+
+response autoresponse_write(const mystring& directory,
+ const mystring& location,
+ const mystring& disabled,
+ const mystring& msg)
+{
+ mystring tmpfile = location + ".lock";
+
+ if(!is_dir(directory.c_str())) {
+ if(mkdir(directory.c_str(), 0755))
+ RETURN(err, "Could not create autoresponse directory");
+ }
+
+ if(is_exist(tmpfile.c_str()))
+ RETURN(err, "Temporary autoresponse file already exists");
+
+ if(is_exist(disabled.c_str()))
+ RETURN(err, "Autoresponse is disabled, reenable it before writing a new message");
+
+ fdobuf out(tmpfile.c_str(), fdobuf::create | fdobuf::excl, 0644);
+ if(!out)
+ RETURN(err, "Unable to open temporary autoresponse file for writing");
+
+ out << msg;
+ if(!out.flush() || !out.close()) {
+ unlink(tmpfile.c_str());
+ RETURN(err, "Unable to write message to file");
+ }
+ if(rename(tmpfile.c_str(), location.c_str())) {
+ unlink(tmpfile.c_str());
+ RETURN(err, "Unable to rename temporary autoresponse file");
+ }
+
+ RETURN(ok, "Message successfully written to autoresponse file");
+}
+
+response autoresponse_disable(const mystring& location,
+ const mystring& disabled)
+{
+ if(!is_exist(location.c_str()))
+ RETURN(ok, "Autoresponse file did not exist");
+ if(is_exist(disabled.c_str()))
+ RETURN(err, "Disabled autoresponse file already exists");
+ if(rename(location.c_str(), disabled.c_str()))
+ RETURN(err, "Unable to rename autoresponse file");
+ RETURN(ok, "Autoresponse file sucessfully disabled");
+}
+
+response autoresponse_enable(const mystring& location,
+ const mystring& disabled)
+{
+ if(is_exist(location.c_str()))
+ RETURN(ok, "Autoresponse is already enabled");
+ if(!is_exist(disabled.c_str()))
+ RETURN(err, "Disabled autoresponse file did not exist");
+ if(rename(disabled.c_str(), location.c_str()))
+ RETURN(err, "Unable to rename previously disabled autoresponse file");
+ RETURN(ok, "Autoresponse file sucessfully restored");
+}
+
+static bool read_file(const mystring& filename, mystring& out)
+{
+ fdibuf in(filename.c_str());
+ if(!in)
+ return false;
+ char contents[65536];
+ unsigned contentlen;
+ in.read(contents, 65536);
+ contentlen = in.last_count();
+ out = mystring(contents, contentlen);
+ return true;
+}
+
+response autoresponse_read(const mystring& location,
+ const mystring& disabled, int fd)
+{
+ mystring line;
+ if(!is_exist(location.c_str()) &&
+ !is_exist(disabled.c_str()))
+ RETURN(err, "Autoresponder file does not exist");
+
+ mystring contents;
+ if(!read_file(location, contents) &&
+ !read_file(disabled, contents))
+ RETURN(err, "Unable to read data from autoresponse file");
+ response resp(response::ok, contents);
+ resp.write(fd);
+ RETURN(ok, "Retrieved autoresponse file");
+}
+
+response autoresponse_delete(const mystring& directory)
+{
+ if(!is_dir(directory.c_str()))
+ RETURN(err, "Autoresponse directory does not exist.");
+ if(!delete_directory(directory))
+ RETURN(err, "Could not delete autoresponse directory.");
+ RETURN(ok, "Autoresponse directory deleted.");
+}
+
+response autoresponse_status(const mystring& directory,
+ const mystring& location,
+ const mystring& disabled)
+{
+ const char* msg;
+ if(is_exist(location.c_str()))
+ msg = "enabled";
+ else if(is_exist(disabled.c_str()))
+ msg = "disabled";
+ else if(is_dir(directory.c_str()))
+ msg = "missing message file";
+ else
+ msg = "nonexistant";
+ RETURN(ok, msg);
+}
+
+CMD_FD(autoresponse)
+ // Usage: autoresponse baseuser-virtuser pass action [autorespmessage]
+{
+
+ mystring user = args[0];
+ mystring pass = args[1];
+ args[1] = LOG_PASSWORD;
+ mystring action = args[2];
+ mystring message;
+ if(args.count() == 4) {
+ message = args[3];
+ args[3] = LOG_MESSAGE;
+ }
+ logcommand(args);
+
+ pwentry* pw;
+ vpwentry* vpw;
+ OK_RESPONSE(lookup_and_validate(user, pw, vpw, pass, true, true));
+
+ const mystring directory = vpw->mailbox + "/" + config->autoresponse_dir();
+ const mystring filename = directory + "/" + config->autoresponse_file();
+ const mystring disabled = filename + ".disabled";
+
+ if(action == "disable")
+ return autoresponse_disable(filename, disabled);
+ else if(action == "enable")
+ return autoresponse_enable(filename, disabled);
+ else if(action == "read")
+ return autoresponse_read(filename, disabled, fd);
+ else if(action == "write")
+ if(!message)
+ RETURN(bad, "Missing autoresponse message argument");
+ else
+ return autoresponse_write(directory, filename, disabled, message);
+ else if(action == "delete")
+ return autoresponse_delete(directory);
+ else if(action == "status")
+ return autoresponse_status(directory, filename, disabled);
+
+ RETURN(err, "Unrecognized command");
+}