View | Details | Raw Unified | Return to bug 1201
Collapse All | Expand All

(-)spamassassin-trunk-new/spamc/libspamc.h (-3 / +10 lines)
Lines 73-78 Link Here
73
73
74
#define EX_NOTSPAM		  0
74
#define EX_NOTSPAM		  0
75
#define EX_ISSPAM		  1
75
#define EX_ISSPAM		  1
76
#define EX_LEARNED		  5
77
#define EX_NOTLEARNED	  6
76
#define EX_TOOBIG		866
78
#define EX_TOOBIG		866
77
79
78
/* Aug 14, 2002 bj: Bitflags instead of lots of bool parameters */
80
/* Aug 14, 2002 bj: Bitflags instead of lots of bool parameters */
Lines 97-102 Link Here
97
/* log to stderr */
99
/* log to stderr */
98
#define SPAMC_LOG_TO_STDERR  (1<<22)
100
#define SPAMC_LOG_TO_STDERR  (1<<22)
99
101
102
/* Nov 24, 2004 NP: added learning support */
103
#define SPAMC_LEARN			 (1<<21)
104
100
/* Aug 14, 2002 bj: A struct for storing a message-in-progress */
105
/* Aug 14, 2002 bj: A struct for storing a message-in-progress */
101
typedef enum
106
typedef enum
102
{
107
{
Lines 136-141 Link Here
136
    int out_len;		/* Output from spamd. Either the filtered
141
    int out_len;		/* Output from spamd. Either the filtered
137
				   message, or the check-only response. Or else,
142
				   message, or the check-only response. Or else,
138
				   a pointer to msg above. */
143
				   a pointer to msg above. */
144
	int is_learned;	/* Output from spamd. Gives state
145
						about learn resp. unlearn process */
139
146
140
    /* these members added in SpamAssassin version 2.60: */
147
    /* these members added in SpamAssassin version 2.60: */
141
    struct libspamc_private_message *priv;
148
    struct libspamc_private_message *priv;
Lines 205-211 Link Here
205
 * failover, more than one host is defined, but if there is only one there,
212
 * failover, more than one host is defined, but if there is only one there,
206
 * no failover is done.
213
 * no failover is done.
207
 */
214
 */
208
int message_filter(struct transport *tp, const char *username,
215
int message_filter(struct transport *tp, const char *username, int learntype,
209
		   int flags, struct message *m);
216
		   int flags, struct message *m);
210
217
211
/* Dump the message. If there is any data in the message (typically, m->type
218
/* Dump the message. If there is any data in the message (typically, m->type
Lines 217-223 Link Here
217
/* Do a message_read->message_filter->message_write sequence, handling errors
224
/* Do a message_read->message_filter->message_write sequence, handling errors
218
 * appropriately with dump_message or appropriate CHECK_ONLY output. Returns
225
 * appropriately with dump_message or appropriate CHECK_ONLY output. Returns
219
 * EX_OK or EX_ISSPAM/EX_NOTSPAM on success, some error EX on error. */
226
 * EX_OK or EX_ISSPAM/EX_NOTSPAM on success, some error EX on error. */
220
int message_process(struct transport *trans, char *username, int max_size,
227
int message_process(struct transport *trans, char *username, int learntype, int max_size,
221
		    int in_fd, int out_fd, const int flags);
228
		    int in_fd, int out_fd, const int flags);
222
229
223
/* Cleanup the resources we allocated for storing the message. Call after
230
/* Cleanup the resources we allocated for storing the message. Call after
Lines 225-231 Link Here
225
void message_cleanup(struct message *m);
232
void message_cleanup(struct message *m);
226
233
227
/* Aug 14, 2002 bj: This is now legacy, don't use it. */
234
/* Aug 14, 2002 bj: This is now legacy, don't use it. */
228
int process_message(struct transport *tp, char *username,
235
int process_message(struct transport *tp, char *username, int learntype,
229
		    int max_size, int in_fd, int out_fd,
236
		    int max_size, int in_fd, int out_fd,
230
		    const int check_only, const int safe_fallback);
237
		    const int check_only, const int safe_fallback);
231
238
(-)spamassassin-trunk-new/spamc/spamc.c (-22 / +90 lines)
Lines 140-146 Link Here
140
        "                      [default: 250k]\n");
140
        "                      [default: 250k]\n");
