/*
Copyright (C) 2003 Aaron Stone
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: sievecmd.c 2137 2006-05-26 19:49:52Z aaron $
* This is dbmail-sievecmd, which provides
* a command line interface to the sievescripts */
#include "dbmail.h"
#define PNAME "dbmail/sievecmd"
char *configFile = DEFAULT_CONFIG_FILE;
int verbose;
int quiet;
int reallyquiet;
/* set up database login data */
extern db_param_t _db_params;
int main(int argc, char *argv[])
{
int res = 0, opt = 0, opt_prev = 0, act = 0;
u64_t user_idnr = 0;
char *user_name = NULL;
char *script_name = NULL;
char *script_source = NULL;
extern char *optarg;
extern int opterr;
openlog(PNAME, LOG_PID, LOG_MAIL);
setvbuf(stdout, 0, _IONBF, 0);
/* get options */
opterr = 0; /* suppress error message from getopt() */
while ((opt = getopt(argc, argv,
"-a:d:i:c::r:u:l" /* Major modes */
/*"i"*/ "f:qnyvVh" /* Common options */ )) != -1) {
/* The initial "-" of optstring allows unaccompanied
* options and reports them as the optarg to opt 1 (not '1') */
if (opt == 1)
opt = opt_prev;
opt_prev = opt;
switch (opt) {
case -1:
/* Break right away if this is the end of the args */
break;
case 'a':
case 'd':
case 'i':
case 'r':
if (act != 0 && opt != opt_prev)
act = 'h';
else
act = opt;
if (!script_name) {
script_name = dm_strdup(optarg);
} else if (!script_source) {
script_source = dm_strdup(optarg);
}
break;
case 'c':
if (optarg)
script_name = dm_strdup(optarg);
act = opt;
break;
case 'u':
user_name = dm_strdup(optarg);
break;
case 'l':
if (act != 0)
act = 'h';
else
act = opt;
break;
/* Common options */
/*case 'i': FIXME: this is from user.c, but we're using -i for insertion.
printf("Interactive console is not supported in this release.\n");
return 1;*/
case 'f':
if (optarg && strlen(optarg) > 0)
configFile = optarg;
else {
qerrorf("dbmail-users: -f requires a filename\n\n");
return 1;
}
break;
case 'h':
act = 'h';
break;
case 'n':
printf("-n switch is not supported in this "
"version.\n");
return 1;
case 'y':
printf("-y switch is not supported in this "
"version.\n");
return 1;
case 'q':
/* If we get q twice, be really quiet! */
if (quiet)
reallyquiet = 1;
if (!verbose)
quiet = 1;
break;
case 'v':
if (!quiet)
verbose = 1;
break;
case 'V':
/* Show the version and return non-zero. */
printf("\n*** DBMAIL: dbmail-sievecmd version "
"$Revision: 2137 $ %s\n\n", COPYRIGHT);
return 0;
break;
default:
act = 'h';
break;
}
}
if (act == 'h' || act == 0 || !user_name) {
do_showhelp();
goto mainend;
}
qprintf("*** dbmail-sievecmd ***\n");
/* read the config file */
if (config_read(configFile) == -1) {
qerrorf("Failed. Unable to read config file %s\n",
configFile);
res = -1;
goto mainend;
}
SetTraceLevel("DBMAIL");
GetDBParams(&_db_params);
/* Open database connection */
qprintf("Opening connection to database...\n");
if (db_connect() != 0) {
qerrorf("Failed. Could not connect to database (check log)\n");
dm_free(user_name);
return -1;
}
/* Open authentication connection */
qprintf("Opening connection to authentication...\n");
if (auth_connect() != 0) {
qerrorf("Failed. Could not connect to authentication (check log)\n");
dm_free(user_name);
return -1;
}
qprintf("Ok. Connected!\n");
/* Retrieve the user ID number */
switch (auth_user_exists(user_name, &user_idnr)) {
case 0:
qerrorf("User [%s] does not exist!\n", user_name);
res = -1;
goto mainend;
break;
case -1:
qerrorf("Error retrieving User ID Number\n");
res = -1;
goto mainend;
}
switch (act) {
case 'a':
res = do_activate(user_idnr, script_name);
break;
case 'd':
res = do_deactivate(user_idnr, script_name);
break;
case 'i':
res = do_insert(user_idnr, script_name, script_source);
break;
case 'c':
res = do_cat(user_idnr, script_name);
break;
case 'r':
res = do_remove(user_idnr, script_name);
break;
case 'l':
res = do_list(user_idnr);
break;
case 'h':
default:
res = do_showhelp();
break;
}
mainend:
dm_free(user_name);
dm_free(script_name);
dm_free(script_source);
db_disconnect();
auth_disconnect();
config_free();
return res;
}
int do_activate(u64_t user_idnr, char *name)
{
int res = 0;
res = db_activate_sievescript(user_idnr, name);
if (res == -3) {
qerrorf("Script [%s] does not exist.\n", name);
return -1;
} else if (res != 0) {
qerrorf("Error activating script [%s].\n"
"It is possible that no script is currently active!\n",
name);
return -1;
}
qprintf("Script [%s] is now active. All others are inactive.\n",
name);
return 0;
}
int do_deactivate(u64_t user_idnr, char *name)
{
int res = 0;
res = db_deactivate_sievescript(user_idnr, name);
if (res == -3) {
qerrorf("Script [%s] does not exist.\n", name);
return -1;
} else if (res != 0) {
qerrorf("Error deactivating script [%s].\n", name);
return -1;
}
qprintf("Script [%s] is now deactivated."
" No scripts are currently active.\n",
name);
return 0;
}
int do_cat(u64_t user_idnr, char *name)
{
int res = 0;
char *buf = NULL;
char *scriptname = NULL;
if (name)
scriptname = name;
else
res = db_get_sievescript_active(user_idnr, &scriptname);
if (res != 0) {
qerrorf("Database error when fetching active script!\n");
return -1;
}
if (scriptname == NULL) {
qerrorf("No active script found!\n");
return -1;
}
res = db_get_sievescript_byname(user_idnr, scriptname, &buf);
if (res != 0) {
qerrorf("Database error when fetching script!\n");
return -1;
}
if (buf == NULL) {
qerrorf("Script not found!\n");
return -1;
}
printf("%s", buf);
dm_free(buf);
if (!name)
dm_free(scriptname);
return 0;
}
int do_insert(u64_t user_idnr, char *name, char *source)
{
int res = 0;
char *buf = NULL;
FILE *file = NULL;
sort_result_t *sort_result;
if (!source)
file = stdin;
else if (strcmp(source, "-") == 0)
file = stdin;
else
file = fopen(source, "r");
if (!file) {
qerrorf("Could not open file [%s]: %s\n",
optarg, strerror(errno));
return -1;
}
/* Read the file into a char array */
res = read_script_file(file, &buf);
if (res != 0) {
qerrorf("Error reading in your script!\n");
return -1;
}
/* Check if the script is valid */
res = db_add_sievescript(user_idnr, "@!temp-script!@", buf);
dm_free(buf);
if (res != 0) {
qerrorf("Error inserting temporary script into the database!\n");
return -1;
}
sort_result = sort_validate(user_idnr, "@!temp-script!@");
if (sort_result == NULL) {
qprintf("Script could not be validated.\n");
db_delete_sievescript(user_idnr, "@!temp-script!@");
return -1;
}
if (sort_get_error(sort_result) != 0) {
qprintf("Script [%s] has errors: %s.\n",
name, sort_get_errormsg(sort_result));
db_delete_sievescript(user_idnr, "@!temp-script!@");
sort_free_result(sort_result);
return -1;
}
sort_free_result(sort_result);
res = db_rename_sievescript(user_idnr, "@!temp-script!@", name);
if (res == -3) {
qprintf("Script [%s] already exists.\n", name);
db_delete_sievescript(user_idnr, "@!temp-script!@");
return -1;
} else if (res != 0) {
qerrorf("Error inserting script [%s] into the database!\n",
name);
db_delete_sievescript(user_idnr, "@!temp-script!@");
return -1;
}
qprintf("Script [%s] successfully inserted and marked inactive!\n",
name);
return 0;
}
int do_remove(u64_t user_idnr, char *name)
{
int res;
res = db_delete_sievescript(user_idnr, name);
if (res == -3) {
qerrorf("Script [%s] does not exist.\n", name);
return -1;
} else if (res != 0) {
qerrorf("Error deleting script [%s].\n", name);
return -1;
}
qprintf("Script [%s] deleted.\n", name);
return 0;
}
int do_list(u64_t user_idnr)
{
struct dm_list scriptlist;
struct element *tmp;
if (db_get_sievescript_listall(user_idnr, &scriptlist) < 0) {
qerrorf("Error retrieving Sieve script list.\n");
return -1;
}
if (dm_list_length(&scriptlist) > 0) {
qprintf("Found %ld scripts:\n",
dm_list_length(&scriptlist));
} else
qprintf("No scripts found!\n");
tmp = dm_list_getstart(&scriptlist);
while (tmp) {
sievescript_info_t *info = (sievescript_info_t *) tmp->data;
if (info->active == 1)
qprintf(" + ");
else
qprintf(" - ");
qprintf("%s\n", info->name);
dm_free(info->name);
tmp = tmp->nextnode;
}
if (scriptlist.start)
dm_list_free(&scriptlist.start);
return 0;
}
int do_showhelp(void)
{
printf("*** dbmail-sievecmd ***\n");
printf("Use this program to manage your users' Sieve scripts.\n");
printf("See the man page for more info. Summary:\n\n");
printf(" -u username Username of script user \n");
printf(" -l List scripts belonging to user \n");
printf(" -a scriptname Activate the named script \n");
printf(" (only one script can be active; \n"
" deactivates any others) \n");
printf(" -d scriptname Deactivate the named script \n");
printf(" (no scripts will be active after this) \n");
printf(" -i scriptname file Insert the named script from file \n");
printf(" (a single dash, -, indicates input \n"
" from STDIN) \n");
printf(" -c [scriptname] Print the contents of the named script\n");
printf(" (if no script is given, the active \n"
" script is printed) \n");
printf(" -r scriptname Remove the named script \n");
printf(" (if script was active, no script is \n"
" active after deletion) \n");
return 0;
}
int read_script_file(FILE * f, char **m_buf)
{
size_t f_len = 1024;
size_t f_pos = 0;
char *f_buf = NULL;
if (!f) {
printf("Received NULL as script input\n");
return -1;
}
/* Allocate the initial input buffer. */
f_buf = dm_malloc(sizeof(char) * f_len);
if (f_buf == NULL)
return -2;
while (!feof(f)) {
if (f_pos + 1 >= f_len) {
f_buf =
dm_realloc(f_buf, sizeof(char) * (f_len *= 2));
if (f_buf == NULL)
return -2;
}
f_buf[f_pos] = fgetc(f);
f_pos++;
}
if (f_pos)
f_buf[f_pos] = '\0';
*m_buf = f_buf;
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1