Browse code

General CVS update

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@15 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2003/08/03 07:37:52
Showing 17 changed files
... ...
@@ -1,3 +1,13 @@
1
+Sat Jul 26 17:11:46 CEST 2003
2
+-----------------------------
3
+  * libclamav: updated mbox code (Nigel)
4
+
5
+Thu Jul 24 13:29:39 CEST 2003
6
+-----------------------------
7
+  * libclamav: mbox: fixed detection of the Gibe virus (bug reported
8
+	       by Rene Bellora); support for log file names (problem
9
+	       reported by Tomasz Papszun)
10
+
1 11
 Sun Jul 20 23:43:38 CEST 2003
2 12
 -----------------------------
3 13
   * libclamav: mbox: improved scanning of uuencoded files and other
... ...
@@ -68,7 +68,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for
68 68
 dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created
69 69
 dnl (the prefix is a bit different, since we add an extra -target- and -host-)
70 70
 dnl 
71
-dnl @version: $Id: acinclude.m4,v 1.1 2003/07/29 15:40:20 nervoso Exp $
71
+dnl @version: $Id: acinclude.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $
72 72
 dnl @author Guido Draheim <guidod@gmx.de>                 STATUS: used often
73 73
 
74 74
 AC_DEFUN([AC_CREATE_TARGET_H],
... ...
@@ -4110,7 +4110,7 @@ dnl      AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
4110 4110
 dnl      AC_COMPILE_CHECK_SIZEOF(off_t, $headers)
4111 4111
 dnl
4112 4112
 dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu>
4113
-dnl @version $Id: acinclude.m4,v 1.1 2003/07/29 15:40:20 nervoso Exp $
4113
+dnl @version $Id: acinclude.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $
4114 4114
 dnl
4115 4115
 AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
4116 4116
 [changequote(<<, >>)dnl
... ...
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for
81 81
 dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created
82 82
 dnl (the prefix is a bit different, since we add an extra -target- and -host-)
83 83
 dnl 
84
-dnl @version: $Id: aclocal.m4,v 1.1 2003/07/29 15:37:09 nervoso Exp $
84
+dnl @version: $Id: aclocal.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $
85 85
 dnl @author Guido Draheim <guidod@gmx.de>                 STATUS: used often
86 86
 
87 87
 AC_DEFUN([AC_CREATE_TARGET_H],
... ...
@@ -4041,7 +4041,7 @@ dnl      AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
4041 4041
 dnl      AC_COMPILE_CHECK_SIZEOF(off_t, $headers)
4042 4042
 dnl
4043 4043
 dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu>
4044
-dnl @version $Id: aclocal.m4,v 1.1 2003/07/29 15:37:09 nervoso Exp $
4044
+dnl @version $Id: aclocal.m4,v 1.2 2003/08/02 22:37:52 kojm Exp $
4045 4045
 dnl
4046 4046
 AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
4047 4047
 [changequote(<<, >>)dnl
... ...
@@ -62,6 +62,9 @@ void clamscan(struct optstruct *opt)
62 62
     if(optl(opt, "stdout")) mprintf_stdout = 1;
63 63
     else mprintf_stdout = 0;
64 64
 
65
+    if(optl(opt, "debug"))
66
+	cl_debug();
67
+
65 68
     if(optc(opt, 'V')) {
66 69
 	mprintf("clamscan / ClamAV version "VERSION"\n");
67 70
 	mexit(0);
... ...
@@ -168,11 +171,12 @@ void help(void)
168 168
 
169 169
     mprintf("\n");
170 170
     mprintf("		   Clam AntiVirus Scanner "VERSION"\n");
171
-    mprintf("		   (c) 2002 Tomasz Kojm <zolw@konarski.edu.pl>\n");
171
+    mprintf("	    (c) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>\n");
172 172
     mprintf("	  \n");
173 173
     mprintf("    --help		    -h		Show help\n");
174 174
     mprintf("    --version		    -V		Print version number and exit\n");
175 175
     mprintf("    --verbose		    -v		Be verbose\n");
176
+    mprintf("    --debug				Enable debug messages\n");
176 177
     mprintf("    --quiet				Be quiet, output only error messages\n");
177 178
     mprintf("    --stdout				Write to stdout instead of stderr\n");
178 179
     mprintf("					(this help is always written to stdout)\n");
... ...
@@ -47,6 +47,7 @@ int main(int argc, char **argv)
47 47
 	    {"help", 0, 0, 'h'},
48 48
 	    {"quiet", 0, 0, 0},
49 49
 	    {"verbose", 0, 0, 'v'},
50
+	    {"debug", 0, 0, 0},
50 51
 	    {"version", 0, 0, 'V'},
51 52
 	    {"tempdir", 1, 0, 0},
52 53
 	    {"database", 1, 0, 'd'},
... ...
@@ -1901,7 +1901,7 @@ fi
1901 1901
 
1902 1902
 # Define the identity of the package.
1903 1903
  PACKAGE=clamav
1904
- VERSION=20030720
1904
+ VERSION=cvs
1905 1905
 
1906 1906
 
1907 1907
 cat >>confdefs.h <<_ACEOF
... ...
@@ -19,7 +19,7 @@ AC_INIT(clamscan/clamscan.c)
19 19
 AC_CREATE_TARGET_H(target.h)
20 20
 AC_CANONICAL_SYSTEM
21 21
 
22
-AM_INIT_AUTOMAKE(clamav, 20030720)
22
+AM_INIT_AUTOMAKE(clamav, cvs)
23 23
 dnl AM_INIT_AUTOMAKE(clamav, `date +%Y%m%d`)
24 24
 LC_CURRENT=1
25 25
 LC_REVISION=3
... ...
@@ -1,3 +1,4 @@
1
+Trojan.Download-DK (Clam)=426f644852774f6938764e6a51754d6a51324c6a55324c6a63300d0a4c33356a59584a686232746c4c32747a6343356c6547554162584e6f5a5867755a58686c414752736241417541473176626742310d0a636d7741515142476157786c4146527641455276643235736232466b4146565354
1 2
 Js.Exception.Gen (Clam)=73657454696d656f757428277b73657428293b7d272c31303030293b0a766172204d657373616765203d20224675636b20596f75223b
2 3
 JS.FortNight.M (Clam)=653d4a5363726970742e456e636f64653e23407e5e6d51454141413d3d5b4b6d3b732b0959525344624f2b5e78634a4021716f5d7a48322c
3 4
 JS/Fortnight.B.1 (Clam)=2c416b3959747b547e747f6b54744f27547e55492f2745345944776c264a68684154634532526b557f5920092b3d2646794740243973522131397d7f2a097820265a2a53776621556f317355665a622b4b2a4a477330214f4272716309427926212a4a7766543f7731773f395a62794b636466752b3275632b5d572c59587a
... ...
@@ -50,7 +51,7 @@ Trojan.IRC-Bot.gen (Clam)=494e5649444941aec1a17742*41844e534849454c4400*73094ce2
50 50
 Trojan.IRC-Sdbot (Clam)=773030742e616469676974616c2e6e6574ffff416e6b0b1a4432340023c5f1ee6debadadafc7d44e848dbdff8a4f4c45bf2e326b321e3e323ffb652b6c36006d736f66807eff057b6578658f034d6963726f1700a74096e5a97205a710db0bbf882525636f5f7065630820bff0b6fb2f632025730200400e686f205c660d0a3a735bf8b7
51 51
 Trojan.Bionet.313 (Clam)=8366cf9034d82e01109c82743e4fbc22eeff0942696f4e6574636667bf062cf802ce4ce19214da41b59f01bd300eb926f3a5a460933c305ecf8544cecab9fcefe2fb10002bba78d51c48c94cc1742026e5864c4dd149e16c6536782dbf85c4868d27a2245e250b4ebcff2524424e3230494424135e3c6826803537531c2046f0
52 52
 Trojan.Sub7-V21.srv (Clam)=615408086921f29001000c9434573bfdf60c0c2d7828ea06435569657902c0955ced10521992e61d30728414140430b5c354fa4964492e64e9f6181805e4f292153ea86f34708c706ab2d42e7e1efc17449496be487348279b008fe47248187ad606d07c65b35c2e687fe08c50e473b6592e9b8444743875
53
-Worm.Fakerr.a (Clam)=09000b48006b496c4c6552675561546520312e30332c2049206d416b6520546849732076497255732042654361557345204920644f6e27542068417645204e6f5468496e4720744f20644f2121
53
+Worm.Gruel.A (Clam)=09000b48006b496c4c6552675561546520312e30332c2049206d416b6520546849732076497255732042654361557345204920644f6e27542068417645204e6f5468496e4720744f20644f2121
54 54
 Trojan.Webber.A (Clam)=c3005589e551505356578b750c8365f8008365fc00eb4f31db89dfeb368b45fc01f88b55080fbe04020fbe143e39d075014389f183c8ff40803c010075f939c37510ff45f88b45103945f875058b45fceb2d4789f183c8ff40803c010075f939c772baff45fc8b450889c183c8ff40803c010075f93945fc72
55 55
 Troj/IGMPNuke (Clam)=2bc266dabdc059d785f030ed9b76751bb9bfc093edf2f10d751ec8240f751f496e6105fe75eceb398ac1045a1f10e91b9b7b200621ea318d4c130303abb9ed76c607d0803fccf7b8c788c2aced60075ed288f6d0ec87ffd77306f0be9bd97dfa9bdbe2d98e68adbfe14ed9ee9d84868a3e
56 56
 Troj/EliteWrap.103 (Clam)=636a010072199a380a00c40404006c6f61640000636a000072197d31960072197d318c007219ea6710009d190c009d1908009d1904009d190000a76204009800726a02000000522d9a004b49b1679a380e000c05080057696e4c6f6733320000636a020072199a380c00240506004c6f
... ...
@@ -152,3 +153,24 @@ Troj/FDoS-ICQRevenge (Clam)=01000904000078010000000000007f9036350000000000000100
152 152
 Troj/SendFake-A (Clam)=ff50e80603000083c40c8d8524feffff50e89bfbffff83c404908d8524feffff50683c134000e8c6fbffff83c4088d8524feffff50e89b02000083c40489c085c07518a1ac20400050e87702000083c4046a01e8a502000083c40468621340008d8524feffff50e8b102000083c40889c0898520fdffff83bd20fdffff0075178d8524feffff506865134000e85402000083c408eb03
153 153
 Troj/DDoS-Snoofer (Clam)=f0d38d45b05121d78d55d0edf003f1f5106aff006a408b0656ff9058122233219e21154cf4f20ca922bbeb0949121c0700a7f0fc2e047268474f580034262d3626fee02155b08d45c08d4de3d0523520bb27890410ff5290930da30aac0dbc0c28cc0ddc0320eee30ddb68f835116a0f562e08f6ff92640d19e81a10b4f026d52015b4bf232af0acdcf2b613f7f868e845f0578b07ff
154 154
 Troj/DDoS-Snoofer.b (Clam)=ec83ec0c684611400064a100000000506489250000000083ec2853568b7508578bc683e6fe8965f483e0018b0ec745f820104000568945fc897508ff51048b1633db68f8304000536a0f56895de8895de4895dd4ff92640300008b3d74a14000508d45e850ffd78d4dd45051ff15b4a1400083c41050ff15aca140008d55e45052ffd78bf868e8304000578b07ff
155
+Trojan.Yabinder (Clam)=14c962836612134420315598be5551f0897704b8a330cfaeff0f41a408f3c7ba476a40cc89470c51011e42b42b3949b48858fcf54e280e2c5737cdc7df4023c55d7b11536563686f204e6897f86f66660d0a857279057b6a3ce4370168c8a44f807e8ad442b574150cbdf6510305bf64059188193b4c4dd41247553481162c
156
+Pieck (Clam)=eb0e00fe000000000000000000000000be0c00fa2e89a40b082e8c940d088cc88ed0bc6018fb561e06b8ffffbb7203cd213d72
157
+Trojan.SMS-Bomber (Clam)=5f534d535f426f6d620000000000ffcc31002fc38be28b583ad411a5a900606737252fc48be28b583ad411a5a900606737252f3a4fad339966cf11b70c00aa0060
158
+W97M.Coldape.A (Clam)=4e69636b2022546865204c6f7665204d6f6e6b657922205669727573205061636b61676520627920414c542d463420616e6420414c542d46313120666f722074686520416c7465726e6174697665205669727573204d61666961ce00000000000000a40001001e00ca00ae00020027a5ce00ae000400446f6e65ae000000ae004100484b45595f43555252454e545f555345525c536f6674776172655c564220616e64205642412050726f6772616d2053657474696e67735c4f66666963655c382e3000ae00070041564d2d5642530020
159
+Worm.Lovgate.B (Clam)=0e70bad803bf2c5ca6ea5bcd856cd39fec1d480a7a1bcead158efee92dd12a10c3b72e9d6249a633c804737d2f31ee75ccfc42f46cfbf1028316799a00a98c07a38f916f21caca64eb1bf1abcda9e8649e3b632c56862fa65364522afc8aed05a1f0508026e1ed18119787f699ccce95eaeba3dc0bbb8bb0d3c91d8aba1945
160
+Trojan.BombXP.2.0.0.0rev0.1c (Clam)=736d73626f6d620000000000ffcc3100056f95bbe7724adf4babd30f9f2868e854aa1b68b1730da449b4aedaf375a9409c3a4fad339966cf11b70c00aa0060d3
161
+Trojan.Qwak (Clam)=207061737377292e2e2e00496e76616c6964204469616c6563742e2e2e00004e6f207265706c792066726f6d206469616c65637420726571756573742e2e2e0000000053656e64696e67206469616c656374206e65676f74696174652e2e2e0000000043616c6c6564206e616d65206e6f7420666f756e64202857726f6e67
162
+Joke.Boredom.A (Clam)=065557696e646f777320686173206465746563746564207468617420796f75206d6179207375666665722066726f6d20686176696e67206120736d616c6c2070656e69732e20204973207468697320636f72726563743f08576f72645772617009000007
163
+Trojan.Prosiak.E (Clam)=24c3546561a5391094a86134f15369cf2ba872341005d6c5fa3c444c14696d6534e359f73e256f77696842d0759924090c46ffd068732369616041717561ade02744d8a9100b0c53e7210492b442130a
164
+Trojan.Prosiak.G (Clam)=48c64a57e1aa3001da8ff812feff81db6d61696c2e6c75626c696e2e706cef39a26ac2b77ad90192
165
+Worm.Romeo (Clam)=c7ad193b3990f4a8100cd6f1c6e5895c895b6f1beb3acf4308d22dd4d1137e5ae32c373ce7edc1e07c0d250c1c843217a15c358381bd1d052d1709dbecb30a607e
166
+Worm.MyLife.B (Clam)=01cfffffef216e740d0a526550726f6a65637431000d0a466f722069ff433664cbcc314338440f3a0fc0feff4fad339966cf11b70c00aa0060d393e4b104bfdbde6c0382000500666c6d74010300636172e4b6fbdb00199042002204233e1c6c74a536046e3956f8020020043ae8022607
167
+Trojan.Dropper.B (Clam)=4d494d452d56657273696f6e3a20312e300d436f6e74656e742d4c6f636174696f6e3a46696c653a2f2f666f6f2e6578650d436f6e74656e742d5472616e736665722d456e636f64696e673a2062696e6172790d0d4d5a90000300000004000000ffff00
168
+Exploit.ObjCodebase.Calc (Clam)=0909093c6f626a6563742077696474683d30206865696768743d302069643d226f46696c652220636c61737369643d22636c7369643a31313131313131312d313131312d313131312d313131312d3131313131313131313131312220636f6465626173653d22633a2f77696e6e742f73797374656d33322f63616c632e657865223e3c2f6f626a6563743e
169
+Exploit.ObjCodebase.Calc.Mail (Clam)=636f6465626173653d334422633a2f77696e6e742f73797374656d33322f63616c632e657865223e3c2f6f626a6563743e
170
+Trojan.Prorat.10.B (Clam)=3a767a2d546f5804124a8071e6f4839dfdd5218f5e15e6e55ee0b6ded352a97f8e40ca19565ca844410a44661fcea88df445f9e561acb83b60a20754d3c536d5478b0575aa0d51d901cb111eb3b4644fabf8ef406fbb15c5738f1ff71635acb07d2fb1e8d9df1650e7dee835606dd80ba47f96b9e3e8eaef7c3038ae203d4205f11423bb5a4740
171
+Trojan.Dropper.C (Clam)=3c5343524950540866756e6374a76effffdffa206d616c77ab652829
172
+Trojan.Delf.BZ (Clam)=14e97b00f7ffb8807b4900e82d09f7ffe8c803f7ffa1d06549008b00e804a4fbff833d7c7b490000740ba17c7b490050e8f03bf7ff33c05a595964891068b1324900c3e9ed02f7ffebf85f5e5be81307f7ff00000069736e736572766572000000ffffffff16000000687474703a2f2f7777772e697370796e6f772e636f6d
173
+Troj/SunOS.RootKit #2 (Clam)=6e222c206765747569642829293b0d0a7d0d0a5f454f465f0d0a6363202d6f20757372207573722e630d0a63686d6f6420373030207573720d0a4946533d222f220d0a6578706f7274204946530d0a2f7573722f6f70656e77696e2f62696e2f66662e636f7265203020302030203020300d0a2366666320302030206664302f66643020310d0a726d202d6620757372207573722e63
174
+V2PX.1200 (Clam)=e701b9fa326f385b389954b810d76f2198da1a7867124f387b18b9749801bb84326f387b18b974782b5bb17859d380e0580f9579d116a0b16ec28c07813b38b3eeb9faa838f5196a0a251b186d15a01a5aa11818a21818f5194b3bd1e2386bb3f069153b38b1bccc58d999f95cd3a6d9b7e95ad155ec7475998b6931ee48504eb833fe489d47b89d119c11de7011
175
+V2P6.1993 (Clam)=303635a13de5b23e58ee096990e5308e40e469405e296fe428b9884fde4e884e3635a13e3fde65884e856e8a4e856e64ae1a61e48ede4ed7666ebe821d6c884e8c963736adf286b491703ed66e6e3e71e5288243d46e94cd626ee5288243fc6ecd6a6e6036cd686ecd606e953671f3adf2703ed66e6e3e71e528b294cd626ee528b6cd6a6ee528b4cd686ee528b0cd606e953671f3ad
... ...
@@ -31,7 +31,7 @@
31 31
         <p class="COPYRIGHT">Copyright &copy; 2002 by Paul Hoadley and
32 32
         Eric Parsonage</p>
33 33
 
34
-        <p class="PUBDATE">$Date: 2003/07/29 15:42:40 $<br>
34
+        <p class="PUBDATE">$Date: 2003/08/02 22:37:52 $<br>
35 35
         </p>
36 36
 
37 37
         <div>
... ...
@@ -57,10 +57,9 @@ int downloadmanager(const struct optstruct *opt, const char *hostname)
57 57
     mprintf("Checking for a new database - started at %s", ctime(&currtime));
58 58
 
59 59
 
60
-
61
-    /* first thing we want, is a local file md5 checksum */
60
+    /* first thing we want is a local file md5 checksum */
62 61
     if(fileinfo(DB1NAME, 1) == -1) {
63
-	/* there is no database, so we just download new one */
62
+	/* there is no database, so we just download a new one */
64 63
 	nodb = 1; 
65 64
 	mprintf(DB1NAME" not found in the data directory.\n");
66 65
     } else {
... ...
@@ -70,9 +69,7 @@ int downloadmanager(const struct optstruct *opt, const char *hostname)
70 70
 	}
71 71
     }
72 72
 
73
-    /* second database */
74 73
     if(fileinfo(DB2NAME, 1) == -1) {
75
-	/* there is no database, so we just download new one */
76 74
 	nodb2 = 1; 
77 75
 	mprintf(DB2NAME" not found in the data directory.\n");
78 76
     } else {
... ...
@@ -82,10 +79,6 @@ int downloadmanager(const struct optstruct *opt, const char *hostname)
82 82
 	}
83 83
     }
84 84
 
85
-    /*
86
-     * Ok, we have local file md5 checksum, now we download md5sum of current
87
-     * database from Internet.
88
-     */
89 85
 
90 86
     if(optl(opt, "proxy-user")) {
91 87
 	user = getargl(opt, "proxy-user");
... ...
@@ -75,7 +75,7 @@ struct cl_node {
75 75
     struct patt *list;
76 76
     struct cl_node *trans[CL_NUM_CHILDS], *fail;
77 77
 
78
-    /* FIXME: these variables are only used in the root node */
78
+    /* FIXME: these variables are only used in a root node */
79 79
     unsigned int maxpatlen, partsigs;
80 80
     unsigned int nodes;
81 81
     struct cl_node **nodetable;
... ...
@@ -106,11 +106,13 @@ extern int cl_loaddb(const char *filename, struct cl_node **root, int *virnum);
106 106
 extern int cl_loaddbdir(const char *dirname, struct cl_node **root, int *virnum);
107 107
 extern char *cl_retdbdir(void);
108 108
 
109
-/* datadir stat functions */
109
+/* data dir stat functions */
110 110
 extern int cl_statinidir(const char *dirname, struct cl_stat *dbstat);
111 111
 extern int cl_statchkdir(const struct cl_stat *dbstat);
112 112
 extern int cl_statfree(struct cl_stat *dbstat);
113 113
 
114
+/* enable debug information */
115
+extern void cl_debug(void);
114 116
 
115 117
 /* build a trie */
116 118
 extern void cl_buildtrie(struct cl_node *root);
... ...
@@ -17,7 +17,7 @@
17 17
  */
18 18
 
19 19
 #ifndef	CL_DEBUG
20
-#define	NDEBUG	/* map CLAMAV debug onto standard */
20
+/*#define	NDEBUG	/* map CLAMAV debug onto standard */
21 21
 #endif
22 22
 
23 23
 #ifdef CL_THREAD_SAFE
... ...
@@ -36,6 +36,7 @@
36 36
 #include <fcntl.h>
37 37
 #include <sys/stat.h>
38 38
 #include <sys/types.h>
39
+#include <sys/param.h>
39 40
 #include <clamav.h>
40 41
 
41 42
 #include "table.h"
... ...
@@ -72,7 +73,8 @@ static	size_t	strip(char *buf, int len);
72 72
 static	size_t	strstrip(char *s);
73 73
 static	bool	continuationMarker(const char *line);
74 74
 static	int	parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const char *arg);
75
-static	int	saveFile(const blob *b, const char *dir);
75
+static	bool	saveFile(const blob *b, const char *dir);
76
+static	bool	newMessageStart(const char *buf);
76 77
 
77 78
 /* Maximum number of attachements that we accept */
78 79
 #define	MAX_ATTACHMENTS	10
... ...
@@ -85,6 +87,8 @@ static	int	saveFile(const blob *b, const char *dir);
85 85
 #define	CONTENT_TRANSFER_ENCODING	2
86 86
 #define	CONTENT_DISPOSITION		3
87 87
 
88
+/*#define	VALIDATE_MBOX	/* validate the file is a UNIX mbox */
89
+
88 90
 /* Mime sub types */
89 91
 #define	PLAIN		1
90 92
 #define	ENRICHED	2
... ...
@@ -144,9 +148,8 @@ cl_mbox(const char *dir, int desc)
144 144
 
145 145
 	cli_dbgmsg("in mbox()\n");
146 146
 
147
-	if(initialiseTables(&rfc821Table, &subtypeTable) < 0) {
147
+	if(initialiseTables(&rfc821Table, &subtypeTable) < 0)
148 148
 		return -1;
149
-	}
150 149
 
151 150
 	m = messageCreate();
152 151
 	assert(m != NULL);
... ...
@@ -155,7 +158,7 @@ cl_mbox(const char *dir, int desc)
155 155
 
156 156
 	if((fd = fdopen(dup(desc), "rb")) == NULL) {
157 157
 		cli_errmsg("Can't open descriptor %d\n", desc);
158
-	    return -1;
158
+		return -1;
159 159
 	}
160 160
 
161 161
 	/*
... ...
@@ -166,18 +169,18 @@ cl_mbox(const char *dir, int desc)
166 166
 		char *strptr;
167 167
 #endif
168 168
 		/*cli_dbgmsg("read: %s", buffer);*/
169
+#ifdef	VALIDATE_MBOX
169 170
 		if(first)
170 171
 			/*
171 172
 			 * Check it is a mail box.
172 173
 			 * tm@softcom.dk: check for a single mail message
173 174
 			 */
174
-			if((strncmp(buffer, "From ", 5) != 0) &&
175
-			   (strncmp(buffer, "Return-Path: ", 13) != 0) &&
176
-			   (strncmp(buffer, "Received: ", 10) != 0)) {
175
+			if(!newMessageStart(buffer)) {
177 176
 				cli_errmsg("Not a valid mail message");
178 177
 				retcode = -1;
179 178
 				break;
180 179
 			}
180
+#endif
181 181
 
182 182
 		/*
183 183
 		 * Handle this where we're mid point through this stuff
... ...
@@ -198,7 +201,7 @@ cl_mbox(const char *dir, int desc)
198 198
 			for(ptr = strtok_r(buffer, ";\r\n", &strptr); ptr; ptr = strtok_r(NULL, ":\r\n", &strptr))
199 199
 				messageAddArgument(m, ptr);
200 200
 
201
-		} else if((!inHeader) && lastLineWasEmpty && (strncmp(buffer, "From ", 5) == 0)) {
201
+		} else if((!inHeader) && lastLineWasEmpty && newMessageStart(buffer)) {
202 202
 			/*
203 203
 			 * New message, save the previous message, if any
204 204
 			 */
... ...
@@ -234,7 +237,7 @@ cl_mbox(const char *dir, int desc)
234 234
 			} else {
235 235
 				const bool isLastLine = !continuationMarker(buffer);
236 236
 				const char *cmd = strtok_r(buffer, " \t", &strptr);
237
-				
237
+
238 238
 				if (cmd && *cmd) {
239 239
 					const char *arg = strtok_r(NULL, "\r\n", &strptr);
240 240
 
... ...
@@ -284,7 +287,6 @@ cl_mbox(const char *dir, int desc)
284 284
 	tableDestroy(rfc821Table);
285 285
 	tableDestroy(subtypeTable);
286 286
 
287
-
288 287
 	cli_dbgmsg("cli_mbox returning %d\n", retcode);
289 288
 
290 289
 	return retcode;
... ...
@@ -298,7 +300,7 @@ cl_mbox(const char *dir, int desc)
298 298
  * textIn is the plain text message being built up so far
299 299
  * blobsIn contains the array of attachments found so far
300 300
  *
301
- * Returns: 
301
+ * Returns:
302 302
  *	0 for fail
303 303
  *	1 for success, attachements saved
304 304
  *	2 for success, attachements not saved
... ...
@@ -308,7 +310,7 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
308 308
 {
309 309
 	char *ptr;
310 310
 	message *messages[MAXALTERNATIVE];
311
-	int inhead, inMimeHead, i, rc;
311
+	int inhead, inMimeHead, i, rc, htmltextPart, multiparts = 0;
312 312
 	text *aText;
313 313
 	blob *blobList[MAX_ATTACHMENTS], **blobs;
314 314
 	const char *cptr;
... ...
@@ -325,9 +327,8 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
325 325
 	blobs = blobsIn;
326 326
 
327 327
 	/* Anything left to be parsed? */
328
-	if(mainMessage) {
328
+	if(mainMessage && (messageGetBody(mainMessage) != NULL)) {
329 329
 		int numberOfAttachments = 0;
330
-		int plaintextPart, multiparts;
331 330
 		mime_type mimeType;
332 331
 		const char *mimeSubtype;
333 332
 		const text *t_line;
... ...
@@ -338,7 +339,6 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
338 338
 		char *strptr;
339 339
 #endif
340 340
 
341
-		assert(messageGetBody(mainMessage) != NULL);
342 341
 		mimeType = messageGetMimeType(mainMessage);
343 342
 		mimeSubtype = messageGetMimeSubtype(mainMessage);
344 343
 
... ...
@@ -366,7 +366,7 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
366 366
 
367 367
 			if(boundary == NULL) {
368 368
 				cli_warnmsg("Multipart MIME message contains no boundaries\n");
369
-				return 2;       /* Broken e-mail message */
369
+				return 2;	/* Broken e-mail message */
370 370
 			}
371 371
 
372 372
 
... ...
@@ -494,10 +494,10 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
494 494
 				aMessage = NULL;
495 495
 				assert(multiparts > 0);
496 496
 
497
-				plaintextPart = getTextPart(messages, multiparts);
497
+				htmltextPart = getTextPart(messages, multiparts);
498 498
 
499
-				if(plaintextPart >= 0)
500
-					aText = textAddMessage(aText, messages[plaintextPart]);
499
+				if(htmltextPart >= 0)
500
+					aText = textAddMessage(aText, messages[htmltextPart]);
501 501
 				else
502 502
 					/*
503 503
 					 * There isn't a text bit. If there's a
... ...
@@ -507,11 +507,11 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
507 507
 					for(i = 0; i < multiparts; i++)
508 508
 						if(messageGetMimeType(messages[i]) == MULTIPART) {
509 509
 							aMessage = messages[i];
510
-							plaintextPart = i;
510
+							htmltextPart = i;
511 511
 							break;
512 512
 						}
513 513
 
514
-				assert(plaintextPart != -1);
514
+				assert(htmltextPart != -1);
515 515
 
516 516
 				rc = insert(aMessage, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable);
517 517
 				blobArrayDestroy(blobs, nBlobs);
... ...
@@ -536,12 +536,12 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
536 536
 			case ALTERNATIVE:
537 537
 				cli_dbgmsg("Multipart alternative handler\n");
538 538
 
539
-				plaintextPart = getTextPart(messages, multiparts);
539
+				htmltextPart = getTextPart(messages, multiparts);
540 540
 
541
-				if(plaintextPart == -1)
542
-					plaintextPart = 0;
541
+				if(htmltextPart == -1)
542
+					htmltextPart = 0;
543 543
 
544
-				aMessage = messages[plaintextPart];
544
+				aMessage = messages[htmltextPart];
545 545
 				aText = textAddMessage(aText, aMessage);
546 546
 
547 547
 				rc = insert(NULL, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable);
... ...
@@ -592,6 +592,7 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
592 592
 					assert(aMessage != NULL);
593 593
 
594 594
 					dtype = messageGetDispositionType(aMessage);
595
+					cptr = messageGetMimeSubtype(aMessage);
595 596
 
596 597
 #ifdef	CL_DEBUG
597 598
 					cli_dbgmsg("Mixed message part %d is of type %d\n",
... ...
@@ -600,13 +601,9 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
600 600
 
601 601
 					switch(messageGetMimeType(aMessage)) {
602 602
 					case APPLICATION:
603
-						/*
604
-						 * We don't care about the application
605
-						 * subtype, since we don't spawn
606
-						 * anything off
607
-						 */
608 603
 						if((strcasecmp(dtype, "attachment") == 0) ||
609
-						   (strcasecmp(dtype, "octet-stream")))
604
+						   (strcasecmp(cptr, "x-msdownload") == 0) ||
605
+						   (strcasecmp(dtype, "octet-stream") == 0))
610 606
 							addAttachment = TRUE;
611 607
 						else {
612 608
 							cli_dbgmsg("Discarded application not sent as attachment\n");
... ...
@@ -660,7 +657,8 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
660 660
 						 *
661 661
 						 */
662 662
 						cli_dbgmsg("Found multipart inside multipart\n");
663
-						rc = insert(NULL, blobs, nBlobs, messageToText(aMessage), dir, rfc821Table, subtypeTable);
663
+						/*rc = insert(NULL, blobs, nBlobs, messageToText(aMessage), dir, rfc821Table, subtypeTable);*/
664
+						rc = insert(aMessage, blobs, nBlobs, messageToText(aMessage), dir, rfc821Table, subtypeTable);
664 665
 
665 666
 						mainMessage = aMessage;
666 667
 						continue;
... ...
@@ -710,7 +708,9 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
710 710
 				 * the list we've just built up
711 711
 				 */
712 712
 				for(i = 0; i < nBlobs; i++) {
713
+#ifdef	CL_DEBUG
713 714
 					assert(blobs[i]->magic == BLOB);
715
+#endif
714 716
 					blobList[numberOfAttachments++] = blobs[i];
715 717
 				}
716 718
 
... ...
@@ -727,11 +727,11 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
727 727
 				 * message and we need to dig out the plain
728 728
 				 * text part of that alternative
729 729
 				 */
730
-				plaintextPart = getTextPart(messages, multiparts);
731
-				if(plaintextPart == -1)
732
-					plaintextPart = 0;
730
+				htmltextPart = getTextPart(messages, multiparts);
731
+				if(htmltextPart == -1)
732
+					htmltextPart = 0;
733 733
 
734
-				rc = insert(messages[plaintextPart], blobs, nBlobs, aText, dir, rfc821Table, subtypeTable);
734
+				rc = insert(messages[htmltextPart], blobs, nBlobs, aText, dir, rfc821Table, subtypeTable);
735 735
 				blobArrayDestroy(blobs, nBlobs);
736 736
 				break;
737 737
 			default:
... ...
@@ -775,6 +775,9 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
775 775
 				bool inHeader = TRUE;
776 776
 				bool inMimeHeader = FALSE;
777 777
 				message *m;
778
+
779
+				assert(t != NULL);
780
+
778 781
 				m = messageCreate();
779 782
 				assert(m != NULL);
780 783
 
... ...
@@ -822,7 +825,7 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
822 822
 						else {
823 823
 							const bool isLastLine = !continuationMarker(buffer);
824 824
 							const char *cmd = strtok_r(buffer, " \t", &strptr);
825
-							
825
+
826 826
 							if (cmd && *cmd) {
827 827
 								const char *arg = strtok_r(NULL, "\r\n", &strptr);
828 828
 
... ...
@@ -870,7 +873,10 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
870 870
 			return 0;
871 871
 
872 872
 		case APPLICATION:
873
-			if(strcasecmp(messageGetMimeSubtype(mainMessage), "octet-stream") == 0) {
873
+			cptr = messageGetMimeSubtype(mainMessage);
874
+
875
+			if((strcasecmp(cptr, "octet-stream") == 0) ||
876
+			   (strcasecmp(cptr, "x-msdownload") == 0)) {
874 877
 				blob *aBlob = messageToBlob(mainMessage);
875 878
 
876 879
 				if(aBlob) {
... ...
@@ -899,27 +905,67 @@ insert(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const cha
899 899
 		}
900 900
 	}
901 901
 
902
-
903 902
 #ifdef	CL_DEBUG
904 903
 	cli_dbgmsg("%d attachments found\n", nBlobs);
905 904
 #endif
906 905
 
907
-	if(nBlobs == 0 && mainMessage) {
906
+	if(nBlobs == 0) {
907
+		blob *b;
908
+
908 909
 		/*
909
-		 * No attachments, but it may still contain a uu-encoded file
910
+		 * No attachements - look for a text that we can save to scan
910 911
 		 */
911
-		blob *b;
912 912
 
913
-		messageSetEncoding(mainMessage,	"x-uuencode");
913
+#ifdef	CL_DEBUG
914
+		cli_dbgmsg("%d multiparts found\n", multiparts);
915
+#endif
916
+		htmltextPart = getTextPart(messages, multiparts);
917
+
918
+		if(htmltextPart > 0) {
919
+			b = messageToBlob(messages[htmltextPart]);
914 920
 
915
-		if((b = messageToBlob(mainMessage)) != NULL) {
916
-			if((cptr = blobGetFilename(b)) != NULL) {
917
-				cli_dbgmsg("Found uuencoded message %s\n", cptr);
921
+			assert(b != NULL);
922
+
923
+#ifdef	CL_DEBUG
924
+			cli_dbgmsg("Found HTML part in %d, encoded with scheme %d\n",
925
+				htmltextPart, messageGetEncoding(messages[htmltextPart]));
926
+#endif
927
+
928
+			(void)saveFile(b, dir);
918 929
 
919
-				(void)saveFile(b, dir);
920
-			}
921 930
 			blobDestroy(b);
922 931
 		}
932
+
933
+		if(mainMessage) {
934
+			/*
935
+			 * Look for uu-encoded main file
936
+			 */
937
+			const text *t_line;
938
+
939
+			for(t_line = messageGetBody(mainMessage); t_line; t_line = t_line->t_next) {
940
+				const char *line = t_line->t_text;
941
+
942
+				if((strncasecmp(line, "begin ", 6) == 0) &&
943
+				   (isdigit(line[6])) &&
944
+				   (isdigit(line[7])) &&
945
+				   (isdigit(line[8])) &&
946
+				   (line[9] == ' '))
947
+					break;
948
+			}
949
+
950
+			if(t_line != NULL) {
951
+				messageSetEncoding(mainMessage,	"x-uuencode");
952
+
953
+				if((b = messageToBlob(mainMessage)) != NULL) {
954
+					if((cptr = blobGetFilename(b)) != NULL) {
955
+						cli_dbgmsg("Found uuencoded message %s\n", cptr);
956
+
957
+						(void)saveFile(b, dir);
958
+					}
959
+					blobDestroy(b);
960
+				}
961
+			}
962
+		}
923 963
 	} else {
924 964
 		short attachmentNumber;
925 965
 
... ...
@@ -1028,13 +1074,10 @@ initialiseTables(table_t **rfc821Table, table_t **subtypeTable)
1028 1028
 }
1029 1029
 
1030 1030
 /*
1031
- * If there's a plain text version use that, otherwise
1031
+ * If there's a HTML text version use that, otherwise
1032 1032
  * use the first text part, otherwise just use the
1033
- * first one around
1034
- *
1035
- * Alternatively we could hunt out any HTML
1036
- * version and save that, if the displaying client
1037
- * can cope with HTML.
1033
+ * first one around. HTML text is most likely to include
1034
+ * a scripting worm
1038 1035
  *
1039 1036
  * If we can't find one, return -1
1040 1037
  */
... ...
@@ -1046,7 +1089,7 @@ getTextPart(message *const messages[], size_t size)
1046 1046
 	for(i = 0; i < size; i++) {
1047 1047
 		assert(messages[i] != NULL);
1048 1048
 		if((messageGetMimeType(messages[i]) == TEXT) &&
1049
-		   (strcasecmp(messageGetMimeSubtype(messages[i]), "plain") == 0))
1049
+		   (strcasecmp(messageGetMimeSubtype(messages[i]), "html") == 0))
1050 1050
 			return (int)i;
1051 1051
 	}
1052 1052
 	for(i = 0; i < size; i++)
... ...
@@ -1210,20 +1253,24 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
1210 1210
 	return type;
1211 1211
 }
1212 1212
 
1213
-static int
1213
+static bool
1214 1214
 saveFile(const blob *b, const char *dir)
1215 1215
 {
1216 1216
 	unsigned long nbytes = blobGetDataSize(b);
1217
-	const char *cptr;
1218
-	char *filename = NULL;
1219
-	size_t dirLen = strlen(dir);
1220 1217
 	int fd;
1221
-	const char *suffix;
1218
+	const char *cptr, *suffix;
1219
+#ifdef	NAME_MAX	/* e.g. Linux */
1220
+	char filename[NAME_MAX + 1];
1221
+#else
1222
+#ifdef	MAXNAMELEN	/* e.g. Solaris */
1223
+	char filename[MAXNAMELEN + 1];
1224
+#endif
1225
+#endif
1222 1226
 
1223 1227
 	assert(dir != NULL);
1224 1228
 
1225 1229
 	if(nbytes == 0)
1226
-		return 1;
1230
+		return TRUE;
1227 1231
 
1228 1232
 	cptr = blobGetFilename(b);
1229 1233
 
... ...
@@ -1243,9 +1290,11 @@ saveFile(const blob *b, const char *dir)
1243 1243
 	}
1244 1244
 	cli_dbgmsg("Saving attachment in %s/%s\n", dir, cptr);
1245 1245
 
1246
-	/* tk: use dynamic allocation */
1247
-	filename = cli_malloc(dirLen + strlen(cptr) + strlen(suffix) + 8);
1248
-	sprintf(filename, "%s/%sXXXXXX", dir, cptr);
1246
+	/*
1247
+	 * Allow for very long filenames. We have to truncate them to fit
1248
+	 */
1249
+	snprintf(filename, sizeof(filename) - 7, "%s/%s", dir, cptr);
1250
+	strcat(filename, "XXXXXX");
1249 1251
 
1250 1252
 	/*
1251 1253
 	 * TODO: add a HAS_MKSTEMP property
... ...
@@ -1259,8 +1308,7 @@ saveFile(const blob *b, const char *dir)
1259 1259
 
1260 1260
 	if(fd < 0) {
1261 1261
 		cli_errmsg("%s: %s\n", filename, strerror(errno));
1262
-		free(filename);
1263
-		return 0;
1262
+		return FALSE;
1264 1263
 	}
1265 1264
 
1266 1265
 	/*
... ...
@@ -1279,7 +1327,32 @@ saveFile(const blob *b, const char *dir)
1279 1279
 	cli_dbgmsg("Attachment saved as %s (%ul bytes long)\n",
1280 1280
 		filename, nbytes);
1281 1281
 
1282
-	free(filename);
1282
+	return TRUE;
1283
+}
1283 1284
 
1284
-	return 1;
1285
+static bool
1286
+newMessageStart(const char *buf)
1287
+{
1288
+	if(strncmp(buf, "From ", 5) == 0)
1289
+		return TRUE;
1290
+
1291
+	/*
1292
+	 * Do NOT enable this code, it gets confused by RFC822 messages
1293
+	 * enapsulated in other messages e.g.
1294
+	 *
1295
+	 * ....
1296
+	 * --NAB47372.960554223/xxx
1297
+	 * Content-Type: message/rfc822
1298
+	 *
1299
+	 * Return-Path: MAILER-DAEMON
1300
+	 * ....
1301
+	 */
1302
+#if	0
1303
+	if(strncmp(buf, "Return-Path: ", 13) == 0)
1304
+		return TRUE;
1305
+	if(strncmp(buf, "Received: ", 10) == 0)
1306
+		return TRUE;
1307
+#endif
1308
+
1309
+	return FALSE;
1285 1310
 }
... ...
@@ -43,6 +43,8 @@
43 43
 pthread_mutex_t cli_rand_mutex = PTHREAD_MUTEX_INITIALIZER;
44 44
 #endif
45 45
 
46
+int cli_debug_flag = 0;
47
+
46 48
 void cli_warnmsg(const char *str, ...)
47 49
 {
48 50
 	va_list args;
... ...
@@ -65,16 +67,21 @@ void cli_errmsg(const char *str, ...)
65 65
 
66 66
 void cli_dbgmsg(const char *str, ...)
67 67
 {
68
-#ifdef CL_DEBUG
69 68
 	va_list args;
70 69
 
71
-    va_start(args, str);
72
-    fprintf(stderr, "LibClamAV debug: ");
73
-    vfprintf(stderr, str, args);
74
-    va_end(args);
75
-#else
76
-    return;
77
-#endif
70
+    if(cli_debug_flag) {
71
+	va_start(args, str);
72
+	fprintf(stderr, "LibClamAV debug: ");
73
+	vfprintf(stderr, str, args);
74
+	va_end(args);
75
+    } else
76
+	return;
77
+
78
+}
79
+
80
+void cl_debug(void)
81
+{
82
+    cli_debug_flag = 1;
78 83
 }
79 84
 
80 85
 char *cl_perror(int clerror)
... ...
@@ -50,12 +50,12 @@ int cli_scanrar_inuse = 0;
50 50
 #define SCAN_ARCHIVE	(options & CL_ARCHIVE)
51 51
 #define SCAN_MAIL	(options & CL_MAIL)
52 52
 
53
-#define MAGIC_BUFFER_SIZE 6
53
+#define MAGIC_BUFFER_SIZE 10
54 54
 #define RAR_MAGIC_STR "Rar!"
55 55
 #define ZIP_MAGIC_STR "PK\003\004"
56 56
 #define GZIP_MAGIC_STR "\037\213"
57 57
 #define MAIL_MAGIC_STR "From "
58
-/*#define RAWMAIL_MAGIC_STR "Received: "*/
58
+#define RAWMAIL_MAGIC_STR "Received: "
59 59
 #define BZIP_MAGIC_STR "BZh"
60 60
 
61 61
 
... ...
@@ -637,12 +637,10 @@ int cli_magic_scandesc(int desc, char **virname, long int *scanned, const struct
637 637
 	    cli_dbgmsg("Recognized mail file.\n");
638 638
 	    ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
639 639
 	}
640
-	/*
641 640
 	else if(!strncmp(magic, RAWMAIL_MAGIC_STR, strlen(RAWMAIL_MAGIC_STR))) {
642 641
 	    cli_dbgmsg("Recognized raw mail file.\n");
643 642
 	    ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
644 643
 	}
645
-	*/
646 644
 
647 645
 	lseek(desc, 0, SEEK_SET);
648 646
     }
... ...
@@ -139,9 +139,10 @@ textAdd(text *t_head, const text *t)
139 139
 	if(t_head == NULL)
140 140
 		return textCopy(t);
141 141
 
142
-	ret = t_head;
142
+	if(t == NULL)
143
+		return t_head;
143 144
 
144
-	assert(t != NULL);
145
+	ret = t_head;
145 146
 
146 147
 	while(t_head->t_next)
147 148
 		t_head = t_head->t_next;
... ...
@@ -170,6 +171,8 @@ textAdd(text *t_head, const text *t)
170 170
 text *
171 171
 textAddMessage(text *aText, const message *aMessage)
172 172
 {
173
+	assert(aMessage != NULL);
174
+
173 175
 	if(messageGetEncoding(aMessage) == NOENCODING)
174 176
 		return textAdd(aText, messageGetBody(aMessage));
175 177
 	else {
... ...
@@ -4,7 +4,7 @@
4 4
 # Created: 1993-05-16
5 5
 # Public domain
6 6
 
7
-# $Id: mkinstalldirs,v 1.1 2003/07/29 15:39:41 nervoso Exp $
7
+# $Id: mkinstalldirs,v 1.2 2003/08/02 22:37:52 kojm Exp $
8 8
 
9 9
 errstatus=0
10 10
 dirmode=""
... ...
@@ -369,7 +369,7 @@ void help(void)
369 369
 {
370 370
     mprintf("\n");
371 371
     mprintf("		   Clam AntiVirus: Signature Tool (sigtool)  "VERSION"\n");
372
-    mprintf("		   (c) 2002 Tomasz Kojm <zolw@konarski.edu.pl>\n");
372
+    mprintf("	       (c) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>\n");
373 373
     mprintf("\n");
374 374
     mprintf("   --help		    -h		show help\n");
375 375
     mprintf("   --version		    -V		print version number and exit\n");