141
    usg("  -u username         User for spamd to process this message under.\n"
141
    usg("  -u username         User for spamd to process this message under.\n"
142
        "                      [default: current user]\n");
142
        "                      [default: current user]\n");
143
    
143
144
    usg("  -L learntype        Message gets learned as spam (0),\n"
145
 		"                      or learned as ham (1), or forgotten (2)\n");
146
	
144
    usg("  -B                  Assume input is a single BSMTP-formatted\n"
147
    usg("  -B                  Assume input is a single BSMTP-formatted\n"
145
        "                      message.\n");
148
        "                      message.\n");
146
    
149
    
Lines 173-185 Link Here
173
 */
176
 */
174
int
177
int
175
read_args(int argc, char **argv,
178
read_args(int argc, char **argv,
176
          int *max_size, char **username,
179
          int *max_size, char **username, int *learntype,
177
          struct transport *ptrn)
180
          struct transport *ptrn)
178
{
181
{
179
#ifndef _WIN32
182
#ifndef _WIN32
180
    const char *opts = "-BcrRd:e:fyp:t:s:u:xSHU:ElhV";
183
    const char *opts = "-BcrRd:e:fyp:t:s:u:L:xSHU:ElhV";
181
#else
184
#else
182
    const char *opts = "-BcrRd:fyp:t:s:u:xSHElhV";
185
    const char *opts = "-BcrRd:fyp:t:s:u:L:xSHElhV";
183
#endif
186
#endif
184
    int opt;
187
    int opt;
185
    int ret = EX_OK;
188
    int ret = EX_OK;
Lines 280-285 Link Here
280
                *username = optarg;
283
                *username = optarg;
281
                break;
284
                break;
282
            }
285
            }
286
            case 'L':
287
			{
288
				flags |= SPAMC_LEARN;
289
				*learntype = atoi(optarg);
290
				if(*learntype >= 3)
291
				{
292
					libspamc_log(flags, LOG_ERR, "Please specifiy a legal learn type");
293
					ret = EX_USAGE;
294
				}
295
				break;
296
			}
283
#ifndef _WIN32
297
#ifndef _WIN32
284
            case 'U':
298
            case 'U':
285
            {
299
            {
Lines 320-326 Link Here
320
            }
334
            }
321
        }
335
        }
322
    }
336
    }
323
    
337
338
	// learning action has to block some parameters //
339
	if (flags & SPAMC_LEARN)
340
	{
341
		if (flags & SPAMC_CHECK_ONLY)
342
		{
343
			libspamc_log(flags, LOG_ERR, "Learning excludes check only");
344
			ret = EX_USAGE;
345
		}
346
		if (flags & SPAMC_REPORT_IFSPAM)
347
		{
348
			libspamc_log(flags, LOG_ERR, "Learning excludes report if spam");
349
			ret = EX_USAGE;
350
		}
351
		if (flags & SPAMC_REPORT)
352
		{
353
			libspamc_log(flags, LOG_ERR, "Learning excludes report");
354
			ret = EX_USAGE;
355
		}
356
		if (flags & SPAMC_SYMBOLS)
357
		{
358
   			libspamc_log(flags, LOG_ERR, "Learning excludes symbols");
359
			ret = EX_USAGE;
360
		}
361
	}
324
    return ret;
362
    return ret;
325
}
363
}
326
364
Lines 460-465 Link Here
460
    int out_fd = -1;
498
    int out_fd = -1;
461
    int result;
499
    int result;
462
    int ret;
500
    int ret;
501
	int learntype = 0;
463
502
464
    transport_init(&trans);
503
    transport_init(&trans);
465
504
Lines 476-487 Link Here
476
   /* Now parse the command line arguments. First, set the defaults. */
515
   /* Now parse the command line arguments. First, set the defaults. */
477
   max_size = 250 * 1024;
516
   max_size = 250 * 1024;
478
   username = NULL;
517
   username = NULL;
479
   if ((ret = read_args(argc, argv, &max_size, &username, &trans)) != EX_OK) {
518
   if ((ret = read_args(argc, argv, &max_size, &username, &learntype, &trans)) != EX_OK) {
480
       if (ret == EX_TEMPFAIL )
519
       if (ret == EX_TEMPFAIL )
481
           ret = EX_OK;
520
           ret = EX_OK;
482
       goto finish;
521
       goto finish;
483
   }
522
   }
