1/* Auxiliary functions for interfacing with SpamAssassin
2   Copyright (C) 2008-2021 Sergey Poznyakoff
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17module 'sa'.
18
19const SA_SYMBOLS    0
20const SA_REPORT     1
21const SA_LEARN_SPAM 2
22const SA_LEARN_HAM  3
23const SA_FORGET     4
24
25#pragma regex push +extended
26
27static func __sa_format_score0(string code, number prec)
28  returns string
29do
30  number len length(code)
31  if len > prec
32    return substring(code, 0, len - prec-1) . '.' .
33           substring(code, len - prec, -1)
34  else
35    return "0." . replstr("0", prec - len) . code
36  fi
37done
38
39/* Format CODE as a floating-point number with PREC decimal digits, i.e.:
40
41      printf("%0.*f", prec, code/pow(10,prec))
42
43   in C equivalent.
44*/
45func sa_format_score(number code, number prec)
46  returns string
47do
48  if code < 0
49    return "-" . __sa_format_score0(- code, prec)
50  else
51    return __sa_format_score0(code, prec)
52  fi
53done
54
55/* Reformat SpamAssassin report text in order to include it in a
56   RFC 822 header:
57
58     1. Remove the preamble and epilogue parts.
59     2. Prefix each description line with a "* "
60*/
61func sa_format_report_header(string text)
62  returns string
63do
64  number start index(text, "pts rule name")
65  if start == -1
66    return text
67  fi
68  set start index(text, "\n", start + 1)
69  if start == -1
70    return text
71  fi
72  set start index(text, "\n", start + 1)
73  if start == -1
74    return text
75  fi
76
77  string ret ""
78  number len length(text)
79  loop for number i start + 1,
80       while i < len
81  do
82    if substr(text, i) matches '^ *-?[0-9]\.[0-9]'
83      set pfx "* "
84    else
85      set pfx "  "
86    fi
87    number n index(text, "\n", i)
88    if n >= 0
89      set ret ret . pfx . substring(text, i, n)
90      set i n + 1
91    else
92      set ret ret . pfx . substr(text, i)
93      break
94    fi
95  done
96  return ret
97done
98
99func sa(string urlstr, number prec; number flag)
100  returns number
101do
102  number command
103  if defined(flag)
104    set command flag
105  else
106    set command SA_SYMBOLS
107  fi
108  return spamc(current_message(), urlstr, prec, command)
109done
110
111#pragma regex pop
112