Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

flt_postingassistant.c

00001 /*
00002  * \file flt_postingassistant.c
00003  * \author Christian Kruse, <cjk@wwwtech.de>
00004  * \brief Posting assistant
00005  *
00006  * This file is a plugin for fo_post. It tries to make
00007  * the user do smart postings.
00008  *
00009  */
00010 
00011 /* {{{ Initial comments */
00012 /*
00013  * $LastChangedDate$
00014  * $LastChangedRevision$
00015  * $LastChangedBy$
00016  *
00017  */
00018 /* }}} */
00019 
00020 /* {{{ Includes */
00021 #include "config.h"
00022 #include "defines.h"
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <ctype.h>
00027 #include <string.h>
00028 #include <sys/types.h>
00029 
00030 #include <time.h>
00031 
00032 #include "readline.h"
00033 #include "hashlib.h"
00034 #include "utils.h"
00035 #include "configparser.h"
00036 #include "cfcgi.h"
00037 #include "template.h"
00038 #include "clientlib.h"
00039 #include "fo_post.h"
00040 /* }}} */
00041 
00042 struct {
00043   int poas_must_validate;
00044   u_char **bws;
00045   long bws_len;
00046   int bws_allowed;
00047   float fds_allowed;
00048   int qp;
00049   int qp_must_validate;
00050 } flt_poas_conf = { 0, NULL, 0, 3, 5.0, 25, 0 };
00051 
00052 int last_chars_consist_of(u_char *str,u_char *signs,size_t backnum,int all) {
00053   register u_char *ptr,*sign;
00054   size_t matched;
00055   u_char *lsigns = strdup(signs);
00056 
00057   for(ptr=str;ptr != str-backnum;ptr--) {
00058     for(matched=0,sign=signs;*sign;sign++) {
00059       if(*ptr == *sign) {
00060         matched = 1;
00061         break;
00062       }
00063     }
00064 
00065     if(matched == 0) {
00066       free(lsigns);
00067       return -1;
00068     }
00069 
00070     lsigns[sign-signs] = '\0';
00071   }
00072 
00073   if(all) {
00074     for(matched=0;matched<strlen(signs);matched++) {
00075       if(lsigns[matched] != '\0') {
00076         free(lsigns);
00077         return -1;
00078       }
00079     }
00080   }
00081 
00082   free(lsigns);
00083   return 0;
00084 }
00085 
00086 float flt_poas_check_for_signs(u_char *str,int strict,int musthave) {
00087   register u_char *ptr;
00088   int signs;
00089   int gotsigns = 0;
00090 
00091   for(signs = 0,ptr=str;*ptr;ptr++) {
00092     switch(*ptr) {
00093       case '.':
00094       case '!':
00095       case '?':
00096       case ':':
00097       case ';':
00098       case ',':
00099         signs++;
00100         gotsigns = 1;
00101         break;
00102       default:
00103        if(signs >= 2) {
00104           /* we *never* accept more than three signs */
00105           if(signs > 3) return 3.0;
00106 
00107           switch(strict) {
00108             case 0:
00109             case 1:
00110               /* we accept ... and .. */
00111               if(cf_strncmp(ptr-signs,"...",signs)) break;
00112 
00113               /* we accept ?!?, !?! ?! and !? (in both cases) */
00114               if(last_chars_consist_of(ptr,"?!",signs,1) == 0) break;
00115 
00116               /* we do not accept everything else in strict mode 1 */
00117               if(strict == 1) return 2.0;
00118               break;
00119 
00120             case 2:
00121               return 2.0;
00122               break;
00123           }
00124         }
00125 
00126         signs = 0;
00127     }
00128   }
00129 
00130   if(musthave && gotsigns == 0) return 3.0;
00131 
00132   return .0;
00133 }
00134 
00135 int flt_poas_check_for_cases(u_char *str) {
00136   register u_char *ptr;
00137   int has_big = 0,has_small,big_after = 0;
00138 
00139   for(ptr=str;*ptr;ptr++) {
00140     if(isupper(*ptr)) {
00141       has_big++;
00142       big_after++;
00143     }
00144     else if(islower(*ptr)) {
00145       has_small++;
00146       big_after = 0;
00147     }
00148     else big_after = 0;
00149 
00150     if(big_after > 4) return has_small ? 2.0 : 3.0;
00151   }
00152 
00153   if(!has_small) return 3.0;
00154   if(!has_big)   return 1.0;
00155 
00156   return .0;
00157 }
00158 
00159 int flt_poas_check_newlines(u_char *str) {
00160   register u_char *ptr;
00161   int nl;
00162 
00163   for(ptr=str,nl=0;*ptr;ptr++) {
00164     if(*ptr == '<') {
00165       if(cf_strncmp(ptr,"<br />",6) == 0) {
00166         nl++;
00167       }
00168     }
00169   }
00170 
00171   if(nl <= 2) return 3.0;
00172 
00173   return .0;
00174 }
00175 
00176 int flt_poas_standardchecks(t_message *p) {
00177   float score = flt_poas_conf.fds_allowed;
00178 
00179   score -= flt_poas_check_for_signs(p->subject,0,0);
00180   score -= flt_poas_check_for_signs(p->author,2,0);
00181   score -= flt_poas_check_for_signs(p->content,1,1);
00182 
00183   score -= flt_poas_check_for_cases(p->subject);
00184   score -= flt_poas_check_for_cases(p->author);
00185   score -= flt_poas_check_for_cases(p->content);
00186 
00187   score -= flt_poas_check_newlines(p->content);
00188 
00189   return score >= .0 ? 0 : -1;
00190 }
00191 
00192 int flt_poas_execute(t_cf_hash *head,t_configuration *dc,t_configuration *pc,t_message *p,int sock,int mode) {
00193   /* first: standard checks */
00194   if(cf_cgi_get(head,"assicheck") == NULL || flt_poas_conf.poas_must_validate) {
00195     if(flt_poas_standardchecks(p) != 0) {
00196       cf_cgi_set(head,"assicheck","1");
00197       strcpy(ErrorString,"E_posting_format");
00198       display_posting_form(head);
00199       return FLT_EXIT;
00200     }
00201 
00202     return FLT_OK;
00203   }
00204 
00205   return FLT_DECLINE;
00206 }
00207 
00208 int flt_poas_handle(t_configfile *cfile,t_conf_opt *opt,u_char **args,int argnum) {
00209   switch(*opt->name) {
00210     case 'P':
00211       flt_poas_conf.poas_must_validate = cf_strcmp(args[0],"yes") == 0;
00212       break;
00213     case 'F':
00214       flt_poas_conf.fds_allowed = atof(args[0]);
00215       break;
00216     case 'B':
00217       if(cf_strcmp(opt->name,"BadWords") == 0) flt_poas_conf.bws_len = split(args[0],",",&flt_poas_conf.bws);
00218       else flt_poas_conf.bws_allowed = atoi(args[0]);
00219       break;
00220     case 'Q':
00221       if(cf_strcmp(args[0],"QuotingPercent") == 0) flt_poas_conf.qp = atoi(args[0]);
00222       else flt_poas_conf.qp_must_validate = cf_strcmp(args[0],"yes") == 0;
00223       break;
00224 
00225     default:
00226       return 1;
00227   }
00228 
00229   return 0;
00230 }
00231 
00232 void flt_poas_finish(void) {
00233 }
00234 
00235 t_conf_opt flt_poas_config[] = {
00236   { "PostingAssistantMustValidate", flt_poas_handle, NULL },
00237   { "BadWords",                     flt_poas_handle, NULL },
00238   { "BadwordsAllowed",              flt_poas_handle, NULL },
00239   { "FormateDeficitesAllowed",      flt_poas_handle, NULL },
00240   { "QuotingPercent",               flt_poas_handle, NULL },
00241   { "QuoteMustValidate",            flt_poas_handle, NULL },
00242   { NULL, NULL, NULL }
00243 };
00244 
00245 t_handler_config flt_poas_handlers[] = {
00246   { NEW_POST_HANDLER, flt_poas_execute },
00247   { 0, NULL }
00248 };
00249 
00250 t_module_config flt_poas = {
00251   flt_poas_config,
00252   flt_poas_handlers,
00253   NULL,
00254   NULL,
00255   NULL,
00256   flt_poas_finish
00257 };
00258 
00259 /* eof */

Generated on Sun Apr 25 16:37:39 2004 for Classic Forum by doxygen 1.3.5