484
   
523
485
   ret = get_current_user(&username);
524
   ret = get_current_user(&username);
486
   if (ret != EX_OK)
525
   if (ret != EX_OK)
487
       goto finish;
526
       goto finish;
Lines 513-542 Link Here
513
#endif
552
#endif
514
    ret = transport_setup(&trans, flags);
553
    ret = transport_setup(&trans, flags);
515
    if (ret == EX_OK) {
554
    if (ret == EX_OK) {
516
	
555
517
	ret = message_read(STDIN_FILENO, flags, &m);
556
	ret = message_read(STDIN_FILENO, flags, &m);
518
	
557
	
519
	if (ret == EX_OK) {
558
	if (ret == EX_OK) {
520
	    
559
	    
521
	    ret = message_filter(&trans, username, flags, &m);
560
	    ret = message_filter(&trans, username, learntype, flags, &m);
522
	    free(username); username = NULL;
561
562
		free(username); username = NULL;
523
	    
563
	    
524
	    if (ret == EX_OK) {
564
	    if (ret == EX_OK) {
525
		get_output_fd(&out_fd);
565
		get_output_fd(&out_fd);
526
566
527
		if (message_write(out_fd, &m) >= 0) {
567
			if (flags & SPAMC_LEARN)
568
	 		{
569
 
570
 				if (m.is_learned == 1)
571
 				{
572
 
573
					printf( "Message successfully un/learned\n" );
574
					ret = EX_LEARNED;
575
 
576
 				}
577
 				else
578
 				{
528
579
529
		    result = m.is_spam;
580
					printf( "Message was already un/learned\n" );
530
                    if ((flags & SPAMC_CHECK_ONLY) && result != EX_TOOBIG) {
581
 					ret = EX_NOTLEARNED;
531
			message_cleanup(&m);
582
532
			ret = result;
583
 				}
533
		    }
584
 				message_cleanup(&m);
534
		    else {
585
 
535
			message_cleanup(&m);
586
 				goto finish;
536
                        if (use_exit_code && result != EX_TOOBIG) {
587
 
588
 
589
 			}
590
			else if (message_write(out_fd, &m) >= 0) {
591
592
				result = m.is_spam;
593
                if ((flags & SPAMC_CHECK_ONLY) && result != EX_TOOBIG) {
594
					message_cleanup(&m);
595
					ret = result;
596
				}
597
				else {
598
					message_cleanup(&m);
599
                    if (use_exit_code && result != EX_TOOBIG) {
537
                            ret = result;
600
                            ret = result;
538
                        }
601
               }
539
		    }
602
			}
540
		    goto finish;
603
		    goto finish;
541
		}
604
		}
542
	    }
605
	    }
Lines 559-565 Link Here
559
	message_cleanup(&m);
622
	message_cleanup(&m);
560
	ret = EX_NOTSPAM;
623
	ret = EX_NOTSPAM;
561
    }
624
    }
562
    else {
625
    else if (flags & SPAMC_LEARN )
626
 	{
627
 		message_cleanup(&m);
628
 		ret = EX_UNAVAILABLE;
629
 	}
630
 	else {
563
	message_dump(STDIN_FILENO, out_fd, &m);
631
	message_dump(STDIN_FILENO, out_fd, &m);
564
	message_cleanup(&m);
632
	message_cleanup(&m);
565
	if (ret == EX_TOOBIG) {
633
	if (ret == EX_TOOBIG) {
(-)spamassassin-trunk-new/spamc/libspamc.c (-10 / +76 lines)
Lines 764-769 Link Here
764
{
764
{
765
    char is_spam[6];
765
    char is_spam[6];
766
    char s_str[21], t_str[21];
766
    char s_str[21], t_str[21];
767
	char is_learned[4];
767
768
768
    UNUSED_VARIABLE(len);
769
    UNUSED_VARIABLE(len);
769
770
Lines 810-821 Link Here
810
	}
811
	}
811
	return EX_OK;
812
	return EX_OK;
812
    }
813
    }
814
	else if (sscanf(buf, "Learned: %3s", is_learned) == 1)
815
	{
816
		if(strcmp(is_learned,"yes")==0||strcmp(is_learned,"Yes")==0)
817
		{
818
			m->is_learned = 1;
819
		}
820
		else if(strcmp(is_learned,"no")==0||strcmp(is_learned,"No")==0)
821
		{
822
			m->is_learned = 0;
823
		}
824
		else
825
		{
826
			libspamc_log(flags, LOG_ERR, "spamd responded with bad Learned-state '%s'",
827
		   buf);
828
			return EX_PROTOCOL;
829
		}
830
		return EX_OK;
831
	}
813
832
814
    libspamc_log(flags, LOG_ERR, "spamd responded with bad header '%s'", buf);
833
    libspamc_log(flags, LOG_ERR, "spamd responded with bad header '%s'", buf);
815
    return EX_PROTOCOL;
834
    return EX_PROTOCOL;
816
}
835
}
817
836
818
int message_filter(struct transport *tp, const char *username,
837
int message_filter(struct transport *tp, const char *username, int learntype,
819
		   int flags, struct message *m)
838
		   int flags, struct message *m)
820
{
839
{
821
    char buf[8192];
840
    char buf[8192];
Lines 824-829 Link Here
824
    int sock = -1;
843
    int sock = -1;
825
    int rc;
844
    int rc;
826
    char versbuf[20];
845
    char versbuf[20];
846
	char strlearntype[1];
827
    float version;
847
    float version;
828
    int response;
848
    int response;
829
    int failureval;
849
    int failureval;
Lines 854-862 Link Here
854
    m->out = m->outbuf;
874
    m->out = m->outbuf;
855
    m->out_len = 0;
875
    m->out_len = 0;
856
876
877
    /* Build spamd protocol header */
857
878
858
    /* Build spamd protocol header */
879
	if(flags & SPAMC_CHECK_ONLY)
859
    if (flags & SPAMC_CHECK_ONLY)
860
	strcpy(buf, "CHECK ");
880
	strcpy(buf, "CHECK ");
861
    else if (flags & SPAMC_REPORT_IFSPAM)
881
    else if (flags & SPAMC_REPORT_IFSPAM)
862
	strcpy(buf, "REPORT_IFSPAM ");
882
	strcpy(buf, "REPORT_IFSPAM ");
Lines 864-870 Link Here
864
	strcpy(buf, "REPORT ");
884
	strcpy(buf, "REPORT ");
865
    else if (flags & SPAMC_SYMBOLS)
885
    else if (flags & SPAMC_SYMBOLS)
866
	strcpy(buf, "SYMBOLS ");
886
	strcpy(buf, "SYMBOLS ");
867
    else
887
    else if (flags & SPAMC_LEARN )
888
	{
889
		strcpy(buf, "LEARN ");
890
		len = strlen(buf);
891
	}
892
	else
868
	strcpy(buf, "PROCESS ");
893
	strcpy(buf, "PROCESS ");
869
894
870
    len = strlen(buf);
895
    len = strlen(buf);
Lines 877-882 Link Here
877
    strcat(buf, "\r\n");
902
    strcat(buf, "\r\n");
878
    len = strlen(buf);
903
    len = strlen(buf);
879
904
905
906
	if (flags & SPAMC_LEARN)
907
	{
908
		if ((learntype > 2) | (learntype < 0 ))
909
		{
910
		    free(m->out);
911
		    m->out = m->msg;
912
			m->out_len = m->msg_len;
913
			return EX_OSERR;
914
		}
915
		sprintf(strlearntype,"%d",learntype);
916
		strcpy(buf + len, "Learn-type: ");
917
		strcat(buf + len, strlearntype);
918
		strcat(buf + len, "\r\n");
919
		len += strlen(buf + len);
920
	}
921
880
    if (username != NULL) {
922
    if (username != NULL) {
881
	if (strlen(username) + 8 >= (bufsiz - len)) {
923
	if (strlen(username) + 8 >= (bufsiz - len)) {
882
	    _use_msg_for_out(m);
924
	    _use_msg_for_out(m);
Lines 951-956 Link Here
951
    m->score = 0;
993
    m->score = 0;
952
    m->threshold = 0;
994
    m->threshold = 0;
953
    m->is_spam = EX_TOOBIG;
995
    m->is_spam = EX_TOOBIG;
996
	m->is_learned = 0;
954
    while (1) {
997
    while (1) {
955
	failureval =
998
	failureval =
956
	    _spamc_read_full_line(m, flags, ssl, sock, buf, &len, bufsiz);
999
	    _spamc_read_full_line(m, flags, ssl, sock, buf, &len, bufsiz);
Lines 963-969 Link Here
963
	}
1006
	}
964
1007
965
	if (_handle_spamd_header(m, flags, buf, len) < 0) {
1008
	if (_handle_spamd_header(m, flags, buf, len) < 0) {
966
	    failureval = EX_PROTOCOL;
1009
		failureval = EX_PROTOCOL;
967
	    goto failure;
1010
	    goto failure;
968
	}
1011
	}
969
    }
1012
    }
Lines 980-989 Link Here
980
	}
1023
	}
981
	return EX_OK;
1024
	return EX_OK;
982
    }
1025
    }
1026
	else if (flags & SPAMC_LEARN)
1027
	{
1028
		shutdown(sock, SHUT_RD);
1029
		closesocket(sock);
1030
		sock = -1;
1031
		return EX_OK;
1032
	}
983
    else {
1033
    else {
984
	if (m->content_length < 0) {
1034
	if (m->content_length < 0) {
985
	    /* should have got a length too. */
1035
	    /* should have got a length too. */
986
	    failureval = EX_PROTOCOL;
1036
1037
		failureval = EX_PROTOCOL;
987
	    goto failure;
1038
	    goto failure;
988
	}
1039
	}
989
1040
Lines 1049-1055 Link Here
1049
}
1100
}
1050
1101
1051
1102
1052
int message_process(struct transport *trans, char *username, int max_size,
1103
int message_process(struct transport *trans, char *username, int learntype, int max_size,
1053
		    int in_fd, int out_fd, const int flags)
1104
		    int in_fd, int out_fd, const int flags)
1054
{
1105
{
1055
    int ret;
1106
    int ret;
Lines 1061-1067 Link Here
1061
    ret = message_read(in_fd, flags, &m);
1112
    ret = message_read(in_fd, flags, &m);
1062
    if (ret != EX_OK)
1113
    if (ret != EX_OK)
1063
	goto FAIL;
1114
	goto FAIL;
1064
    ret = message_filter(trans, username, flags, &m);
1115
    ret = message_filter(trans, username, learntype, flags, &m);
1065
    if (ret != EX_OK)
1116
    if (ret != EX_OK)
1066
	goto FAIL;
1117
	goto FAIL;
1067
    if (message_write(out_fd, &m) < 0)
1118
    if (message_write(out_fd, &m) < 0)
Lines 1086-1091 Link Here
1086
    }
1137
    }
1087
}
1138
}
1088
1139
1140
1089
void message_cleanup(struct message *m)
1141
void message_cleanup(struct message *m)
1090
{
1142
{
1091
    if (m->outbuf)
1143
    if (m->outbuf)
Lines 1098-1104 Link Here
1098
}
1150
}
1099
1151
1100
/* Aug 14, 2002 bj: Obsolete! */
1152
/* Aug 14, 2002 bj: Obsolete! */
1101
int process_message(struct transport *tp, char *username, int max_size,
1153
int process_message(struct transport *tp, char *username, int learntype, int max_size,
1102
		    int in_fd, int out_fd, const int my_check_only,
1154
		    int in_fd, int out_fd, const int my_check_only,
1103
		    const int my_safe_fallback)
1155
		    const int my_safe_fallback)
1104
{
1156
{
Lines 1110-1116 Link Here
1110
    if (my_safe_fallback)
1162
    if (my_safe_fallback)
1111
	flags |= SPAMC_SAFE_FALLBACK;
1163
	flags |= SPAMC_SAFE_FALLBACK;
1112
1164
1113
    return message_process(tp, username, max_size, in_fd, out_fd, flags);
1165
    return message_process(tp, username, learntype, max_size, in_fd, out_fd, flags);
1114
}
1166
}
1115
1167
1116
/*
1168
/*
Lines 1390-1393 Link Here
1390
    exit(0);
1442
    exit(0);
1391
}
1443
}
1392
1444
1445
1446
1447
1393
#endif /* LIBSPAMC_UNIT_TESTS */
1448
#endif /* LIBSPAMC_UNIT_TESTS */
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459

Return to bug 1201