diff -r 000000000000 -r 6f7a81934006 daemon/autoresponse.cc --- /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 , +// Bruce Guenter +// +// 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 +#include +#include +#include +#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"); +}