#include "config.h"#include "version.h"#include "libspamc.h"#include "utils.h"#include "spamc.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include "getopt.h"#include <syslog.h>#include <unistd.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <arpa/inet.h>Go to the source code of this file.
Functions | |
| void | check_malloc (void *ptr) |
| void | print_version (void) |
| static void | usg (char *str) |
| void | print_usage (void) |
| int | read_args (int argc, char **argv, int *max_size, char **username, int *extratype, struct transport *ptrn) |
| int | combine_args (char *config_file, int argc, char **argv, int *combo_argc, char **combo_argv) |
| void | get_output_fd (int *fd) |
| int | get_current_user (char **username) |
| int | main (int argc, char *argv[]) |
Variables | |
| int | flags = SPAMC_RAW_MODE | SPAMC_SAFE_FALLBACK |
| int | use_exit_code = 0 |
| char ** | exec_argv |
| static int | timeout = 600 |
|
|
Definition at line 105 of file spamc.c. References EX_OSERR, flags, libspamc_log(), and LOG_ERR. Referenced by combine_args(), and main(). 00106 { 00107 if(ptr == NULL) { 00108 libspamc_log(flags, LOG_ERR, 00109 "Error allocating memory using malloc\n"); 00110 /* this is really quite serious. we can't do anything. die */ 00111 exit(EX_OSERR); 00112 } 00113 }
|
|
||||||||||||||||||||||||
|
Definition at line 521 of file spamc.c. References check_malloc(), EX_CONFIG, and EX_OK. Referenced by main(). 00523 { 00524 FILE *config; 00525 char option[100]; 00526 int i, count = 0; 00527 char *tok = NULL; 00528 int is_user_defined_p = 1; 00529 00530 if (config_file == NULL) { 00531 config_file = CONFIG_FILE; 00532 is_user_defined_p = 0; 00533 } 00534 00535 if((config = fopen(config_file, "r")) == NULL) { 00536 if (is_user_defined_p == 1) { /* if the config file was user defined we should issue an error */ 00537 fprintf(stderr,"Failed to open config file: %s\n", config_file); 00538 } 00539 return EX_CONFIG; 00540 } 00541 00542 while(!(feof(config)) && (fgets(option, 100, config))) { 00543 00544 count++; /* increment the line counter */ 00545 00546 if(option[0] == '#' || option[0] == '\n') { 00547 continue; 00548 } 00549 00550 tok = option; 00551 while((tok = strtok(tok, " ")) != NULL) { 00552 if(tok[0] == '\n') 00553 break; 00554 for(i=strlen(tok); i>0; i--) { 00555 if(tok[i] == '\n') 00556 tok[i] = '\0'; 00557 } 00558 combo_argv[*combo_argc] = strdup(tok); 00559 check_malloc(combo_argv[*combo_argc]); 00560 /* TODO: leaked. not a big deal since spamc exits quickly */ 00561 tok = NULL; 00562 *combo_argc+=1; 00563 } 00564 } 00565 00566 fclose(config); 00567 00568 /* note: not starting at 0, that's the command name */ 00569 for(i=1; i<argc; i++) { 00570 combo_argv[*combo_argc] = strdup(argv[i]); 00571 check_malloc(combo_argv[*combo_argc]); 00572 /* TODO: leaked. not a big deal since spamc exits quickly */ 00573 *combo_argc+=1; 00574 } 00575 return EX_OK; 00576 }
|
|
|
Determines the username of the uid spamc is running under. If the program's caller didn't identify the user to run as, use the current user for this. Note that we're not talking about UNIX perm- issions, but giving SpamAssassin a username so it can do per-user configuration (whitelists & the like). Allocates memory for the username, returns EX_OK if successful. Definition at line 653 of file spamc.c. References EX_NOTSPAM, EX_OK, EX_OSERR, flags, and SPAMC_CHECK_ONLY. Referenced by main(). 00654 { 00655 #ifndef _WIN32 00656 struct passwd *curr_user; 00657 #endif 00658 00659 if (*username != NULL) { 00660 *username = strdup(*username); 00661 if (username == NULL) 00662 goto fail; 00663 goto pass; 00664 } 00665 00666 #ifndef _WIN32 00667 00668 /* Get the passwd information for the effective uid spamc is running 00669 * under. Setting errno to zero is recommended in the manpage. 00670 */ 00671 errno = 0; 00672 curr_user = getpwuid(geteuid()); 00673 if (curr_user == NULL) { 00674 perror("getpwuid() failed"); 00675 goto fail; 00676 } 00677 00678 /* Since "curr_user" points to static library data, we don't wish to 00679 * risk some other part of the system overwriting it, so we copy the 00680 * username to our own buffer -- then this won't arise as a problem. 00681 */ 00682 *username = strdup(curr_user->pw_name); 00683 if (*username == NULL) { 00684 goto fail; 00685 } 00686 00687 #endif 00688 00689 pass: 00690 return EX_OK; 00691 00692 fail: 00693 /* FIXME: The handling of SPAMC_CHECK_ONLY should probably be moved to 00694 * the end of main() 00695 */ 00696 if (flags & SPAMC_CHECK_ONLY) { 00697 printf("0/0\n"); 00698 return EX_NOTSPAM; 00699 } 00700 return EX_OSERR; 00701 }
|
|
|
Definition at line 579 of file spamc.c. References EX_OSERR, exec_argv, flags, libspamc_log(), LOG_CRIT, LOG_ERR, STDIN_FILENO, and STDOUT_FILENO. Referenced by main(). 00580 { 00581 #ifndef _WIN32 00582 int pipe_fds[2]; 00583 pid_t pid; 00584 #endif 00585 00586 if (*fd != -1) 00587 return; 00588 00589 /* If we aren't told to feed our output to an external app, we simply 00590 * write to stdout. 00591 */ 00592 if (exec_argv == NULL) { 00593 *fd = STDOUT_FILENO; 00594 return; 00595 } 00596 00597 #ifndef _WIN32 00598 /* Create a pipe for communication between child and parent. */ 00599 if (pipe(pipe_fds)) { 00600 libspamc_log(flags, LOG_ERR, "pipe creation failed: %m"); 00601 exit(EX_OSERR); 00602 } 00603 00604 pid = fork(); 00605 if (pid < 0) { 00606 libspamc_log(flags, LOG_ERR, "fork failed: %m"); 00607 exit(EX_OSERR); 00608 } 00609 else if (pid == 0) { 00610 /* This is the child process: 00611 * Normally you'd expect the parent process here, however that would 00612 * screw up an invoker waiting on the death of the parent. So instead, 00613 * we fork a child to feed the data and have the parent exec the new 00614 * program. 00615 */ 00616 close(pipe_fds[0]); 00617 *fd = pipe_fds[1]; 00618 return; 00619 } 00620 00621 /* This is the parent process (see above) */ 00622 close(pipe_fds[1]); 00623 if (dup2(pipe_fds[0], STDIN_FILENO)) { 00624 libspamc_log(flags, LOG_ERR, "redirection of stdin failed: %m"); 00625 exit(EX_OSERR); 00626 } 00627 /* No point in leaving extra fds lying around. */ 00628 close(pipe_fds[0]); 00629 00630 /* Now execute the command specified. */ 00631 execv(exec_argv[0], exec_argv); 00632 00633 /* Whoa, something failed... */ 00634 libspamc_log(flags, LOG_ERR, "exec failed: %m"); 00635 #else 00636 libspamc_log(flags, LOG_CRIT, "THIS MUST NOT HAPPEN AS -e IS NOT SUPPORTED UNDER WINDOWS."); 00637 #endif 00638 exit(EX_OSERR); 00639 }
|
|
||||||||||||
|
Definition at line 705 of file spamc.c. References check_malloc(), combine_args(), EX_NOHOST, EX_OK, EX_SOFTWARE, EX_TEMPFAIL, EX_TOOBIG, flags, full_write(), get_current_user(), get_output_fd(), message::is_spam, message::max_len, message_cleanup(), message_dump(), message_filter(), MESSAGE_NONE, message_read(), message_tell(), message_write(), message::out, message::outbuf, message::priv, message::raw, read_args(), SPAMC_CHECK_ONLY, SPAMC_LEARN, SPAMC_MESSAGE_CLASS_HAM, SPAMC_MESSAGE_CLASS_SPAM, SPAMC_PING, SPAMC_RANDOMIZE_HOSTS, SPAMC_REMOVE_LOCAL, SPAMC_REMOVE_REMOTE, SPAMC_REPORT, SPAMC_REPORT_IFSPAM, SPAMC_REPORT_MSG, SPAMC_SAFE_FALLBACK, SPAMC_SET_LOCAL, SPAMC_SET_REMOTE, SPAMC_SYMBOLS, STDIN_FILENO, STDOUT_FILENO, timeout, message::timeout, transport_init(), transport_setup(), message::type, and use_exit_code. 00706 { 00707 int max_size; 00708 char *username; 00709 struct transport trans; 00710 struct message m; 00711 int out_fd = -1; 00712 int result = EX_SOFTWARE; 00713 int ret = EX_SOFTWARE; 00714 int extratype = 0; 00715 int islearned = 0; 00716 int isreported = 0; 00717 00718 /* these are to hold CLI and config options combined, to be passed 00719 * to read_args() */ 00720 char *combo_argv[24]; 00721 int combo_argc; 00722 00723 int i; 00724 char *config_file = NULL; 00725 00726 transport_init(&trans); 00727 00728 #ifdef LIBSPAMC_UNIT_TESTS 00729 /* unit test support; divert execution. will not return */ 00730 do_libspamc_unit_tests(); 00731 #endif 00732 00733 #ifndef _WIN32 00734 openlog("spamc", LOG_CONS | LOG_PID, LOG_MAIL); 00735 signal(SIGPIPE, SIG_IGN); 00736 #endif 00737 00738 /* set some defaults */ 00739 max_size = 500 * 1024; 00740 username = NULL; 00741 00742 combo_argc = 1; 00743 combo_argv[0] = strdup(argv[0]); 00744 check_malloc(combo_argv[0]); 00745 /* TODO: leaked. not a big deal since spamc exits quickly */ 00746 00747 for(i=0; i<argc; i++) { 00748 if(strncmp(argv[i], "-F", 2) == 0) { 00749 config_file = argv[i+1]; 00750 break; 00751 } 00752 } 00753 00754 if((combine_args(config_file, argc, argv, &combo_argc, combo_argv)) == EX_OK) 00755 { 00756 /* Parse the combined arguments of command line and config file */ 00757 if ((ret = read_args(combo_argc, combo_argv, &max_size, &username, 00758 &extratype, &trans)) != EX_OK) 00759 { 00760 if (ret == EX_TEMPFAIL) 00761 ret = EX_OK; 00762 goto finish; 00763 } 00764 } 00765 else { 00766 /* parse only command line arguments (default behaviour) */ 00767 if((ret = read_args(argc, argv, &max_size, &username, 00768 &extratype, &trans)) != EX_OK) 00769 { 00770 if(ret == EX_TEMPFAIL) 00771 ret = EX_OK; 00772 goto finish; 00773 } 00774 } 00775 00776 ret = get_current_user(&username); 00777 if (ret != EX_OK) 00778 goto finish; 00779 00780 if ((flags & SPAMC_RANDOMIZE_HOSTS) != 0) { 00781 /* we don't need strong randomness; this is just so we pick 00782 * a random host for loadbalancing. 00783 */ 00784 srand(getpid() ^ time(NULL)); 00785 } 00786 00787 /********************************************************************** 00788 * SET UP TRANSPORT 00789 * 00790 * This takes the user parameters and digs up what it can about how 00791 * we connect to the spam daemon. Mainly this involves lookup up the 00792 * hostname and getting the IP addresses to connect to. 00793 */ 00794 m.type = MESSAGE_NONE; 00795 m.out = NULL; 00796 m.outbuf = NULL; 00797 m.raw = NULL; 00798 m.priv = NULL; 00799 m.max_len = max_size; 00800 m.timeout = timeout; 00801 m.is_spam = EX_NOHOST; /* default err code if can't reach the daemon */ 00802 #ifdef _WIN32 00803 setmode(STDIN_FILENO, O_BINARY); 00804 setmode(STDOUT_FILENO, O_BINARY); 00805 #endif 00806 ret = transport_setup(&trans, flags); 00807 00808 if (ret == EX_OK) { 00809 00810 ret = message_read(STDIN_FILENO, flags, &m); 00811 00812 if (ret == EX_OK) { 00813 00814 if (flags & SPAMC_LEARN) { 00815 int msg_class = 0; 00816 unsigned int tellflags = 0; 00817 unsigned int didtellflags = 0; 00818 00819 if ((extratype == 0) || (extratype == 1)) { 00820 if (extratype == 0) { 00821 msg_class = SPAMC_MESSAGE_CLASS_SPAM; 00822 } 00823 else { 00824 msg_class = SPAMC_MESSAGE_CLASS_HAM; 00825 } 00826 tellflags |= SPAMC_SET_LOCAL; 00827 } 00828 else { 00829 tellflags |= SPAMC_REMOVE_LOCAL; 00830 } 00831 00832 ret = message_tell(&trans, username, flags, &m, msg_class, 00833 tellflags, &didtellflags); 00834 00835 if (ret == EX_OK) { 00836 if ((extratype == 0) || (extratype == 1)) { 00837 if (didtellflags & SPAMC_SET_LOCAL) { 00838 islearned = 1; 00839 } 00840 } 00841 else { 00842 if (didtellflags & SPAMC_REMOVE_LOCAL) { 00843 islearned = 1; 00844 } 00845 } 00846 } 00847 } 00848 else if (flags & SPAMC_REPORT_MSG) { 00849 int msg_class = 0; 00850 unsigned int tellflags = 0; 00851 unsigned int didtellflags = 0; 00852 00853 if (extratype == 0) { 00854 msg_class = SPAMC_MESSAGE_CLASS_SPAM; 00855 tellflags |= SPAMC_SET_REMOTE; 00856 tellflags |= SPAMC_SET_LOCAL; 00857 } 00858 else { 00859 msg_class = SPAMC_MESSAGE_CLASS_HAM; 00860 tellflags |= SPAMC_SET_LOCAL; 00861 tellflags |= SPAMC_REMOVE_REMOTE; 00862 } 00863 00864 ret = message_tell(&trans, username, flags, &m, msg_class, 00865 tellflags, &didtellflags); 00866 00867 if (ret == EX_OK) { 00868 if (extratype == 0) { 00869 if (didtellflags & SPAMC_SET_REMOTE) { 00870 isreported = 1; 00871 } 00872 } 00873 else { 00874 if (didtellflags & SPAMC_REMOVE_REMOTE) { 00875 isreported = 1; 00876 } 00877 } 00878 } 00879 } 00880 else { 00881 ret = message_filter(&trans, username, flags, &m); 00882 } 00883 00884 free(username); username = NULL; 00885 00886 if (ret == EX_OK) { 00887 00888 get_output_fd(&out_fd); 00889 00890 if (flags & SPAMC_LEARN) { 00891 if (islearned == 1) { 00892 printf("Message successfully un/learned\n"); 00893 } 00894 else { 00895 printf("Message was already un/learned\n"); 00896 } 00897 message_cleanup(&m); 00898 goto finish; 00899 } 00900 else if (flags & SPAMC_REPORT_MSG) { 00901 if (isreported == 1) { 00902 printf("Message successfully reported/revoked\n"); 00903 } 00904 else { 00905 printf("Unable to report/revoke message\n"); 00906 } 00907 message_cleanup(&m); 00908 goto finish; 00909 } 00910 else if (message_write(out_fd, &m) >= 0) { 00911 result = m.is_spam; 00912 if ((flags & SPAMC_CHECK_ONLY) && result != EX_TOOBIG) { 00913 message_cleanup(&m); 00914 ret = result; 00915 } 00916 else { 00917 message_cleanup(&m); 00918 if (use_exit_code && result != EX_TOOBIG) { 00919 ret = result; 00920 } 00921 } 00922 goto finish; 00923 } 00924 } 00925 } 00926 } 00927 free(username); 00928 00929 /* FAIL: */ 00930 #if 1 00931 result = m.is_spam; 00932 if (ret != EX_OK) { 00933 result = ret; 00934 } 00935 #endif 00936 if (flags & (SPAMC_LEARN|SPAMC_PING) ) { 00937 get_output_fd(&out_fd); 00938 message_cleanup(&m); 00939 } 00940 else { 00941 if (flags & (SPAMC_CHECK_ONLY | SPAMC_REPORT | SPAMC_REPORT_IFSPAM)) { 00942 get_output_fd(&out_fd); 00943 full_write(out_fd, 1, "0/0\n", 4); 00944 } 00945 else if (flags & SPAMC_SYMBOLS) { 00946 /* bug 4991: -y should only output a blank line on connection failure */ 00947 get_output_fd(&out_fd); 00948 full_write(out_fd, 1, "\n", 1); 00949 } 00950 else { 00951 /* bug 5412: spamc -x should not output the message on error */ 00952 if ((flags & SPAMC_SAFE_FALLBACK) || result == EX_TOOBIG) { 00953 get_output_fd(&out_fd); 00954 message_dump(STDIN_FILENO, out_fd, &m); 00955 } 00956 /* else, do NOT get_output_fd() (bug 5478) */ 00957 } 00958 00959 message_cleanup(&m); 00960 if (ret == EX_TOOBIG) { 00961 ret = EX_OK; /* too big always means exit(0) -- bug 5412 */ 00962 } 00963 else if (flags & SPAMC_SAFE_FALLBACK) { 00964 ret = EX_OK; 00965 } 00966 else if (use_exit_code) { 00967 ret = result; 00968 } 00969 } 00970 00971 finish: 00972 #ifdef _WIN32 00973 WSACleanup(); 00974 #endif 00975 return ret; 00976 }
|
|
|
Definition at line 131 of file spamc.c. References print_version(), and usg(). Referenced by read_args(). 00132 { 00133 print_version(); 00134 usg("\n"); 00135 usg("Usage: spamc [options] [-e command [args]] < message\n"); 00136 usg("\n"); 00137 usg("Options:\n"); 00138 00139 usg(" -d, --dest host[,host2]\n" 00140 " Specify one or more hosts to connect to.\n" 00141 " [default: localhost]\n"); 00142 usg(" -H , --randomize Randomize IP addresses for the looked-up\n" 00143 " hostname.\n"); 00144 usg(" -p, --port port Specify port for connection to spamd.\n" 00145 " [default: 783]\n"); 00146 #ifdef SPAMC_SSL 00147 usg(" -S, --ssl Use SSL to talk to spamd.\n"); 00148 #endif 00149 #ifndef _WIN32 00150 usg(" -U, --socket path Connect to spamd via UNIX domain sockets.\n"); 00151 #endif 00152 usg(" -F, --config path Use this configuration file.\n"); 00153 usg(" -t, --timeout timeout\n" 00154 " Timeout in seconds for communications to\n" 00155 " spamd. [default: 600]\n"); 00156 usg(" --connect-retries retries\n" 00157 " Try connecting to spamd this many times\n" 00158 " [default: 3]\n"); 00159 usg(" --retry-sleep sleep Sleep for this time between attempts to\n" 00160 " connect to spamd, in seconds [default: 1]\n"); 00161 usg(" -s, --max-size size Specify maximum message size, in bytes.\n" 00162 " [default: 500k]\n"); 00163 usg(" -u, --username username\n" 00164 " User for spamd to process this message under.\n" 00165 " [default: current user]\n"); 00166 00167 usg(" -L, --learntype learntype\n" 00168 " Learn message as spam, ham or forget to\n" 00169 " forget or unlearn the message.\n"); 00170 00171 usg(" -C, --reporttype reporttype\n" 00172 " Report message to collaborative filtering\n" 00173 " databases. Report type should be 'report' for\n" 00174 " spam or 'revoke' for ham.\n"); 00175 00176 usg(" -B, --bsmtp Assume input is a single BSMTP-formatted\n" 00177 " message.\n"); 00178 00179 usg(" -c, --check Just print the summary line and set an exit\n" 00180 " code.\n"); 00181 usg(" -y, --tests Just print the names of the tests hit.\n"); 00182 usg(" -r, --full-spam Print full report for messages identified as\n" 00183 " spam.\n"); 00184 usg(" -R, --full Print full report for all messages.\n"); 00185 usg(" --headers Rewrite only the message headers.\n"); 00186 usg(" -E, --exitcode Filter as normal, and set an exit code.\n"); 00187 00188 usg(" -x, --no-safe-fallback\n" 00189 " Don't fallback safely.\n"); 00190 usg(" -l, --log-to-stderr Log errors and warnings to stderr.\n"); 00191 #ifndef _WIN32 00192 usg(" -e, --pipe-to command [args]\n" 00193 " Pipe the output to the given command instead\n" 00194 " of stdout. This must be the last option.\n"); 00195 #endif 00196 usg(" -h, --help Print this help message and exit.\n"); 00197 usg(" -V, --version Print spamc version and exit.\n"); 00198 usg(" -K Keepalive check of spamd.\n"); 00199 #ifdef HAVE_ZLIB_H 00200 usg(" -z Compress mail message sent to spamd.\n"); 00201 #endif 00202 usg(" -f (Now default, ignored.)\n"); 00203 00204 usg("\n"); 00205 }
|
|
|
Definition at line 116 of file spamc.c. Referenced by print_usage(), and read_args(). 00117 { 00118 printf("%s version %s\n", "SpamAssassin Client", VERSION_STRING); 00119 #ifdef SPAMC_SSL 00120 printf(" compiled with SSL support (%s)\n", OPENSSL_VERSION_TEXT); 00121 #endif 00122 }
|
|
||||||||||||||||||||||||||||
|
Does the command line parsing for argv[]. Returns EX_OK or EX_TEMPFAIL if successful. EX_TEMPFAIL is a kludge for the cases where we want in main to return immediately; we can't exit() because on Windows WSACleanup() needs to be called. Definition at line 215 of file spamc.c. References transport::connect_retries, EX_OK, EX_OSERR, EX_TEMPFAIL, EX_USAGE, exec_argv, flags, transport::hostname, libspamc_log(), LOG_ERR, no_argument, optional_argument, transport::port, print_usage(), print_version(), required_argument, transport::retry_sleep, transport::socketpath, SPAMC_BSMTP_MODE, SPAMC_CHECK_ONLY, spamc_getopt_long(), SPAMC_HEADERS, SPAMC_LEARN, SPAMC_LOG_TO_STDERR, SPAMC_MAX_MESSAGE_LEN, SPAMC_MODE_MASK, spamc_optarg, spamc_optind, SPAMC_PING, SPAMC_RANDOMIZE_HOSTS, SPAMC_REPORT, SPAMC_REPORT_IFSPAM, SPAMC_REPORT_MSG, SPAMC_SAFE_FALLBACK, SPAMC_SSLV2, SPAMC_SSLV3, SPAMC_SYMBOLS, SPAMC_USE_SSL, SPAMC_USE_ZLIB, timeout, TRANSPORT_TCP, TRANSPORT_UNIX, transport::type, and use_exit_code. Referenced by main(). 00218 { 00219 #ifndef _WIN32 00220 const char *opts = "-BcrRd:e:fyp:t:s:u:L:C:xzSHU:ElhVKF:0:1:2"; 00221 #else 00222 const char *opts = "-BcrRd:fyp:t:s:u:L:C:xzSHElhVKF:0:1:2"; 00223 #endif 00224 int opt; 00225 int ret = EX_OK; 00226 int longind = 1; 00227 00228 static struct option longoptions[] = { 00229 { "dest" , required_argument, 0, 'd' }, 00230 { "randomize", no_argument, 0, 'H' }, 00231 { "port", required_argument, 0, 'p' }, 00232 { "ssl", optional_argument, 0, 'S' }, 00233 { "socket", required_argument, 0, 'U' }, 00234 { "config", required_argument, 0, 'F' }, 00235 { "timeout", required_argument, 0, 't' }, 00236 { "connect-retries", required_argument, 0, 0 }, 00237 { "retry-sleep", required_argument, 0, 1 }, 00238 { "max-size", required_argument, 0, 's' }, 00239 { "username", required_argument, 0, 'u' }, 00240 { "learntype", required_argument, 0, 'L' }, 00241 { "reporttype", required_argument, 0, 'C' }, 00242 { "bsmtp", no_argument, 0, 'B' }, 00243 { "check", no_argument, 0, 'c' }, 00244 { "tests", no_argument, 0, 'y' }, 00245 { "full-spam", no_argument, 0, 'r' }, 00246 { "full", no_argument, 0, 'R' }, 00247 { "headers", no_argument, 0, 2 }, 00248 { "exitcode", no_argument, 0, 'E' }, 00249 { "no-safe-fallback", no_argument, 0, 'x' }, 00250 { "log-to-stderr", no_argument, 0, 'l' }, 00251 { "pipe-to", required_argument, 0, 'e' }, 00252 { "help", no_argument, 0, 'h' }, 00253 { "version", no_argument, 0, 'V' }, 00254 { "compress", no_argument, 0, 'z' }, 00255 { 0, 0, 0, 0} /* last element _must_ be all zeroes */ 00256 }; 00257 00258 while ((opt = spamc_getopt_long(argc, argv, opts, longoptions, 00259 &longind)) != -1) 00260 { 00261 switch (opt) 00262 { 00263 case 'B': 00264 { 00265 flags = (flags & ~SPAMC_MODE_MASK) | SPAMC_BSMTP_MODE; 00266 break; 00267 } 00268 case 'c': 00269 { 00270 flags |= SPAMC_CHECK_ONLY; 00271 break; 00272 } 00273 case 'd': 00274 { 00275 ptrn->type = TRANSPORT_TCP; 00276 ptrn->hostname = spamc_optarg; /* fix the ptr to point to this string */ 00277 break; 00278 } 00279 #ifndef _WIN32 00280 case 'e': 00281 { 00282 int i, j; 00283 00284 /* Allocate memory for the necessary pointers needed to 00285 * store the remaining arguments. 00286 */ 00287 exec_argv = malloc(sizeof(*exec_argv) * (argc - spamc_optind + 2)); 00288 if (exec_argv == NULL) { 00289 return EX_OSERR; 00290 } 00291 00292 for (i = 0, j = spamc_optind - 1; j < argc; i++, j++) { 00293 exec_argv[i] = argv[j]; 00294 } 00295 exec_argv[i] = NULL; 00296 00297 return EX_OK; 00298 } 00299 #endif 00300 case 'f': 00301 { 00302 /* obsolete, backwards compat */ 00303 break; 00304 } 00305 case 'K': 00306 { 00307 flags |= SPAMC_PING; 00308 break; 00309 } 00310 case 'l': 00311 { 00312 flags |= SPAMC_LOG_TO_STDERR; 00313 break; 00314 } 00315 case 'H': 00316 { 00317 flags |= SPAMC_RANDOMIZE_HOSTS; 00318 break; 00319 } 00320 case 'p': 00321 { 00322 ptrn->port = (unsigned short)atoi(spamc_optarg); 00323 break; 00324 } 00325 case 'r': 00326 { 00327 flags |= SPAMC_REPORT_IFSPAM; 00328 break; 00329 } 00330 case 'E': 00331 { 00332 use_exit_code = 1; 00333 break; 00334 } 00335 case 'R': 00336 { 00337 flags |= SPAMC_REPORT; 00338 break; 00339 } 00340 case 's': 00341 { 00342 *max_size = atoi(spamc_optarg); 00343 break; 00344 } 00345 #ifdef SPAMC_SSL 00346 case 'S': 00347 { 00348 flags |= SPAMC_USE_SSL; 00349 if (!spamc_optarg || (strcmp(spamc_optarg,"sslv23") == 0)) { 00350 /* this is the default */ 00351 } 00352 else if (strcmp(spamc_optarg,"sslv2") == 0) { 00353 flags |= SPAMC_SSLV2; 00354 } 00355 else if (strcmp(spamc_optarg,"sslv3") == 0) { 00356 flags |= SPAMC_SSLV3; 00357 } 00358 else if (strcmp(spamc_optarg,"tlsv1") == 0) { 00359 flags |= (SPAMC_SSLV2 | SPAMC_SSLV3); 00360 } 00361 else { 00362 libspamc_log(flags, LOG_ERR, "Please specifiy a legal ssl version (%s)", spamc_optarg); 00363 ret = EX_USAGE; 00364 } 00365 break; 00366 } 00367 #endif 00368 case 't': 00369 { 00370 timeout = atoi(spamc_optarg); 00371 break; 00372 } 00373 case 'u': 00374 { 00375 *username = spamc_optarg; 00376 break; 00377 } 00378 case 'L': 00379 { 00380 flags |= SPAMC_LEARN; 00381 if (strcmp(spamc_optarg,"spam") == 0) { 00382 *extratype = 0; 00383 } 00384 else if (strcmp(spamc_optarg,"ham") == 0) { 00385 *extratype = 1; 00386 } 00387 else if (strcmp(spamc_optarg,"forget") == 0) { 00388 *extratype = 2; 00389 } 00390 else { 00391 libspamc_log(flags, LOG_ERR, "Please specifiy a legal learn type"); 00392 ret = EX_USAGE; 00393 } 00394 break; 00395 } 00396 case 'C': 00397 { 00398 flags |= SPAMC_REPORT_MSG; 00399 if (strcmp(spamc_optarg,"report") == 0) { 00400 *extratype = 0; 00401 } 00402 else if (strcmp(spamc_optarg,"revoke") == 0) { 00403 *extratype = 1; 00404 } 00405 else { 00406 libspamc_log(flags, LOG_ERR, "Please specifiy a legal report type"); 00407 ret = EX_USAGE; 00408 } 00409 break; 00410 } 00411 #ifndef _WIN32 00412 case 'U': 00413 { 00414 ptrn->type = TRANSPORT_UNIX; 00415 ptrn->socketpath = spamc_optarg; 00416 break; 00417 } 00418 #endif 00419 case 'x': 00420 { 00421 flags &= (~SPAMC_SAFE_FALLBACK); 00422 break; 00423 } 00424 case 'y': 00425 { 00426 flags |= SPAMC_SYMBOLS; 00427 break; 00428 } 00429 00430 case '?': 00431 case ':': 00432 { 00433 libspamc_log(flags, LOG_ERR, "invalid usage"); 00434 ret = EX_USAGE; 00435 /* FALLTHROUGH */ 00436 } 00437 case 'h': 00438 { 00439 print_usage(); 00440 if (ret == EX_OK) 00441 ret = EX_TEMPFAIL; 00442 return(ret); 00443 } 00444 case 'V': 00445 { 00446 print_version(); 00447 return(EX_TEMPFAIL); 00448 } 00449 case 'z': 00450 { 00451 #ifdef HAVE_ZLIB_H 00452 flags |= SPAMC_USE_ZLIB; 00453 #else 00454 libspamc_log(flags, LOG_ERR, "spamc -z support not available"); 00455 ret = EX_USAGE; 00456 #endif 00457 break; 00458 } 00459 case 0: 00460 { 00461 ptrn->connect_retries = atoi(spamc_optarg); 00462 break; 00463 } 00464 case 1: 00465 { 00466 ptrn->retry_sleep = atoi(spamc_optarg); 00467 break; 00468 } 00469 case 2: 00470 { 00471 flags |= SPAMC_HEADERS; 00472 break; 00473 } 00474 } 00475 } 00476 00477 if (*max_size > SPAMC_MAX_MESSAGE_LEN) { 00478 libspamc_log(flags, LOG_ERR, "-s parameter is beyond max of %d", 00479 SPAMC_MAX_MESSAGE_LEN); 00480 ret = EX_USAGE; 00481 } 00482 00483 /* learning action has to block some parameters */ 00484 if (flags & SPAMC_LEARN) { 00485 if (flags & SPAMC_CHECK_ONLY) { 00486 libspamc_log(flags, LOG_ERR, "Learning excludes check only"); 00487 ret = EX_USAGE; 00488 } 00489 if (flags & SPAMC_PING) { 00490 libspamc_log(flags, LOG_ERR, "Learning excludes ping"); 00491 ret = EX_USAGE; 00492 } 00493 if (flags & SPAMC_REPORT_IFSPAM) { 00494 libspamc_log(flags, LOG_ERR, "Learning excludes report if spam"); 00495 ret = EX_USAGE; 00496 } 00497 if (flags & SPAMC_REPORT) { 00498 libspamc_log(flags, LOG_ERR, "Learning excludes report"); 00499 ret = EX_USAGE; 00500 } 00501 if (flags & SPAMC_SYMBOLS) { 00502 libspamc_log(flags, LOG_ERR, "Learning excludes symbols"); 00503 ret = EX_USAGE; 00504 } 00505 if (flags & SPAMC_REPORT_MSG) { 00506 libspamc_log(flags, LOG_ERR, "Learning excludes reporting to collaborative filtering databases"); 00507 ret = EX_USAGE; 00508 } 00509 } 00510 return ret; 00511 }
|
|
|
Definition at line 125 of file spamc.c. Referenced by print_usage().
|
|
|
Definition at line 99 of file spamc.c. Referenced by get_output_fd(), and read_args(). |
|
|
Definition at line 93 of file spamc.c. Referenced by check_malloc(), get_current_user(), get_output_fd(), main(), process_message(), and read_args(). |
|
|
Definition at line 101 of file spamc.c. Referenced by main(), and read_args(). |
|
|
Definition at line 96 of file spamc.c. Referenced by main(), and read_args(). |