Copying ede-bug-report from branches in trunk

This commit is contained in:
Sanel Zukan 2009-07-03 14:23:51 +00:00
parent bfed428c37
commit 66e586f37f
138 changed files with 35380 additions and 0 deletions

View File

@ -0,0 +1,387 @@
#ifndef __BUGIMAGE_H__
#define __BUGIMAGE_H__
#include <FL/Fl_Image.H>
static unsigned char idata_bug[] =
{255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,
255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,
255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,
255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,
255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,
255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,
255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,
255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,
255,255,255,0,255,255,255,0,255,255,255,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,61,30,13,
1,61,30,13,38,255,254,254,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,
13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,62,32,14,0,77,45,23,0,93,60,
34,0,107,75,48,0,110,78,50,0,96,64,37,0,82,49,27,0,65,34,16,0,59,29,13,0,61,30,
13,0,61,30,13,0,61,30,13,0,61,31,14,0,67,35,16,0,78,46,24,0,67,35,17,0,59,29,
13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,61,30,13,87,61,30,13,17,61,30,13,0,61,30,13,0,61,30,
13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,62,32,
14,0,77,45,23,0,93,60,34,0,107,75,48,0,110,78,50,0,96,64,37,0,82,49,27,0,65,34,
16,0,59,29,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,31,14,0,67,35,16,0,78,46,
24,0,67,35,17,0,59,29,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,
13,0,61,30,13,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,63,32,14,75,61,31,13,
114,43,18,7,0,45,19,7,0,45,19,7,0,45,19,7,0,43,19,7,0,57,28,11,0,62,31,14,0,61,
30,13,0,61,30,13,0,62,32,14,0,77,45,23,0,93,60,34,0,107,75,48,0,110,78,50,0,96,
64,37,0,82,49,27,0,65,34,16,0,59,29,13,0,61,30,13,0,61,30,13,0,61,30,13,0,61,
31,14,0,67,35,16,0,78,46,24,0,67,35,17,0,55,26,11,0,57,27,11,0,57,27,11,0,58,
28,12,0,58,28,12,0,61,30,13,2,62,31,14,3,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
71,40,20,19,75,43,22,221,80,47,24,41,80,48,25,0,80,48,25,0,80,48,26,0,76,45,23,
0,61,30,13,0,61,30,13,0,61,30,13,0,61,30,13,0,62,32,14,0,77,45,23,0,93,60,34,
24,107,75,48,68,110,78,50,76,96,64,37,36,82,49,27,4,65,34,16,0,59,29,13,0,61,
30,13,0,61,30,13,0,61,30,13,0,61,31,14,0,65,35,16,0,80,47,25,0,75,43,22,0,40,
17,6,0,42,18,6,0,42,18,6,0,39,16,6,0,36,14,4,0,55,26,11,102,59,29,13,13,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,77,45,23,181,92,59,34,143,90,58,
33,0,88,58,33,0,92,60,34,0,81,48,25,0,59,28,12,0,61,30,13,0,61,30,13,0,54,25,
10,0,61,30,13,76,76,44,23,196,91,58,33,241,102,70,42,255,104,72,45,255,94,61,
36,249,81,48,25,215,65,34,16,114,61,29,13,10,61,30,13,0,59,29,13,0,61,30,13,0,
61,31,14,0,65,35,16,0,77,45,23,0,86,54,30,0,87,55,31,0,86,54,30,0,86,54,30,0,
78,46,24,0,62,32,14,118,37,15,5,92,29,10,3,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,43,20,7,60,84,54,30,195,57,23,9,0,61,19,7,0,65,30,13,0,69,
38,18,0,61,30,13,0,61,30,13,0,58,28,12,0,100,66,38,162,73,40,19,255,61,30,13,
255,80,47,25,255,90,57,33,255,91,58,33,255,84,52,28,255,73,41,20,255,62,31,14,
255,62,31,14,215,62,31,14,24,65,34,16,0,61,30,13,0,61,31,14,0,65,35,16,0,77,45,
23,0,86,54,30,0,91,58,33,0,88,56,32,0,88,56,32,0,86,53,29,140,57,29,13,201,29,
10,3,8,34,13,4,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,36,15,5,
12,78,48,25,212,67,29,13,53,86,37,18,0,82,42,21,0,69,38,18,0,59,29,13,0,62,31,
14,11,51,23,9,109,87,55,30,239,143,112,81,255,147,116,85,255,85,52,28,255,77,
45,24,255,77,44,23,255,73,40,20,255,63,32,14,255,55,25,10,255,45,18,6,255,58,
32,15,135,83,53,31,34,57,26,10,0,61,31,14,0,65,35,16,0,77,45,23,0,86,54,30,0,
96,63,37,0,96,63,37,0,96,64,37,80,78,47,25,255,33,13,4,84,34,13,4,0,34,13,4,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,76,45,23,165,
93,61,35,240,94,64,37,99,83,52,28,0,68,35,16,0,57,26,11,25,61,30,13,194,62,31,
14,255,47,21,8,255,47,21,8,255,81,49,25,255,126,93,62,255,134,102,72,255,84,51,
27,255,42,18,7,255,43,20,8,255,76,48,27,255,78,57,40,255,81,66,55,255,84,70,59,
231,64,37,20,67,59,28,12,0,65,35,16,0,77,45,23,0,86,54,30,0,97,64,38,0,101,69,
42,4,94,62,36,209,28,10,3,150,29,11,3,22,40,18,6,0,40,18,6,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,45,21,8,26,54,28,12,163,83,51,
27,206,80,47,25,177,77,47,26,84,67,38,20,214,55,25,10,255,61,30,13,255,62,31,
14,255,62,31,14,255,54,25,10,255,49,22,9,255,51,23,9,255,46,21,8,255,34,19,10,
255,51,35,22,255,67,51,37,255,68,55,43,255,75,64,53,255,85,75,68,255,88,78,70,
246,68,41,24,75,65,34,15,0,77,45,23,0,86,54,30,15,96,64,38,113,100,68,41,187,67,
38,18,200,12,3,0,63,37,16,5,1,36,15,5,0,53,25,10,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,37,17,6,5,12,3,0,83,34,15,5,52,46,24,10,
114,104,83,65,243,169,161,160,255,58,31,16,255,45,18,7,255,47,20,7,255,54,24,10,
255,59,29,12,255,62,31,14,255,62,31,14,255,59,29,13,255,36,19,10,255,40,26,16,
255,50,36,24,255,62,47,34,255,70,57,45,255,78,66,56,255,88,80,73,255,88,77,68,
245,53,29,14,166,70,43,22,196,86,53,29,196,87,55,31,205,82,49,27,187,29,11,3,
109,40,19,7,15,45,22,8,0,53,26,11,0,62,31,14,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,42,22,9,0,7,8,3,56,0,0,0,110,170,48,1,136,175,
50,1,214,160,141,125,255,216,214,216,255,170,150,131,255,142,116,94,255,102,76,
55,255,68,40,22,255,59,29,12,255,61,30,13,255,58,28,12,255,31,15,6,255,33,20,
10,255,45,30,18,255,55,40,27,255,64,50,37,255,73,60,48,255,80,71,63,255,73,55,
40,255,147,75,41,255,99,36,14,93,47,27,12,11,46,22,9,20,26,10,3,67,22,8,2,79,
47,23,9,0,45,21,8,0,49,22,9,0,58,28,12,37,62,31,14,33,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,61,30,13,8,62,31,14,8,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,80,33,10,0,107,41,9,0,188,65,7,133,255,101,9,255,255,
103,6,255,190,60,0,255,172,149,125,255,255,254,254,255,255,254,254,255,207,197,
190,255,104,79,60,255,61,32,16,255,61,29,13,255,58,28,12,255,24,10,3,255,24,13,
6,255,39,24,13,255,49,34,22,255,58,43,31,255,65,54,43,255,62,45,33,255,180,
112,75,255,237,132,94,254,168,43,13,163,0,2,0,60,0,0,0,103,4,0,0,119,37,16,5,39,
50,25,10,0,47,23,9,0,34,13,4,0,45,19,7,102,47,20,8,39,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,61,30,13,62,57,27,11,170,53,24,
10,122,61,32,14,49,97,64,38,32,111,80,51,4,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,121,49,13,0,255,110,16,56,255,123,23,249,251,125,27,255,250,
119,22,255,255,110,10,255,162,48,0,255,166,148,126,255,255,254,254,255,254,254,
254,255,167,148,131,255,76,49,31,255,59,28,12,255,59,29,13,255,21,7,1,255,15,6,
2,255,31,18,9,255,43,28,16,255,46,36,24,255,55,47,37,255,185,130,103,255,235,
144,114,255,219,98,67,255,213,62,21,255,120,28,7,149,21,8,2,19,42,19,7,9,57,30,
13,0,85,54,30,0,95,62,36,0,81,48,26,122,51,24,10,156,255,254,254,0,255,254,254,
0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,31,11,
3,13,28,9,3,77,61,32,15,171,88,56,32,221,99,68,41,145,107,76,48,120,97,64,38,
186,81,49,26,160,61,32,16,109,73,33,13,95,245,127,38,206,255,146,48,255,252,143,
48,255,250,135,38,255,251,127,28,255,253,117,13,255,163,57,1,255,147,113,83,
255,227,225,223,255,238,236,238,255,129,104,85,255,61,32,16,255,59,28,12,255,21,
6,1,255,4,0,0,255,18,11,5,255,24,26,21,255,88,75,64,255,192,141,118,255,227,
109,77,255,215,81,50,255,217,83,43,255,214,73,28,255,215,66,23,231,123,40,14,47,
61,38,19,26,91,59,33,61,101,69,43,73,97,64,38,129,77,45,24,242,42,18,7,102,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,22,7,2,2,29,11,3,58,10,2,0,94,42,20,8,
95,67,39,19,133,71,41,20,147,49,24,10,108,155,89,48,205,254,179,112,255,255,
166,83,255,252,157,70,255,251,146,55,255,250,139,42,255,252,136,33,255,255,128,
7,255,209,76,0,255,142,58,11,255,157,128,99,255,165,153,139,255,92,67,47,255,
57,27,11,255,7,4,1,255,5,5,5,255,70,56,50,255,159,111,90,255,211,124,94,255,
222,82,50,255,215,71,43,255,226,87,48,255,224,83,37,255,220,89,41,255,224,85,36,
255,157,55,21,247,62,36,18,211,83,50,27,237,90,57,32,253,78,47,24,218,19,5,1,
123,21,6,1,36,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,36,15,5,33,24,9,2,68,22,8,2,57,21,9,2,63,33,8,1,52,237,137,65,201,255,
182,112,255,255,174,98,255,252,165,85,255,251,151,61,255,255,142,45,255,255,139,
35,255,255,129,10,255,255,122,0,255,252,98,0,255,207,54,0,255,144,42,6,255,69,
32,14,255,21,12,4,255,55,12,2,255,153,64,35,255,215,113,78,255,228,91,56,255,
220,66,36,255,214,58,28,255,211,60,25,255,151,42,14,255,186,64,26,255,227,94,45,
255,224,99,48,255,224,93,41,245,112,40,14,54,34,16,6,29,37,17,6,69,24,9,2,96,10,
2,0,84,29,11,3,14,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,34,20,9,1,0,10,7,34,101,27,2,142,254,
127,29,255,255,156,61,255,253,163,77,255,252,159,74,255,253,148,56,255,232,122,
37,255,217,102,21,255,251,112,4,255,253,111,0,255,249,106,0,255,249,92,0,255,
247,68,0,255,194,35,0,255,100,8,0,255,210,32,1,255,228,49,9,255,225,63,30,255,
216,53,19,255,215,49,14,255,220,50,17,255,133,27,7,255,0,0,0,255,28,4,0,255,197,
71,30,255,229,101,49,255,235,106,49,255,128,44,14,159,0,0,0,95,0,0,0,120,10,2,
0,105,34,14,4,11,34,13,4,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
224,77,7,146,254,122,22,255,252,143,42,255,252,149,54,255,254,148,52,255,236,
128,40,255,115,53,24,255,36,15,8,255,145,44,0,255,255,99,0,255,248,96,0,255,244,
89,0,255,238,70,0,255,231,46,0,255,196,23,0,255,220,33,0,255,219,40,1,255,219,
46,4,255,215,43,7,255,210,39,9,255,214,39,11,255,94,12,3,255,0,0,0,255,0,0,0,
255,131,37,11,255,231,93,42,255,230,102,46,255,198,81,31,210,45,12,3,36,10,5,1,
50,29,11,3,31,46,23,8,0,45,21,8,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,253,85,3,196,252,113,14,255,252,128,26,255,252,132,31,255,255,133,30,
255,219,104,23,255,61,25,12,255,0,2,1,255,83,16,0,255,255,82,0,255,246,81,0,255,
242,80,0,255,237,67,0,255,226,43,0,255,191,23,0,255,217,34,0,255,220,43,2,255,
218,44,4,255,212,35,5,255,206,29,6,255,210,30,8,255,132,18,4,255,0,0,0,255,0,0,
0,255,135,36,10,255,229,86,35,255,226,96,42,255,227,100,42,249,140,52,17,36,
69,22,7,0,26,12,3,0,40,22,9,0,40,21,8,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
114,43,11,88,245,81,0,248,254,102,3,255,252,110,9,255,252,113,12,255,253,111,11,
255,249,102,6,255,114,33,1,255,24,2,0,255,148,35,0,255,253,71,0,255,243,68,0,
255,240,72,0,255,236,63,0,255,224,41,0,255,190,23,0,255,215,34,0,255,219,42,2,
255,217,40,4,255,209,29,4,255,203,23,4,255,202,25,6,255,202,33,9,255,120,19,4,
255,130,28,7,255,210,64,23,255,222,81,32,255,226,96,42,255,231,106,48,255,132,
50,16,99,120,42,13,0,100,36,11,0,91,34,11,0,92,33,10,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,95,62,37,1,69,
48,29,125,128,48,12,234,252,80,0,255,252,90,0,255,252,93,0,255,253,94,0,255,
253,92,0,255,255,88,0,255,250,80,0,255,230,66,0,255,247,66,0,255,243,59,0,255,
239,61,0,255,237,67,0,255,233,60,0,255,222,38,0,255,188,23,1,255,213,33,0,255,
217,41,2,255,214,36,3,255,207,26,3,255,201,21,4,255,201,25,6,255,205,34,9,255,
214,45,14,255,219,57,20,255,217,68,25,255,221,82,33,255,227,98,42,255,237,113,
51,255,137,59,23,217,104,40,13,18,124,50,17,0,127,50,18,0,121,61,29,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,104,73,45,10,105,73,46,80,
94,64,39,193,88,51,24,164,210,66,2,91,252,88,4,255,251,92,1,255,252,87,0,255,
251,82,0,255,250,79,0,255,249,76,0,255,249,72,0,255,250,67,0,255,243,57,0,255,
238,52,0,255,236,56,0,255,234,63,0,255,231,56,0,255,220,36,0,255,186,23,1,255,
210,32,1,255,216,39,2,255,211,32,3,255,204,23,3,255,200,20,4,255,201,26,6,255,
204,34,10,255,207,44,14,255,211,55,19,255,217,68,25,255,222,83,33,255,227,100,
44,255,241,118,54,255,160,71,29,251,58,36,18,187,86,53,30,7,100,67,41,0,105,76,
48,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,62,31,14,8,73,40,20,51,86,54,30,137,95,63,37,168,102,70,42,213,98,66,
39,254,73,43,22,170,19,8,2,46,130,31,1,145,255,123,40,255,250,94,7,255,249,77,
0,255,247,72,0,255,246,68,0,255,245,65,0,255,243,60,0,255,241,55,0,255,238,50,
0,255,234,48,0,255,233,51,0,255,231,55,0,255,227,48,0,255,217,31,0,255,184,23,
1,255,208,30,1,255,214,36,3,255,209,28,3,255,202,19,3,255,200,20,4,255,202,27,
7,255,205,35,10,255,208,45,14,255,212,57,20,255,217,70,27,255,223,86,35,255,
229,103,45,255,242,121,56,255,172,72,26,202,50,27,12,209,91,58,33,179,100,68,42,
5,106,75,47,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,55,27,11,73,50,23,9,150,57,28,12,196,51,26,11,175,40,18,6,134,39,18,6,155,
26,10,3,129,10,2,0,90,24,11,3,57,182,71,22,121,251,116,42,255,246,86,9,255,244,
65,0,255,241,59,0,255,239,55,0,255,238,53,0,255,237,50,0,255,236,48,0,255,233,
45,0,255,230,42,0,255,228,42,0,255,225,42,0,255,222,37,0,255,213,27,0,255,183,
22,1,255,206,28,1,255,212,33,3,255,206,25,3,255,200,18,3,255,200,21,5,255,203,
29,7,255,206,38,11,255,209,47,15,255,214,60,21,255,218,74,28,255,224,90,37,255,
230,107,48,255,244,125,59,255,174,73,26,210,7,1,0,104,75,46,23,222,104,72,44,
195,106,75,47,53,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,49,22,9,9,15,3,0,8,26,9,3,6,28,10,3,2,24,8,2,35,22,7,2,50,31,12,4,37,
28,15,6,7,255,254,254,0,251,131,67,88,236,85,24,255,239,68,4,255,236,53,0,255,
233,48,0,255,233,46,0,255,233,45,0,255,232,44,0,255,231,43,0,255,229,40,0,255,
226,38,0,255,223,35,0,255,221,32,0,255,217,29,0,255,209,23,0,255,180,21,1,255,
203,25,1,255,210,30,4,255,204,22,4,255,199,18,4,255,200,24,6,255,203,31,8,255,
207,40,12,255,210,50,17,255,214,63,22,255,220,77,30,255,226,93,39,255,232,111,
50,255,247,129,61,255,162,68,24,211,0,0,0,116,17,6,1,116,82,50,27,223,104,72,
45,255,100,68,41,128,90,57,32,61,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,233,69,17,71,227,61,7,255,230,51,1,
255,227,39,0,255,227,39,0,255,228,41,0,255,228,40,0,255,227,40,0,255,226,38,0,
255,224,36,0,255,221,33,0,255,219,30,0,255,216,27,0,255,213,25,0,255,206,20,0,
255,178,19,2,255,200,23,2,255,208,27,5,255,203,22,5,255,202,22,5,255,207,28,7,
255,207,35,10,255,207,44,14,255,212,55,19,255,216,68,24,255,221,82,33,255,227,
98,42,255,233,116,54,255,247,132,62,255,138,53,18,200,0,0,0,118,0,0,0,96,12,2,
0,101,49,25,10,151,65,37,18,154,75,44,22,196,75,43,22,178,64,33,15,43,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,214,26,0,33,220,43,0,246,
221,43,0,255,220,32,0,255,222,35,0,255,223,35,0,255,223,35,0,255,222,34,0,255,
221,32,0,255,219,31,0,255,217,28,0,255,215,26,0,255,211,24,0,255,210,21,0,255,
203,17,0,255,174,16,1,255,196,19,2,255,205,25,6,255,208,27,7,255,200,25,6,255,
179,24,6,255,199,36,10,255,210,49,16,255,214,59,21,255,218,73,27,255,224,88,36,
255,230,104,46,255,236,122,57,255,243,129,60,255,103,32,9,186,0,0,0,110,0,0,0,
64,17,5,1,39,12,2,0,79,7,1,0,88,21,6,1,78,33,12,4,148,42,18,6,155,58,28,12,111,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,210,26,0,1,214,35,0,202,218,42,
1,255,216,30,0,255,217,30,0,255,217,30,0,255,221,29,0,255,224,29,0,255,222,28,
0,255,215,26,0,255,213,24,0,255,210,22,0,255,208,20,0,255,206,18,0,255,199,14,
0,255,169,13,1,255,191,15,3,255,207,25,7,255,191,26,7,255,76,6,1,255,10,2,0,
255,128,28,8,255,218,55,19,255,216,65,24,255,221,79,31,255,226,95,40,255,233,
112,51,255,240,129,62,255,235,118,52,255,75,17,3,170,0,0,0,97,0,0,0,45,4,0,0,2,
36,16,5,1,42,19,7,8,34,15,5,3,255,254,254,0,21,5,1,2,46,21,8,12,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,212,29,1,157,215,38,1,255,211,
28,0,255,212,26,0,255,216,26,0,255,192,26,1,255,130,25,4,255,161,21,1,255,213,
22,0,255,209,21,0,255,206,19,0,255,203,17,0,255,202,15,1,255,196,12,1,255,165,
10,1,255,188,14,3,255,210,26,7,255,118,13,2,255,0,3,0,255,51,22,8,255,124,40,
16,255,218,60,21,255,218,72,27,255,223,86,35,255,229,102,45,255,235,119,56,255,
245,136,66,255,208,94,37,244,39,3,0,150,4,0,0,84,0,0,0,32,4,0,0,1,22,7,1,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,171,21,2,80,212,33,2,255,208,26,
1,255,208,21,0,255,206,23,1,255,104,32,11,255,46,25,10,255,29,15,5,255,142,14,
1,255,210,18,0,255,202,16,1,255,200,14,1,255,199,13,2,255,194,12,1,255,163,9,
0,255,188,16,3,255,209,26,7,255,130,18,4,255,40,21,7,255,90,44,21,255,153,59,
27,255,221,66,24,255,221,80,32,255,226,94,40,255,232,110,50,255,238,128,62,255,
249,135,64,255,149,53,17,217,4,0,0,129,7,0,0,70,0,0,0,21,12,3,0,0,15,4,0,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,109,13,2,8,192,22,2,224,204,21,
1,255,203,18,1,255,200,20,1,255,100,32,12,255,57,27,10,255,26,16,5,255,82,10,
2,255,205,15,1,255,199,13,2,255,197,13,2,255,197,14,3,255,194,14,2,255,162,10,
1,255,191,20,5,255,205,30,8,255,192,35,10,255,116,39,16,255,134,59,29,255,199,
67,27,255,221,75,29,255,224,89,37,255,230,104,46,255,236,120,56,255,242,136,67,
255,236,119,52,254,86,21,5,184,7,0,0,108,4,0,0,53,0,0,0,10,4,0,0,0,0,0,0,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,141,11,1,133,197,
16,2,255,196,17,2,255,202,16,1,255,170,20,4,255,94,24,8,255,88,16,4,255,157,12,
2,255,200,14,2,255,196,15,3,255,197,17,3,255,199,20,4,255,193,18,3,255,159,10,
1,255,192,25,6,255,204,36,10,255,210,44,14,255,211,52,18,255,213,62,22,255,
220,72,27,255,222,85,34,255,228,99,42,255,233,114,53,255,238,129,62,255,249,137,
65,255,180,77,28,232,19,0,0,146,19,2,0,84,4,0,0,33,4,0,0,2,4,0,0,0,4,0,0,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,102,7,0,37,170,13,
2,240,196,16,3,255,194,16,3,255,199,15,3,255,196,15,3,255,200,16,3,255,202,16,
3,255,197,18,4,255,199,20,4,255,200,22,5,255,201,26,7,255,192,21,5,255,155,10,
1,255,192,28,7,255,207,43,13,255,210,52,17,255,214,61,22,255,218,70,27,255,
221,82,33,255,227,95,40,255,232,109,49,255,236,124,59,255,242,132,63,255,235,
115,49,254,87,23,6,187,15,0,0,115,22,4,0,58,7,0,0,14,4,0,0,0,4,0,0,0,4,0,0,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,94,6,0,0,103,
7,1,139,191,18,4,255,194,20,4,255,196,20,4,255,198,21,5,255,198,22,5,255,199,
23,5,255,200,24,6,255,201,26,6,255,202,29,8,255,204,32,9,255,193,25,6,255,154,
12,1,255,195,35,9,255,210,52,17,255,214,62,22,255,217,71,27,255,221,81,33,255,
225,93,39,255,230,107,48,255,236,120,56,255,239,129,61,255,246,122,53,255,151,
54,18,220,12,0,0,139,26,6,1,82,29,6,1,30,4,0,0,2,4,0,0,0,4,0,0,0,4,0,0,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,115,8,0,0,81,4,0,
36,124,12,2,204,199,24,6,255,195,25,6,255,198,27,7,255,200,28,7,255,200,30,8,
255,202,31,8,255,203,33,9,255,204,36,10,255,207,41,13,255,196,32,8,255,158,15,2,
255,200,42,13,255,214,61,22,255,218,73,27,255,221,82,33,255,225,93,40,255,230,
106,47,255,234,117,55,255,238,124,57,255,244,116,48,255,188,70,24,238,37,3,0,
162,17,1,0,106,40,11,2,52,28,3,0,9,10,2,0,0,12,3,0,0,12,3,0,0,12,3,0,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,112,7,1,0,110,7,1,0,49,
2,0,89,140,18,4,222,202,31,8,255,196,31,8,255,200,34,9,255,202,37,11,255,204,
39,11,255,205,42,13,255,207,46,14,255,209,51,17,255,197,38,10,255,157,15,2,255,
200,44,13,255,215,69,25,255,222,85,34,255,226,95,41,255,230,105,47,255,233,113,
51,255,234,112,48,255,239,101,37,255,199,66,20,243,57,8,1,174,7,0,0,121,29,8,1,
74,47,10,1,22,12,0,0,0,7,3,0,0,10,3,0,0,10,3,0,0,10,3,0,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,113,9,1,0,116,9,1,0,97,8,1,19,
31,2,0,126,145,23,5,223,203,37,10,255,200,38,11,255,200,41,13,255,204,46,14,
255,207,51,17,255,210,56,19,255,212,60,21,255,196,41,11,255,155,15,2,255,200,46,
12,255,217,77,30,255,225,95,40,255,227,100,42,255,229,101,42,255,232,98,37,255,
237,89,29,255,192,57,15,241,65,10,2,180,4,0,0,130,19,4,0,91,47,12,2,40,33,3,0,3,
7,4,0,0,10,4,0,0,10,4,0,0,10,4,0,0,10,4,0,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,114,11,2,0,114,11,2,0,118,12,2,0,81,7,1,40,12,
1,0,131,117,19,4,200,192,38,11,252,202,41,12,255,200,44,13,255,203,50,16,255,
207,58,20,255,210,62,22,255,193,39,11,255,154,17,2,255,204,50,13,255,217,74,26,
255,221,81,30,255,224,81,27,255,233,84,27,255,229,79,23,255,161,45,11,226,47,6,
1,171,7,0,0,132,15,2,0,99,42,12,2,52,34,5,0,9,0,1,0,0,10,4,0,0,10,4,0,0,10,4,
0,0,10,4,0,0,10,4,0,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,115,13,2,0,115,13,2,0,115,13,2,0,119,14,3,0,78,8,1,49,0,0,0,123,59,7,
1,165,145,25,6,222,186,36,9,252,202,43,11,255,203,46,13,255,205,51,14,255,187,
35,8,255,149,17,3,255,211,51,13,255,221,66,19,255,228,71,20,255,222,70,19,255,
184,55,14,238,99,22,5,197,22,1,0,154,10,0,0,128,15,1,0,100,39,11,1,55,29,6,0,12,
4,0,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,115,13,2,0,115,13,2,0,115,
13,2,0,115,13,2,0,116,16,3,0,77,10,1,42,10,0,0,112,0,0,0,137,61,8,1,169,120,21,
5,208,149,29,7,228,175,40,10,242,177,36,9,249,154,25,5,249,188,50,13,244,170,
50,14,232,144,39,10,220,91,19,4,195,29,2,0,162,10,0,0,137,7,0,0,118,17,3,0,93,
43,12,1,49,34,6,0,10,4,0,0,0,7,1,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,
0,0,10,2,0,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
115,13,2,0,115,13,2,0,115,13,2,0,115,13,2,0,113,15,3,0,100,15,3,0,85,14,3,25,42,
5,0,90,0,0,0,127,0,0,0,136,12,0,0,143,31,3,0,154,47,7,1,162,53,8,1,163,37,4,0,
159,22,1,0,154,12,0,0,148,12,0,0,138,10,0,0,124,10,1,0,107,28,8,1,79,43,11,2,38,
37,6,0,6,12,1,0,0,7,2,0,0,7,1,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,
10,2,0,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,115,
13,2,0,115,13,2,0,115,13,2,0,115,13,2,0,113,15,3,0,96,14,3,0,97,17,3,0,95,18,4,
2,68,12,2,40,40,6,1,86,12,1,0,112,0,0,0,120,0,0,0,123,0,0,0,123,0,0,0,123,4,0,
0,121,7,0,0,115,15,3,0,102,31,7,0,79,45,10,1,47,40,9,1,18,21,2,0,1,15,3,0,0,
15,3,0,0,7,2,0,0,7,1,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,115,13,2,0,
115,13,2,0,115,13,2,0,115,13,2,0,113,15,3,0,96,14,3,0,95,16,3,0,94,18,4,0,86,18,
4,0,83,15,3,0,75,12,3,18,64,12,3,43,50,13,3,61,49,14,3,69,43,12,2,69,33,7,1,
60,45,10,1,46,49,8,1,28,47,7,0,11,33,2,0,1,7,2,0,0,7,2,0,0,17,3,0,0,15,3,0,0,7,
2,0,0,7,1,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,115,13,2,0,115,13,2,0,
115,13,2,0,115,13,2,0,113,15,3,0,96,14,3,0,95,16,3,0,94,18,4,0,84,17,4,0,80,13,
3,0,83,7,2,0,90,12,5,0,100,34,18,0,141,89,53,0,103,47,22,0,21,3,0,1,28,3,0,0,
26,0,0,0,10,0,0,0,4,0,0,0,7,3,0,0,10,2,0,0,17,3,0,0,15,3,0,0,7,2,0,0,7,1,0,0,
10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,10,2,0,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,
254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,
255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,254,0,255,254,
254,0};
static Fl_RGB_Image image_bug(idata_bug, 48, 48, 4, 0);
#endif

View File

@ -0,0 +1,165 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdlib.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <edelib/Debug.h>
#include <edelib/String.h>
#include "Bugzilla.h"
EDELIB_NS_USING(String)
/* must be static; don't ask me why */
static struct xmlrpc_clientparms gparms;
static struct xmlrpc_curl_xportparms gparms_curl;
struct BugzillaData {
xmlrpc_env xenv;
xmlrpc_client *xcli;
String url;
};
BugzillaData *bugzilla_new(const char *u) {
BugzillaData *data = new BugzillaData;
xmlrpc_env_init(&data->xenv);
xmlrpc_client_setup_global_const(&data->xenv);
data->url = u;
/*
* to allow https connections; curl by default refuse connections without valid certificate
* (at least docs says that ;))
*/
gparms_curl.no_ssl_verifypeer = 1;
gparms_curl.no_ssl_verifyhost = 1;
/* only curl transport is supported */
gparms.transport = "curl";
gparms.transportparmsP = &gparms_curl;
xmlrpc_client_create(&data->xenv, XMLRPC_CLIENT_NO_FLAGS, "ede-bug-report", "0.1", &gparms, sizeof(gparms), &data->xcli);
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to init xmlrpc client data (%s)\n", data->xenv.fault_string);
delete data;
data = NULL;
}
return data;
}
void bugzilla_free(BugzillaData *data) {
if(data == NULL)
return;
xmlrpc_client_destroy(data->xcli);
xmlrpc_env_clean(&data->xenv);
delete data;
}
char *bugzilla_get_version(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_value *result;
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bugzilla.version", &result, "()");
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to call xmlrpc function (%s)\n", data->xenv.fault_string);
return "";
}
/* this value will be malloc()-ated by xmlrpc_decompose_value() and should be freeed by user */
char *ret;
xmlrpc_decompose_value(&data->xenv, result, "{s:s,*}", "version", &ret);
xmlrpc_DECREF(result);
return ret;
}
int bugzilla_login(BugzillaData *data, const char *user, const char *passwd) {
E_ASSERT(data != NULL);
xmlrpc_value *result;
int remember = 0; /* remember login data */
int id = -1; /* bugzilla user id */
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "User.login", &result,
"({s:s,s:s,s:b})",
"login", user,
"password", passwd,
"remember", remember);
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to perform login function (%s)\n", data->xenv.fault_string);
return id;
}
xmlrpc_decompose_value(&data->xenv, result, "{s:i,*}", "id", &id);
xmlrpc_DECREF(result);
return id;
}
void bugzilla_logout(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_value *result;
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "User.logout", &result, "()");
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to call xmlrpc function (%s)\n", data->xenv.fault_string);
return;
}
xmlrpc_DECREF(result);
}
int bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity)
{
E_ASSERT(data != NULL);
int bug_id = -1;
xmlrpc_value *result;
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result,
"({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
"product", product,
"component", component,
"summary", summary,
"version", version,
"description", description,
"op_sys", op_sys,
"platform", platform,
"priority", priority,
"severity", severity);
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to perform submit function (%s)\n", data->xenv.fault_string);
return bug_id;
}
xmlrpc_decompose_value(&data->xenv, result, "{s:i,*}", "id", &bug_id);
xmlrpc_DECREF(result);
return bug_id;
}

View File

@ -0,0 +1,38 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLA_H__
#define __BUGZILLA_H__
struct BugzillaData;
BugzillaData *bugzilla_new(const char *url);
void bugzilla_free(BugzillaData *data);
/* return bugzilla version or empty string if fails; returned value must be free()-ed */
char *bugzilla_get_version(BugzillaData *data);
/* return user id or -1 if fails */
int bugzilla_login(BugzillaData *data, const char *user, const char *passwd);
void bugzilla_logout(BugzillaData *data);
/* return bug id or -1 if fails */
int bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity);
#endif

View File

@ -0,0 +1,301 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* used from local xmlrpc-c source */
#include <pthreadx.h>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl.H>
#include <edelib/Nls.h>
#include <edelib/MessageBox.h>
#include <edelib/String.h>
#include "PulseProgress.h"
#include "BugzillaSender.h"
#include "Bugzilla.h"
#define EDE_BUGZILLA_XMLRPC_URL "http://bugs.equinox-project.org/xmlrpc.cgi"
/* must match to existing user */
#define EDE_BUGZILLA_USER "ede-bugs@lists.sourceforge.net"
#define EDE_BUGZILLA_PASS "edebugs2709"
#define PROGRESS_STEP_REFRESH 0.06
/* message length without '\n' */
#define REPORT_STR_LEN 1024
EDELIB_NS_USING(alert)
EDELIB_NS_USING(message)
EDELIB_NS_USING(String)
/* for easier passing it to the thread */
struct BugContent {
const char *bug_title;
const char *bug_content;
};
static Fl_Double_Window *win;
static PulseProgress *progress;
static BugzillaData *bdata;
static bool data_submitted;
/* we use only one additional thread */
static int report_pipe[2];
static pthread_mutex_t runner_mutex;
/* to prevent sending data; shared between threads */
static bool cancel_sending;
static void write_string(int fd, const char *str) {
int len = strlen(str);
if(len > REPORT_STR_LEN)
len = REPORT_STR_LEN;
::write(fd, str, len);
::write(fd, "\n", 1);
}
/* these are messages prepended with 'FAILED' so we knows how error was emited */
static void write_string_fail(int fd, const char *str) {
int len = strlen(str);
if(len > REPORT_STR_LEN) {
/* our max message size sans 'FAILED' header */
len = REPORT_STR_LEN - 6;
}
::write(fd, "FAILED", 6);
::write(fd, str, len);
::write(fd, "\n", 1);
}
static int read_string(int fd, String& ret) {
char c;
char buf[REPORT_STR_LEN];
int i, nc;
memset(buf, 0, sizeof(buf));
i = 0;
nc = ::read(fd, &c, 1);
while(nc > 0 && c != '\n' && i < REPORT_STR_LEN) {
buf[i] = c;
i = i + nc;
nc = ::read(fd, &c, 1);
}
buf[i] = '\0';
ret = buf;
return i;
}
static void cancel_cb(Fl_Widget*, void*) {
/*
* XXX: we must not use win->hide() here, mostly due sucky xmlrpc-c design. When window
* is going to be closed, but we still have pending RPC connections, we will get assertion from
* xmlrpc-c. To prevent that, we will change cancel_state and hope thread will catch it before
* bugzilla_submit_bug() is called. If it was called, we can't do anything about it, because data
* is already send to Bugzilla so we can only log out from it.
*
* Alternative (and crude) solution would be to comment assertion check xmlrpc_curl_transport.c (977)
* and leave cleaning stuff to the kernel.
*/
pthread_mutex_lock(&runner_mutex);
cancel_sending = true;
pthread_mutex_unlock(&runner_mutex);
}
static void progress_timeout(void*) {
progress->step();
Fl::repeat_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
}
static void clear_timeouts(void) {
Fl::remove_timeout(progress_timeout);
}
static void report_pipe_cb(int fd, void *) {
String s;
if(read_string(report_pipe[0], s) <= 0)
return;
/* check if the message started with 'FAILED' and see it as error */
if(strncmp(s.c_str(), "FAILED", 6) == 0) {
win->hide();
const char *str = s.c_str();
str += 6; /* do not show our header */
alert(str);
}
progress->copy_label(s.c_str());
/* marked as completed successfully */
if(s == "DONE") {
win->hide();
message(_("The report was sent successfully. Thank you for your contribution"));
/* the only case when data was submitted correctly */
data_submitted = true;
return;
}
/* marked as canceled */
if(s == "CANCELED")
win->hide();
}
static void* thread_worker(void *d) {
int ret;
BugContent *data = (BugContent*)d;
bool should_cancel;
ret = bugzilla_login(bdata, EDE_BUGZILLA_USER, EDE_BUGZILLA_PASS);
if(ret == -1) {
write_string_fail(report_pipe[1], _("Unable to properly login. Probably the host is temporarily down or your are not connected to the internet"));
goto done;
}
/* wait some time if user decided to press 'Cancel' */
sleep(1);
pthread_mutex_lock(&runner_mutex);
should_cancel = cancel_sending;
pthread_mutex_unlock(&runner_mutex);
if(should_cancel) {
write_string(report_pipe[1], "CANCELED");
goto done;
}
write_string(report_pipe[1], _("Submitting the report..."));
ret = bugzilla_submit_bug(bdata,
"ede",
"general",
data->bug_title,
"unspecified",
data->bug_content,
"All",
"All",
"P5",
"normal");
if(ret == -1) {
write_string_fail(report_pipe[1], _("Unable to properly submit the data. Please try again"));
goto done;
}
write_string(report_pipe[1], _("Logging out..."));
bugzilla_logout(bdata);
write_string(report_pipe[1], "DONE");
done:
delete data;
pthread_exit(NULL);
/* shutup compiler */
return NULL;
}
static void perform_send(const char *title, const char *content) {
pthread_t thread;
/*
* Must be allocated since this function could quit before thread was created
* of before thread could acceess the arguments. Freeing is done in that thread.
*/
BugContent *c = new BugContent;
c->bug_title = title;
c->bug_content = content;
/* Create joinable thread. Some implementations prefer this explicitly was set. */
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int rc = pthread_create(&thread, &attr, thread_worker, (void*)c);
if(rc) {
alert(_("Unable to create additional thread"));
/* close everything */
win->hide();
}
pthread_attr_destroy(&attr);
}
bool bugzilla_send_with_progress(const char *title, const char *content) {
data_submitted = false;
cancel_sending = false;
bdata = bugzilla_new(EDE_BUGZILLA_XMLRPC_URL);
if(!bdata) {
alert(_("Unable to initialize bugzilla interface!"));
return false;
}
if(pipe(report_pipe) != 0) {
alert(_("Unable to initialize communication pipe"));
return false;
}
/* prepare mutex */
pthread_mutex_init(&runner_mutex, NULL);
/* register our callback on pipe */
Fl::add_fd(report_pipe[0], FL_READ, report_pipe_cb);
win = new Fl_Double_Window(275, 90, _("Sending report data"));
win->begin();
progress = new PulseProgress(10, 20, 255, 25, _("Sending report..."));
progress->selection_color((Fl_Color)137);
Fl_Button *cancel = new Fl_Button(175, 55, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
win->end();
win->set_modal();
win->show();
progress->label(_("Preparing data..."));
Fl::add_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
perform_send(title, content);
while(win->shown())
Fl::wait();
/* clear pipe callback */
Fl::remove_fd(report_pipe[0]);
clear_timeouts();
pthread_mutex_destroy(&runner_mutex);
close(report_pipe[0]);
close(report_pipe[1]);
bugzilla_free(bdata);
/* true if we completed all stages */
return data_submitted;
}

View File

@ -0,0 +1,18 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLASENDER_H__
#define __BUGZILLASENDER_H__
bool bugzilla_send_with_progress(const char *title, const char *content);
#endif

View File

@ -0,0 +1,120 @@
#
# $Id$
#
# Part of Equinox Desktop Environment (EDE).
# Copyright (c) 2009 EDE Authors.
#
# This program is licensed under terms of the
# GNU General Public License version 2 or newer.
# See COPYING for details.
SubDir TOP ede-bug-report ;
# needed paths
XMLRPC_C_SRC_PATH = [ FDirName $(TOP) ede-bug-report xmlrpc-c ] ;
XMLRPC_C_TOP = $(XMLRPC_C_SRC_PATH) ;
XMLRPC_C_LIB_DIR = [ FDirName $(XMLRPC_C_SRC_PATH) lib ] ;
XMLRPC_C_FLAGS =
-I$(XMLRPC_C_SRC_PATH)
-I [ FDirName $(XMLRPC_C_SRC_PATH) include ]
-I [ FDirName $(XMLRPC_C_SRC_PATH) deps util include ]
-I [ FDirName $(XMLRPC_C_SRC_PATH) deps expat xmlparse ]
-I [ FDirName $(XMLRPC_C_SRC_PATH) deps expat xmltok ] ;
# ede-bug-report related builds
SOURCE = Bugzilla.cpp BugzillaSender.cpp PulseProgress.cpp ede-bug-report.cpp ;
BINARY = ede-bug-report ;
ObjectC++Flags $(SOURCE) : $(WNO_LONG_LONG) $(XMLRPC_C_FLAGS) $(CURL_CFLAGS) ;
EdeProgram $(BINARY) : $(SOURCE) ;
TranslationStrings locale : $(SOURCE) ;
# link against xmlrpc-c libraries
LinkAgainst $(BINARY) : -L$(XMLRPC_C_LIB_DIR)
-lxmlrpc_local
-lcurl_transport_local
-lxmlrpc_util_local
-lxmlrpc_obj_local
-lxmlparse_local
-lxmltok_local
$(CURL_LIBS)
$(PTHREAD_CFLAGS)
$(PTHREAD_LIBS) ;
# xmlrpc-c related builds
rule XmlrpcLibrary {
local lib = [ FDirName $(XMLRPC_C_LIB_DIR) $(<) ] ;
# compile it with OPTIMFLAGS got from top Jamconfig
ObjectCcFlags $(>) : $(XMLRPC_C_FLAGS) $(OPTIMFLAGS) ;
StaticLibrary $(lib) : $(>) ;
# make sure libraries are build first
LocalDepends $(BINARY) : $(lib:S=$(SUFLIB)) ;
}
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) src ] ;
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) deps util ] ;
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) deps libutil ] ;
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) deps curl-transport ] ;
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) deps expat xmlparse ] ;
SEARCH_SOURCE += [ FDirName $(XMLRPC_C_SRC_PATH) deps expat xmltok ] ;
XMLRPC_C_SRC =
double.c
parse_value.c
resource.c
trace.c
version.c
xmlrpc_data.c
xmlrpc_datetime.c
xmlrpc_string.c
xmlrpc_array.c
xmlrpc_struct.c
xmlrpc_build.c
xmlrpc_decompose.c
xmlrpc_parse.c
xmlrpc_serialize.c
xmlrpc_base64.c
xmlrpc_authcookie.c
xmlrpc_client.c
xmlrpc_client_global.c
xmlrpc_expat.c
xmlrpc_server_info.c ;
ObjectCcFlags $(XMLRPC_C_SRC) : -DMUST_BUILD_CURL_CLIENT ;
CURL_TRANSPORT_SRC =
xmlrpc_curl_transport.c
curltransaction.c
curlmulti.c
lock_pthread.c ;
UTIL_SRC =
casprintf.c
cmdline_parser.c
getoptx.c
string_parser.c
stripcaseeq.c ;
LIBUTIL_SRC =
asprintf.c
error.c
make_printable.c
memblock.c
select.c
sleep.c
time.c
utf8.c ;
XMLPARSE_SRC = xmlparse.c ;
XMLTOK_SRC = xmltok.c xmlrole.c ;
XmlrpcLibrary libxmlrpc_local : $(XMLRPC_C_SRC) ;
XmlrpcLibrary libxmlrpc_obj_local : $(UTIL_SRC) ;
XmlrpcLibrary libxmlrpc_util_local : $(LIBUTIL_SRC) ;
XmlrpcLibrary libxmlparse_local : $(XMLPARSE_SRC) ;
XmlrpcLibrary libxmltok_local : $(XMLTOK_SRC) ;
XmlrpcLibrary libcurl_transport_local : $(CURL_TRANSPORT_SRC) ;

View File

@ -0,0 +1,93 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <FL/Fl_Double_Window.H>
#include <FL/Fl.H>
#include <stdio.h>
#include <FL/fl_draw.H>
#include "PulseProgress.h"
PulseProgress::PulseProgress(int x, int y, int w, int h, const char *l) :
Fl_Widget(x, y, w, h, l), cprogress(0), blen(40), slen(5)
{
box(FL_DOWN_BOX);
color(FL_BACKGROUND_COLOR, (Fl_Color)146);
/* show it at the beginning */
cprogress += blen;
}
void PulseProgress::draw(void) {
int bx, by, bw, bh;
int xoff, yoff, woff, hoff;
bx = Fl::box_dx(box());
by = Fl::box_dy(box());
bw = Fl::box_dw(box());
bh = Fl::box_dh(box());
xoff = x() + bx;
yoff = y() + by;
woff = w() - bw;
hoff = h() - bh;
draw_box(box(), x(), y(), w(), h(), color());
fl_clip(xoff, yoff, woff, hoff);
Fl_Color c = fl_color();
fl_color(color2());
if(cprogress >= woff) {
/* reverse it */
cprogress = -cprogress;
} else if(cprogress == -blen) {
/* start again after reverse */
cprogress = blen;
}
if(cprogress > 0)
fl_rectf(xoff - blen + cprogress, yoff, blen, hoff);
else
fl_rectf(xoff - blen - cprogress, yoff, blen, hoff);
fl_color(c);
fl_pop_clip();
draw_label(x() + bx, y() + by, w() - bw, h() - bh);
}
void PulseProgress::step(void) {
cprogress += slen;
redraw();
}
#if 0
static PulseProgress *pp;
void cb(void *) {
pp->step();
Fl::repeat_timeout(0.06, cb);
}
int main() {
Fl_Double_Window *win = new Fl_Double_Window(300, 300);
win->begin();
pp = new PulseProgress(10, 10, 200, 25, "Sending report...");
win->end();
win->show();
Fl::add_timeout(0.06, cb);
return Fl::run();
}
#endif

View File

@ -0,0 +1,42 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __PULSEPROGRESS_H__
#define __PULSEPROGRESS_H__
#include <FL/Fl_Widget.H>
class PulseProgress : public Fl_Widget {
private:
int cprogress; /* current progress */
int blen; /* bar length */
int slen; /* step length */
protected:
void draw(void);
public:
PulseProgress(int x, int y, int w, int h, const char *l = 0);
void bar_len(int l) { blen = l; }
int bar_len(void) { return blen; }
void step_len(int l) { slen = l; }
int step_len(void) { return slen; }
void step(void);
void restart(void) { cprogress = 0; }
};
#endif

View File

@ -0,0 +1,208 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdlib.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <edelib/Debug.h>
#include <edelib/String.h>
#include "Bugzilla.h"
EDELIB_NS_USING(String)
#define CLIENT_NAME "ede-bug-report"
#define CLIENT_VERSION "0.1"
/* must be static; don't ask me why */
static struct xmlrpc_clientparms gparms;
struct BugzillaData {
xmlrpc_env xenv;
xmlrpc_client *xcli;
String url;
IdResponseCallback id_response_cb;
VersionResponseCallback version_response_cb;
void *cb_data;
};
static void _logout_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
/* do nothing */
}
static void _version_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
BugzillaData *data = (BugzillaData *)user_data;
if(faultp->fault_occurred) {
if(data->version_response_cb) {
/* do callback with error */
(*data->version_response_cb)(NULL, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
return;
}
char *tmp;
xmlrpc_decompose_value(&data->xenv, result, "{s:s,*}", "version", &tmp);
if(data->version_response_cb) {
/* do callback with values */
(*data->version_response_cb)(tmp, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
/* xmlrpc_decompose_value() allocates returned string value */
free(tmp);
}
static void _id_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
BugzillaData *data = (BugzillaData *)user_data;
if(faultp->fault_occurred) {
if(data->id_response_cb) {
/* do callback with error */
(*data->id_response_cb)(-1, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
return;
}
int id;
xmlrpc_decompose_value(&data->xenv, result, "{s:i,*}", "id", &id);
if(data->id_response_cb) {
/* do callback with values */
(*data->id_response_cb)(id, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
}
BugzillaData *bugzilla_new(const char *u) {
BugzillaData *data = new BugzillaData;
xmlrpc_env_init(&data->xenv);
xmlrpc_client_setup_global_const(&data->xenv);
data->url = u;
/* only cURL transport is supported */
gparms.transport = "curl";
xmlrpc_client_create(&data->xenv, XMLRPC_CLIENT_NO_FLAGS, CLIENT_NAME, CLIENT_VERSION,
&gparms, sizeof(gparms), &data->xcli);
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to init xmlrpc client data (%s)\n", data->xenv.fault_string);
delete data;
data = NULL;
}
/* nullify callback stuff */
data->id_response_cb = NULL;
data->version_response_cb = NULL;
data->cb_data = NULL;
return data;
}
void bugzilla_free(BugzillaData *data) {
if(data == NULL)
return;
xmlrpc_client_destroy(data->xcli);
xmlrpc_env_clean(&data->xenv);
delete data;
}
void bugzilla_set_id_response_callback(BugzillaData *data, IdResponseCallback cb) {
E_ASSERT(data != NULL);
data->id_response_cb = cb;
}
void bugzilla_set_version_response_callback(BugzillaData *data, VersionResponseCallback cb) {
E_ASSERT(data != NULL);
data->version_response_cb = cb;
}
void bugzilla_set_callback_data(BugzillaData *data, void *param) {
E_ASSERT(data != NULL);
data->cb_data = param;
}
void bugzilla_event_loop_finish_timeout(BugzillaData *data, unsigned long ms) {
E_ASSERT(data != NULL);
xmlrpc_client_event_loop_finish_timeout(data->xcli, ms);
}
void bugzilla_event_loop_finish(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_event_loop_finish(data->xcli);
}
void bugzilla_get_version(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"Bugzilla.version",
_version_response_handler, data, "()");
}
void bugzilla_login(BugzillaData *data, const char *user, const char *passwd) {
E_ASSERT(data != NULL);
const int remember = 0; /* remember login data */
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"User.login",
_id_response_handler, data,
"({s:s,s:s,s:b})",
"login", user,
"password", passwd,
"remember", remember);
}
void bugzilla_logout(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"User.logout", _logout_response_handler, NULL, "()");
}
void bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity)
{
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"Bug.create",
_id_response_handler, data,
"({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
"product", product,
"component", component,
"summary", summary,
"version", version,
"description", description,
"op_sys", op_sys,
"platform", platform,
"priority", priority,
"severity", severity);
}

View File

@ -0,0 +1,70 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLA_H__
#define __BUGZILLA_H__
/*
* This is asynchronous Bugzilla interface (xmlrpc calls to Bugzilla installation). This means
* that all calls will be processed without blocking and all results will be reported via callbacks.
*
* To keep things simple, we have two type of callbacks, IdResponseCallback and VersionResponseCallback.
* VersionResponseCallback will be called when request is sent via bugzilla_get_version() and
* IdResponseCallback when bugzilla_login() and bugzilla_submit_bug(). In first case, we will get
* user ID or -1 (and set errnum > 0 and err != NULL) if user does not exists or something was wrong
* with the connection. bugzilla_submit_bug() behaves the same, except it returns bug ID if bug was
* created successfully.
*
* Callbacks are sev bia bugzilla_set_id_response_callback() and bugzilla_set_version_response_callback()
* and data passed to the callback is done via bugzilla_set_callback_data().
*
* The reason why IdResponseCallback was used for both bugzilla_login() and bugzilla_submit_bug()
* is because both mark returned values as 'id' and to not clutter things with callbacks types such
* as BugIdResponseCallback or LoginIdResponse-bla-bla... you get it :)
*/
struct BugzillaData;
typedef void (*IdResponseCallback)(int, void *data, int errnum, const char *err);
typedef void (*VersionResponseCallback)(const char *, void *data, int errnum, const char *err);
BugzillaData *bugzilla_new(const char *url);
void bugzilla_free(BugzillaData *data);
/* callbacks when response arrives */
void bugzilla_set_id_response_callback(BugzillaData *data, IdResponseCallback cb);
void bugzilla_set_version_response_callback(BugzillaData *data, VersionResponseCallback cb);
/* data sent to callbacks */
void bugzilla_set_callback_data(BugzillaData *data, void *param);
void bugzilla_event_loop_finish_timeout(BugzillaData *data, unsigned long ms);
void bugzilla_event_loop_finish(BugzillaData *data);
/* get bugzilla version; VersionResponseCallback will be called */
void bugzilla_get_version(BugzillaData *data);
/* login to bugzilla instance; IdResponseCallback will be called */
void bugzilla_login(BugzillaData *data, const char *user, const char *passwd);
void bugzilla_logout(BugzillaData *data);
/* submit bug (must be logged); retuned bug id will be reported via IdResponseCallback */
void bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity);
#endif

View File

@ -0,0 +1,177 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdio.h>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl.H>
#include <edelib/Nls.h>
#include <edelib/MessageBox.h>
#include "PulseProgress.h"
#include "BugzillaSender.h"
#include "Bugzilla.h"
#define EDE_BUGZILLA_URL "http://bugs.equinox-project.org"
#define EDE_BUGZILLA_XMLRPC_URL "http://bugs.equinox-project.org/xmlrpc.cgi"
/* must match to existing user */
#define EDE_BUGZILLA_USER "ede-bugs@lists.sourceforge.net"
#define EDE_BUGZILLA_PASS "edebugs2709"
#define PROGRESS_STEP_REFRESH 0.06
EDELIB_NS_USING(alert)
enum {
STATE_NEXT = 1,
STATE_LOGIN,
STATE_LOGOUT,
STATE_DONE
};
struct ResponseParams {
int working_state;
const char *bug_title;
const char *bug_content;
};
static Fl_Double_Window *win;
static PulseProgress *progress;
static BugzillaData *bdata;
static void xmlrpc_request_timeout(void*) {
bugzilla_event_loop_finish_timeout(bdata, 20);
/* repeat this function so all pending RPC requests are processed */
Fl::repeat_timeout(0.5, xmlrpc_request_timeout);
}
static void progress_timeout(void*) {
progress->step();
Fl::repeat_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
}
static void clear_timeouts(void) {
Fl::remove_timeout(xmlrpc_request_timeout);
Fl::remove_timeout(progress_timeout);
}
static void cancel_cb(Fl_Widget*, void*) {
win->hide();
}
static void _id_response_cb(int id, void *data, int errnum, const char *err) {
if(errnum) {
alert(_("Received bad response: (%i) : %s"), errnum, err);
/* close dialog */
cancel_cb(0, 0);
return;
}
ResponseParams *rparams = (ResponseParams*) data;
if(rparams->working_state == STATE_LOGIN) {
progress->label("Done. Submitting the data...");
printf("logged in as id: %i\n", id);
/* must match EDE Bugzilla server options */
bugzilla_submit_bug(bdata,
"ede",
"general",
rparams->bug_title,
"unspecified",
rparams->bug_content,
"All",
"All",
"P5",
"normal");
rparams->working_state += STATE_NEXT;
return;
}
if(rparams->working_state == STATE_LOGOUT) {
progress->label("Data sent successfully :). Clearing...");
puts("XXX");
bugzilla_logout(bdata);
rparams->working_state += STATE_NEXT;
return;
}
}
bool bugzilla_send_with_progress(const char *title, const char *content) {
/* used to simplify passing multiple data to the response callback */
ResponseParams rparams;
/*
* we maintain state so knows what we done, since our Bugzilla interface
* supports only one callback for ID's
*/
rparams.working_state = STATE_LOGIN;
rparams.bug_title = title;
rparams.bug_content = content;
bdata = bugzilla_new(EDE_BUGZILLA_XMLRPC_URL);
if(!bdata) {
alert(_("Unable to initialize bugzilla interface!"));
return false;
}
/* set callback and data */
bugzilla_set_id_response_callback(bdata, _id_response_cb);
bugzilla_set_callback_data(bdata, &rparams);
win = new Fl_Double_Window(275, 90, _("Sending report data"));
win->begin();
progress = new PulseProgress(10, 20, 255, 25, _("Sending report..."));
progress->selection_color((Fl_Color)137);
Fl_Button *cancel = new Fl_Button(175, 55, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
win->end();
win->set_modal();
win->show();
/*
* try to login; rest of the actions are done in _id_response_cb() due async stuff
* and since events are chained (you can't submit report until get logged in)
*/
progress->label("Logging in...");
bugzilla_login(bdata, EDE_BUGZILLA_USER, EDE_BUGZILLA_PASS);
/* timer for processing RPC requests */
Fl::add_timeout(0.5, xmlrpc_request_timeout);
Fl::add_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
while(win->shown())
Fl::wait();
/*
* make sure the timeout functions are removed because FLTK shares them between loops
* (or: as long as any loop is running, timeout callbacks will be triggered)
*/
clear_timeouts();
/* process all pending requests */
bugzilla_event_loop_finish(bdata);
bugzilla_free(bdata);
bdata = NULL;
/* true if we completed all stages */
return (rparams.working_state == STATE_DONE);
}

View File

@ -0,0 +1,18 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLASENDER_H__
#define __BUGZILLASENDER_H__
bool bugzilla_send_with_progress(const char *title, const char *content);
#endif

View File

@ -0,0 +1,181 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Text_Editor.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Button.H>
#include <edelib/Window.h>
#include <edelib/Nls.h>
#include <edelib/MessageBox.h>
#include <edelib/String.h>
#include <edelib/Regex.h>
#include <edelib/Debug.h>
#include "BugzillaSender.h"
#include "BugImage.h"
#include "icons/bug.xpm"
EDELIB_NS_USING(String)
EDELIB_NS_USING(Regex)
EDELIB_NS_USING(alert)
EDELIB_NS_USING(message)
EDELIB_NS_USING(RX_CASELESS)
static Fl_Input *bug_title_input;
static Fl_Input *email_input;
static Fl_Text_Buffer *text_buf;
/* check if string has spaces */
static bool empty_entry(const char *en) {
if(!en)
return true;
for(const char *p = en; *p; p++) {
if(*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
return false;
}
return true;
}
static bool valid_email(const char *e) {
Regex r;
/* regex stolen from http://www.regular-expressions.info/email.html */
if(!r.compile("\\b[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b", RX_CASELESS)) {
E_WARNING(E_STRLOC ": Unable to properly compile regex pattern");
return false;
}
return (r.match(e) > 0);
}
static void close_cb(Fl_Widget*, void *w) {
edelib::Window *win = (edelib::Window *)w;
win->hide();
}
static void send_cb(Fl_Widget*, void *w) {
const char *txt;
String title, content;
if(empty_entry(bug_title_input->value())) {
alert(_("Report title is missing"));
return;
}
if(empty_entry(email_input->value())) {
alert(_("Email address is missing"));
return;
}
txt = text_buf->text();
if(empty_entry(txt)) {
alert(_("Detail problem description is missing"));
free((void *) txt);
return;
}
if(!valid_email(email_input->value())) {
alert(_("Email address is invalid. Please use the valid email address"));
return;
}
/*
* construct a subject header, so we knows it came from report tool
* BRT - Bug Report Tool
*/
title = "[BRT] ";
title += bug_title_input->value();
/* reserve space for our content */
content.reserve(text_buf->length() + 128);
/* construct content with some header data */
content += "This issue was reported via EDE Bug Report Tool (BRT).\n\n";
content += "Reporter:\n";
content += email_input->value();
content += "\n\n";
content += "Detail description:\n";
content += txt;
free((void *) txt);
if(bugzilla_send_with_progress(title.c_str(), content.c_str()))
close_cb(0, w);
}
int main(int argc, char** argv) {
/* in case if debugger output was given */
const char *gdb_output = NULL;
if(argc == 3 && ((strcmp(argv[1], "--gdb-dump") == 0) || (strcmp(argv[1], "-g") == 0)))
gdb_output = argv[2];
edelib::Window *win = new edelib::Window(480, 365, _("EDE Bug Reporting Tool"));
win->begin();
Fl_Box *image_box = new Fl_Box(10, 10, 60, 59);
image_box->image(image_bug);
Fl_Box *title_box = new Fl_Box(80, 10, 390, 30, _("EDE Bug Reporting Tool"));
title_box->labelfont(1);
title_box->labelsize(14);
title_box->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
Fl_Box *description_box = new Fl_Box(80, 45, 390, 95, _("To help us to improve the future EDE versions, please describe the problem with much details as possible.\n\nNote: valid email address is required, so developers could contact you for more informations if necessary."));
description_box->align(133|FL_ALIGN_INSIDE);
bug_title_input = new Fl_Input(10, 165, 225, 25, _("Short and descriptive title:"));
bug_title_input->align(FL_ALIGN_TOP_LEFT);
email_input = new Fl_Input(240, 165, 230, 25, _("Your email address:"));
email_input->align(FL_ALIGN_TOP_LEFT);
Fl_Text_Editor* te = new Fl_Text_Editor(10, 215, 460, 105, _("Detail description of the problem:"));
te->align(FL_ALIGN_TOP_LEFT);
/* wrap length of the text */
te->wrap_mode(1, 80);
text_buf = new Fl_Text_Buffer();
te->buffer(text_buf);
if(gdb_output) {
if(text_buf->appendfile(gdb_output) == 0) {
text_buf->insert(0, "\nCollected data:\n");
text_buf->insert(0, "(please write additional comments here, removing this line)\n\n");
} else
E_WARNING(E_STRLOC ": Unable to read '%s' as debugger output. Continuing...\n");
}
Fl_Button *send = new Fl_Button(285, 330, 90, 25, _("&Send"));
send->callback(send_cb, win);
Fl_Button *close = new Fl_Button(380, 330, 90, 25, _("&Close"));
close->callback(close_cb, win);
win->window_icon(bug_xpm);
/* win->show(argc, argv); */
win->show();
return Fl::run();
}

View File

@ -0,0 +1,45 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0108
header_name {.h}
code_name {.cxx}
Function {} {open
} {
Fl_Window {} {
label {EDE Bug Reporting Tool} open
xywh {369 205 480 365} type Double visible
} {
Fl_Box {} {selected
image {../icons/bug.png} xywh {10 10 60 59}
}
Fl_Box {} {
label {EDE Bug Reporting Tool}
xywh {80 10 390 30} labelfont 1 labelsize 14 align 20
}
Fl_Box {} {
label {To help us to improve the future EDE versions, please describe the problem with much details as possible.
Note: valid email address is required, so developers could contact you for more informations if necessary.}
xywh {80 45 390 95} align 149
}
Fl_Input {} {
label {Short and descriptive title:}
xywh {10 165 225 25} align 5
}
Fl_Input {} {
label {Your email address:}
xywh {240 165 230 25} align 5
}
Fl_Text_Editor {} {
label {Detail description of the problem:}
xywh {10 215 460 105} align 5
}
Fl_Button {} {
label {&Send}
xywh {285 330 90 25}
}
Fl_Button {} {
label {&Cancel}
xywh {380 330 90 25}
}
}
}

View File

@ -0,0 +1,19 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0108
header_name {.h}
code_name {.cxx}
Function {} {open
} {
Fl_Window {} {open
xywh {389 409 275 90} type Double visible
} {
Fl_Progress {} {
label {Sending report...} selected
xywh {10 20 255 25} selection_color 137
}
Fl_Button {} {
label {&Cancel}
xywh {175 55 90 25}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,216 @@
/* XPM */
static char * bug_xpm[] = {
"22 22 191 2",
" c None",
". c #4C2C16",
"+ c #5D3C23",
"@ c #5E3D23",
"# c #41200E",
"$ c #59331B",
"% c #3C1E0D",
"& c #52311A",
"* c #59371F",
"= c #402310",
"- c #3C2313",
"; c #483220",
"> c #5F3A20",
", c #674D3A",
"' c #412B20",
") c #33170A",
"! c #3C1D0C",
"~ c #2C170B",
"{ c #36281C",
"] c #4E433C",
"^ c #4A3E35",
"/ c #593B21",
"( c #2D1909",
"_ c #CD3502",
": c #D97D3F",
"< c #D4CDBE",
"[ c #958577",
"} c #391E10",
"| c #230E05",
"1 c #17130C",
"2 c #2C2D25",
"3 c #835037",
"4 c #A43818",
"5 c #160802",
"6 c #593B1F",
"7 c #BA6D2B",
"8 c #FFBD3C",
"9 c #FB6B07",
"0 c #DD8D46",
"a c #D6C1B0",
"b c #574636",
"c c #0A0300",
"d c #140C07",
"e c #6D341E",
"f c #E34E24",
"g c #FD511E",
"h c #593720",
"i c #E3A968",
"j c #FFD582",
"k c #EB8D30",
"l c #F56600",
"m c #DB5600",
"n c #8F391D",
"o c #480701",
"p c #BB330E",
"q c #E83C16",
"r c #9A2209",
"s c #B95227",
"t c #E25F2E",
"u c #321A0E",
"v c #070401",
"w c #FF8F1A",
"x c #FFA434",
"y c #5D3014",
"z c #9C3201",
"A c #FF5F00",
"B c #F42600",
"C c #DD1500",
"D c #FC3704",
"E c #DA2106",
"F c #2C0000",
"G c #521E0A",
"H c #FF7030",
"I c #C02F00",
"J c #FF6900",
"K c #FF6D04",
"L c #9E3200",
"M c #BB2500",
"N c #F94B00",
"O c #E53700",
"P c #BD1600",
"Q c #DC2903",
"R c #CF1505",
"S c #A71607",
"T c #AE2E0F",
"U c #FE7635",
"V c #A1491D",
"W c #5D432B",
"X c #141513",
"Y c #A24608",
"Z c #FF6209",
"` c #F94500",
" . c #FF4300",
".. c #FD3500",
"+. c #F33D00",
"@. c #D92800",
"#. c #AD1101",
"$. c #D42003",
"%. c #C10E04",
"&. c #DC270C",
"*. c #E33F16",
"=. c #FD7B38",
"-. c #88401B",
";. c #F94206",
">. c #E82A00",
",. c #EA2D00",
"'. c #E32600",
"). c #E02400",
"!. c #D21300",
"~. c #B21602",
"{. c #E31C04",
"]. c #D81607",
"^. c #D12B0C",
"/. c #D44318",
"(. c #FF8B44",
"_. c #793516",
":. c #100B09",
"<. c #6D4B2F",
"[. c #DD2300",
"}. c #E01F00",
"|. c #EC2100",
"1. c #E81D00",
"2. c #DB1800",
"3. c #C51000",
"4. c #BF1603",
"5. c #C31305",
"6. c #861003",
"7. c #D2300F",
"8. c #E35321",
"9. c #FF9046",
"0. c #662D14",
"a. c #1D0D03",
"b. c #D71B00",
"c. c #CB1C02",
"d. c #581806",
"e. c #A71101",
"f. c #DD1000",
"g. c #B90301",
"h. c #BA0A00",
"i. c #710A03",
"j. c #39190B",
"k. c #D44117",
"l. c #F66F32",
"m. c #F8823D",
"n. c #41190B",
"o. c #B70D01",
"p. c #CA1503",
"q. c #431408",
"r. c #830A02",
"s. c #D60C02",
"t. c #B70C03",
"u. c #B00A01",
"v. c #C8280D",
"w. c #B63C18",
"x. c #E25725",
"y. c #FF8C44",
"z. c #BD5B27",
"A. c #C81304",
"B. c #D21404",
"C. c #CF1A07",
"D. c #B81304",
"E. c #9C0B02",
"F. c #E13E17",
"G. c #E25322",
"H. c #F67B3A",
"I. c #F27937",
"J. c #561E0A",
"K. c #7C1002",
"L. c #CB2108",
"M. c #D82A0C",
"N. c #DA3611",
"O. c #BF2A0E",
"P. c #A71102",
"Q. c #EB5F27",
"R. c #F57131",
"S. c #F26C2D",
"T. c #78270D",
"U. c #611104",
"V. c #AF240A",
"W. c #DF3D13",
"X. c #E33910",
"Y. c #D42909",
"Z. c #F25B21",
"`. c #CD4918",
" + c #661905",
".+ c #3B0600",
"++ c #5C1004",
"@+ c #650E03",
"#+ c #6B1203",
"$+ c #691B06",
"%+ c #2D0400",
" ",
" ",
" ",
" . + @ # ",
" $ % & * = - ; > ",
" - , ' ) ! ~ { ] ^ / ( ",
" _ : < [ } | 1 2 3 4 ",
" 5 6 7 8 9 0 a b c d e f g h ",
" i j k l m n o p q r s t u v ",
" w x y z A B C D E F G H ",
" I J K L M N O P Q R S T U V ",
" W X Y Z ` ...+.@.#.$.%.&.*.=.-. ",
" ;.>.,.'.).!.~.{.].^./.(._.:.<. ",
" [.}.|.1.2.3.4.5.6.7.8.9.0. a. ",
" b.c.d.e.f.g.h.i.j.k.l.m.n. ",
" o.p.q.r.s.t.u.v.w.x.y.z. ",
" A.B.R C.D.E.F.G.H.I.J. ",
" K.L.M.N.O.P.Q.R.S.T. ",
" U.V.W.X.Y.Z.`. + ",
" .+++@+#+$+%+ ",
" ",
" "};

View File

@ -0,0 +1,3 @@
This directory contains customized xmlrpc-c (http://xmlrpc-c.sourceforge.net)
library suitable only for EDE usage. Besides that, some things are removed because
they are not used (abyss server and C++ wrapper).

View File

@ -0,0 +1,311 @@
/*=============================================================================
curlMulti
===============================================================================
This is an extension to Curl's CURLM object. The extensions are:
1) It has a lock so multiple threads can use it simultaneously.
2) Its "select" file descriptor vectors are self-contained. CURLM
requires the user to maintain them separately.
=============================================================================*/
#include "xmlrpc_config.h"
#include <stdlib.h>
#if !MSVCRT
#include <sys/select.h>
#endif
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <curl/multi.h>
#include "mallocvar.h"
#include "xmlrpc-c/util.h"
#include "xmlrpc-c/string_int.h"
#include "curlversion.h"
#include "lock.h"
#include "lock_pthread.h"
#include "curlmulti.h"
static void
interpretCurlMultiError(const char ** const descriptionP,
CURLMcode const code) {
#if HAVE_CURL_STRERROR
*descriptionP = strdup(curl_multi_strerror(code));
#else
xmlrpc_asprintf(descriptionP, "Curl error code (CURLMcode) %d", code);
#endif
}
struct curlMulti {
CURLM * curlMultiP;
lock * lockP;
/* Hold this lock while accessing or using *curlMultiP. You're
using the multi manager whenever you're calling a Curl
library multi manager function.
*/
/* The following file descriptor sets are an integral part of the
CURLM object; Our curlMulti_fdset() routine binds them to the
CURLM object, and said object expects us to use them in a very
specific way, including doing a select() on them. It is very,
very messy.
*/
fd_set readFdSet;
fd_set writeFdSet;
fd_set exceptFdSet;
};
curlMulti *
curlMulti_create(void) {
curlMulti * retval;
curlMulti * curlMultiP;
MALLOCVAR(curlMultiP);
if (curlMultiP == NULL)
retval = NULL;
else {
curlMultiP->lockP = curlLock_create_pthread();
if (curlMultiP->lockP == NULL)
retval = NULL;
else {
curlMultiP->curlMultiP = curl_multi_init();
if (curlMultiP->curlMultiP == NULL)
retval = NULL;
else
retval = curlMultiP;
if (retval == NULL)
curlMultiP->lockP->destroy(curlMultiP->lockP);
}
if (retval == NULL)
free(curlMultiP);
}
return retval;
}
void
curlMulti_destroy(curlMulti * const curlMultiP) {
curl_multi_cleanup(curlMultiP->curlMultiP);
curlMultiP->lockP->destroy(curlMultiP->lockP);
free(curlMultiP);
}
void
curlMulti_perform(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
bool * const immediateWorkToDoP,
int * const runningHandlesP) {
/*----------------------------------------------------------------------------
Do whatever work is ready to be done under the control of multi
manager 'curlMultiP'. E.g. if HTTP response data has recently arrived
from the network, process it as an HTTP response.
Iff this results in some work being finished from our point of view,
return *immediateWorkToDoP. (Caller can query the multi manager for
messages and find out what it is).
Return as *runningHandlesP the number of Curl easy handles under the
multi manager's control that are still running -- yet to finish.
-----------------------------------------------------------------------------*/
CURLMcode rc;
curlMultiP->lockP->acquire(curlMultiP->lockP);
rc = curl_multi_perform(curlMultiP->curlMultiP, runningHandlesP);
curlMultiP->lockP->release(curlMultiP->lockP);
if (rc == CURLM_CALL_MULTI_PERFORM) {
*immediateWorkToDoP = true;
} else {
*immediateWorkToDoP = false;
if (rc != CURLM_OK) {
const char * reason;
interpretCurlMultiError(&reason, rc);
xmlrpc_faultf(envP, "Impossible failure of curl_multi_perform(): "
"%s", reason);
xmlrpc_strfree(reason);
}
}
}
void
curlMulti_addHandle(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
CURL * const curlSessionP) {
CURLMcode rc;
curlMultiP->lockP->acquire(curlMultiP->lockP);
rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP);
curlMultiP->lockP->release(curlMultiP->lockP);
if (rc != CURLM_OK) {
const char * reason;
interpretCurlMultiError(&reason, rc);
xmlrpc_faultf(envP, "Could not add Curl session to the "
"curl multi manager. curl_multi_add_handle() "
"failed: %s", reason);
xmlrpc_strfree(reason);
}
}
void
curlMulti_removeHandle(curlMulti * const curlMultiP,
CURL * const curlSessionP) {
curlMultiP->lockP->acquire(curlMultiP->lockP);
curl_multi_remove_handle(curlMultiP->curlMultiP, curlSessionP);
curlMultiP->lockP->release(curlMultiP->lockP);
}
void
curlMulti_getMessage(curlMulti * const curlMultiP,
bool * const endOfMessagesP,
CURLMsg * const curlMsgP) {
/*----------------------------------------------------------------------------
Get the next message from the queue of things the Curl multi manager
wants to say to us.
Return the message as *curlMsgP.
Iff there are no messages in the queue, return *endOfMessagesP == true.
-----------------------------------------------------------------------------*/
int remainingMsgCount;
CURLMsg * privateCurlMsgP;
/* Note that this is a pointer into the multi manager's memory,
so we have to use it under lock.
*/
curlMultiP->lockP->acquire(curlMultiP->lockP);
privateCurlMsgP = curl_multi_info_read(curlMultiP->curlMultiP,
&remainingMsgCount);
if (privateCurlMsgP == NULL)
*endOfMessagesP = true;
else {
*endOfMessagesP = false;
*curlMsgP = *privateCurlMsgP;
}
curlMultiP->lockP->release(curlMultiP->lockP);
}
void
curlMulti_fdset(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
fd_set * const readFdSetP,
fd_set * const writeFdSetP,
fd_set * const exceptFdSetP,
int * const maxFdP) {
/*----------------------------------------------------------------------------
Set the CURLM object's file descriptor sets to those in the
curlMulti object, update those file descriptor sets with the
current needs of the multi manager, and return the resulting values
of the file descriptor sets.
This is a bizarre operation, but is necessary because of the nonmodular
way in which the Curl multi interface works with respect to waiting
for work with select().
-----------------------------------------------------------------------------*/
CURLMcode rc;
curlMultiP->lockP->acquire(curlMultiP->lockP);
/* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing
ones (so you can easily do a select() on other fds and Curl
fds at the same time). So we have to clear first:
*/
FD_ZERO(&curlMultiP->readFdSet);
FD_ZERO(&curlMultiP->writeFdSet);
FD_ZERO(&curlMultiP->exceptFdSet);
/* WARNING: curl_multi_fdset() doesn't just update the fdsets pointed
to by its arguments. It makes the CURLM object remember those
pointers and refer back to them later! In fact, curl_multi_perform
expects its caller to have done a select() on those masks. No,
really. The man page even admits it.
Inspection of the Libcurl code in March 2007 indicates that
this isn't actually true -- curl_multi_fdset() updates your
fdset and doesn't remember the pointer at all. I.e. it's just
what you would expect. The man pages still says it's as
described above. My guess is that Libcurl was fixed at some
time and the man page not updated. In any case, we have to
work with old Libcurl if at all possible, so we still maintain
these fdsets as if they belong to the CURLM object.
*/
rc = curl_multi_fdset(curlMultiP->curlMultiP,
&curlMultiP->readFdSet,
&curlMultiP->writeFdSet,
&curlMultiP->exceptFdSet,
maxFdP);
*readFdSetP = curlMultiP->readFdSet;
*writeFdSetP = curlMultiP->writeFdSet;
*exceptFdSetP = curlMultiP->exceptFdSet;
curlMultiP->lockP->release(curlMultiP->lockP);
if (rc != CURLM_OK) {
const char * reason;
interpretCurlMultiError(&reason, rc);
xmlrpc_faultf(envP, "Impossible failure of curl_multi_fdset(): %s",
reason);
xmlrpc_strfree(reason);
}
}
void
curlMulti_updateFdSet(curlMulti * const curlMultiP,
fd_set const readFdSet,
fd_set const writeFdSet,
fd_set const exceptFdSet) {
/*----------------------------------------------------------------------------
curl_multi_perform() expects the file descriptor sets, which were bound
to the CURLM object via a prior curlMulti_fdset(), to contain the results
of a recent select(). This subroutine provides you a way to supply those.
-----------------------------------------------------------------------------*/
curlMultiP->readFdSet = readFdSet;
curlMultiP->writeFdSet = writeFdSet;
curlMultiP->exceptFdSet = exceptFdSet;
}

View File

@ -0,0 +1,51 @@
#ifndef CURLMULTI_H_INCLUDED
#define CURLMULTI_H_INCLUDED
#include "bool.h"
#include "xmlrpc-c/util.h"
#include "curltransaction.h"
typedef struct curlMulti curlMulti;
curlMulti *
curlMulti_create(void);
void
curlMulti_destroy(curlMulti * const curlMultiP);
void
curlMulti_perform(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
bool * const immediateWorkToDoP,
int * const runningHandlesP);
void
curlMulti_addHandle(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
CURL * const curlSessionP);
void
curlMulti_removeHandle(curlMulti * const curlMultiP,
CURL * const curlSessionP);
void
curlMulti_getMessage(curlMulti * const curlMultiP,
bool * const endOfMessagesP,
CURLMsg * const curlMsgP);
void
curlMulti_fdset(xmlrpc_env * const envP,
curlMulti * const curlMultiP,
fd_set * const readFdSetP,
fd_set * const writeFdSetP,
fd_set * const exceptFdSetP,
int * const maxFdP);
void
curlMulti_updateFdSet(curlMulti * const curlMultiP,
fd_set const readFdSet,
fd_set const writeFdSet,
fd_set const exceptFdSet);
#endif

View File

@ -0,0 +1,621 @@
/*=============================================================================
curlTransaction
=============================================================================*/
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "mallocvar.h"
#include "xmlrpc-c/util.h"
#include "xmlrpc-c/string_int.h"
#include "xmlrpc-c/client.h"
#include "xmlrpc-c/client_int.h"
#include "version.h"
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include "curlversion.h"
#include "curltransaction.h"
struct curlTransaction {
/* This is all stuff that really ought to be in a Curl object, but
the Curl library is a little too simple for that. So we build
a layer on top of Curl, and define this "transaction," as an
object subordinate to a Curl "session." A Curl session has
zero or one transactions in progress. The Curl session
"private data" is a pointer to the CurlTransaction object for
the current transaction.
*/
CURL * curlSessionP;
/* Handle for the Curl session that hosts this transaction.
Note that only one transaction at a time can use a particular
Curl session, so this had better not be a session that some other
transaction is using simultaneously.
*/
curlt_finishFn * finish;
curlt_progressFn * progress;
void * userContextP;
/* Meaningful to our client; opaque to us */
CURLcode result;
/* Result of the transaction (succeeded, TCP connect failed, etc.).
A properly executed HTTP transaction (request & response) counts
as a successful transaction. When 'result' show success,
curl_easy_get_info() tells you whether the transaction succeeded
at the HTTP level.
*/
char curlError[CURL_ERROR_SIZE];
/* Error message from Curl */
struct curl_slist * headerList;
/* The HTTP headers for the transaction */
const char * serverUrl; /* malloc'ed - belongs to this object */
};
static void
addHeader(xmlrpc_env * const envP,
struct curl_slist ** const headerListP,
const char * const headerText) {
struct curl_slist * newHeaderList;
newHeaderList = curl_slist_append(*headerListP, headerText);
if (newHeaderList == NULL)
xmlrpc_faultf(envP,
"Could not add header '%s'. "
"curl_slist_append() failed.", headerText);
else
*headerListP = newHeaderList;
}
static void
addContentTypeHeader(xmlrpc_env * const envP,
struct curl_slist ** const headerListP) {
addHeader(envP, headerListP, "Content-Type: text/xml");
}
static void
addUserAgentHeader(xmlrpc_env * const envP,
struct curl_slist ** const headerListP,
const char * const userAgent) {
if (userAgent) {
/* Note: Curl has a CURLOPT_USERAGENT option that does some of this
work. We prefer to be totally in control, though, so we build
the header explicitly.
*/
curl_version_info_data * const curlInfoP =
curl_version_info(CURLVERSION_NOW);
char curlVersion[32];
const char * userAgentHeader;
snprintf(curlVersion, sizeof(curlVersion), "%u.%u.%u",
(curlInfoP->version_num >> 16) && 0xff,
(curlInfoP->version_num >> 8) && 0xff,
(curlInfoP->version_num >> 0) && 0xff
);
xmlrpc_asprintf(&userAgentHeader,
"User-Agent: %s Xmlrpc-c/%s Curl/%s",
userAgent, XMLRPC_C_VERSION, curlVersion);
if (userAgentHeader == xmlrpc_strsol)
xmlrpc_faultf(envP, "Couldn't allocate memory for "
"User-Agent header");
else {
addHeader(envP, headerListP, userAgentHeader);
xmlrpc_strfree(userAgentHeader);
}
}
}
static void
addAuthorizationHeader(xmlrpc_env * const envP,
struct curl_slist ** const headerListP,
const char * const hdrValue) {
const char * authorizationHeader;
xmlrpc_asprintf(&authorizationHeader, "Authorization: %s", hdrValue);
if (authorizationHeader == xmlrpc_strsol)
xmlrpc_faultf(envP, "Couldn't allocate memory for "
"Authorization header");
else {
addHeader(envP, headerListP, authorizationHeader);
xmlrpc_strfree(authorizationHeader);
}
}
static void
createCurlHeaderList(xmlrpc_env * const envP,
const char * const authHdrValue,
const char * const userAgent,
struct curl_slist ** const headerListP) {
struct curl_slist * headerList;
headerList = NULL; /* initial value - empty list */
addContentTypeHeader(envP, &headerList);
if (!envP->fault_occurred) {
addUserAgentHeader(envP, &headerList, userAgent);
if (!envP->fault_occurred) {
if (authHdrValue)
addAuthorizationHeader(envP, &headerList, authHdrValue);
}
}
if (envP->fault_occurred)
curl_slist_free_all(headerList);
else
*headerListP = headerList;
}
static size_t
collect(void * const ptr,
size_t const size,
size_t const nmemb,
FILE * const stream) {
/*----------------------------------------------------------------------------
This is a Curl output function. Curl calls this to deliver the
HTTP response body to the Curl client. Curl thinks it's writing to
a POSIX stream.
-----------------------------------------------------------------------------*/
xmlrpc_mem_block * const responseXmlP = (xmlrpc_mem_block *) stream;
char * const buffer = ptr;
size_t const length = nmemb * size;
size_t retval;
xmlrpc_env env;
xmlrpc_env_init(&env);
xmlrpc_mem_block_append(&env, responseXmlP, buffer, length);
if (env.fault_occurred)
retval = (size_t)-1;
else
/* Really? Shouldn't it be like fread() and return 'nmemb'? */
retval = length;
return retval;
}
static int
curlProgress(void * const contextP,
double const dltotal ATTR_UNUSED,
double const dlnow ATTR_UNUSED,
double const ultotal ATTR_UNUSED,
double const ulnow ATTR_UNUSED) {
/*----------------------------------------------------------------------------
This is a Curl "progress function." It's something various Curl
functions call every so often, including whenever something gets
interrupted by the process receiving, and catching, a signal.
There are two purposes of a Curl progress function: 1) lets us log
the progress of a long-running transaction such as a big download,
e.g. by displaying a progress bar somewhere. In Xmlrpc-c, we don't
implement this purpose. 2) allows us to tell the Curl function,
via our return code, that calls it that we don't want to wait
anymore for the operation to complete.
In Curl versions before March 2007, we get called once per second
and signals have no effect. In current Curl, we usually get called
immediately after a signal gets caught while Curl is waiting to
receive a response from the server. But Curl doesn't properly
synchronize with signals, so it may miss one and then we don't get
called until the next scheduled one-per-second call.
All we do is tell Caller it's time to give up if the transport's
client says it is via his "interrupt" flag.
This function is not as important as it once was. This module used
to use curl_easy_perform(), which can be interrupted only via this
progress function. But because of the above-mentioned failure of
Curl to properly synchronize signals (and Bryan's failure to get
Curl developers to accept code to fix it), we now use the Curl
"multi" facility instead and do our own pselect(). But
This function still normally gets called by curl_multi_perform(),
which the transport tries to call even when the user has requested
interruption, because we don't trust our ability to abort a running
Curl transaction. curl_multi_perform() reliably winds up a Curl
transaction when this function tells it to.
-----------------------------------------------------------------------------*/
curlTransaction * const curlTransactionP = contextP;
bool abort;
/* We require anyone setting us up as the Curl progress function to
supply a progress function:
*/
assert(curlTransactionP);
assert(curlTransactionP->progress);
curlTransactionP->progress(curlTransactionP->userContextP, &abort);
return abort;
}
static void
setupAuth(xmlrpc_env * const envP ATTR_UNUSED,
CURL * const curlSessionP,
const xmlrpc_server_info * const serverInfoP,
const char ** const authHdrValueP) {
/*----------------------------------------------------------------------------
Set the options in the Curl session 'curlSessionP' to set up the HTTP
authentication described by *serverInfoP.
But we have an odd special function for backward compatibility, because
this code dates to a time when libcurl did not have the ability to
handle authentication, but we provided such function nonetheless by
building our own Authorization: header. But we did this only for
HTTP basic authentication.
So the special function is this: if libcurl is too old to have
authorization options and *serverInfoP allows basic authentication,
return as *basicAuthHdrParamP an appropriate parameter for the
Authorization: Basic: HTTP header. Otherwise, return
*basicAuthHdrParamP == NULL.
-----------------------------------------------------------------------------*/
if (serverInfoP->allowedAuth.basic) {
CURLcode rc;
rc = curl_easy_setopt(curlSessionP, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
if (rc == CURLE_OK)
*authHdrValueP = NULL;
else {
*authHdrValueP = strdup(serverInfoP->basicAuthHdrValue);
if (*authHdrValueP == NULL)
xmlrpc_faultf(envP, "Unable to allocate memory for basic "
"authentication header");
}
} else
*authHdrValueP = NULL;
/* We don't worry if libcurl is too old for these other kinds of
authentication; they're only defined as _allowed_
authentication methods, for when client and server are capable
of using it, and unlike with basic authentication, we have no
historical commitment to consider an old libcurl as capable of
doing these.
*/
if (serverInfoP->userNamePw)
curl_easy_setopt(curlSessionP, CURLOPT_USERPWD,
serverInfoP->userNamePw);
if (serverInfoP->allowedAuth.digest)
curl_easy_setopt(
curlSessionP, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
if (serverInfoP->allowedAuth.gssnegotiate)
curl_easy_setopt(
curlSessionP, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE);
if (serverInfoP->allowedAuth.ntlm)
curl_easy_setopt(
curlSessionP, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
}
static void
setCurlTimeout(CURL * const curlSessionP ATTR_UNUSED,
unsigned int const timeout ATTR_UNUSED) {
#if HAVE_CURL_NOSIGNAL
unsigned int const timeoutMs = (timeout + 999)/1000;
curl_easy_setopt(curlSessionP, CURLOPT_NOSIGNAL, 1);
assert((long)timeoutMs == (int)timeoutMs);
/* Calling requirement */
curl_easy_setopt(curlSessionP, CURLOPT_TIMEOUT, (long)timeoutMs);
#else
abort();
#endif
}
static void
assertConstantsMatch(void) {
/*----------------------------------------------------------------------------
There are some constants that we define as part of the Xmlrpc-c
interface that are identical to constants in the Curl interface to
make curl option setting work. This function asserts such
formally.
-----------------------------------------------------------------------------*/
assert(XMLRPC_SSLVERSION_DEFAULT == CURL_SSLVERSION_DEFAULT);
assert(XMLRPC_SSLVERSION_TLSv1 == CURL_SSLVERSION_TLSv1);
assert(XMLRPC_SSLVERSION_SSLv2 == CURL_SSLVERSION_SSLv2);
assert(XMLRPC_SSLVERSION_SSLv3 == CURL_SSLVERSION_SSLv3);
}
static void
setupCurlSession(xmlrpc_env * const envP,
curlTransaction * const curlTransactionP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block * const responseXmlP,
const xmlrpc_server_info * const serverInfoP,
const char * const userAgent,
const struct curlSetup * const curlSetupP) {
/*----------------------------------------------------------------------------
Set up the Curl session for the transaction *curlTransactionP so that
a subsequent curl_easy_perform() would perform said transaction.
The data curl_easy_perform() would send for that transaction would
be the contents of *callXmlP; the data curl_easy_perform() gets back
would go into *responseXmlP.
*serverInfoP tells what sort of authentication to set up. This is
an embarassment, as the xmlrpc_server_info type is part of the
Xmlrpc-c interface. Some day, we need to replace this with a type
(probably identical) not tied to Xmlrpc-c.
-----------------------------------------------------------------------------*/
CURL * const curlSessionP = curlTransactionP->curlSessionP;
assertConstantsMatch();
/* A Curl session is serial -- it processes zero or one transaction
at a time. We use the "private" attribute of the Curl session to
indicate which transaction it is presently processing. This is
important when the transaction finishes, because libcurl will just
tell us that something finished on a particular session, not that
a particular transaction finished.
*/
curl_easy_setopt(curlSessionP, CURLOPT_PRIVATE, curlTransactionP);
curl_easy_setopt(curlSessionP, CURLOPT_POST, 1);
curl_easy_setopt(curlSessionP, CURLOPT_URL, curlTransactionP->serverUrl);
XMLRPC_MEMBLOCK_APPEND(char, envP, callXmlP, "\0", 1);
if (!envP->fault_occurred) {
curl_easy_setopt(curlSessionP, CURLOPT_POSTFIELDS,
XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP));
curl_easy_setopt(curlSessionP, CURLOPT_WRITEFUNCTION, collect);
curl_easy_setopt(curlSessionP, CURLOPT_FILE, responseXmlP);
curl_easy_setopt(curlSessionP, CURLOPT_HEADER, 0);
curl_easy_setopt(curlSessionP, CURLOPT_ERRORBUFFER,
curlTransactionP->curlError);
if (curlTransactionP->progress) {
curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSFUNCTION,
curlProgress);
curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSDATA,
curlTransactionP);
} else
curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYPEER,
curlSetupP->sslVerifyPeer);
curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYHOST,
curlSetupP->sslVerifyHost ? 2 : 0);
if (curlSetupP->networkInterface)
curl_easy_setopt(curlSessionP, CURLOPT_INTERFACE,
curlSetupP->networkInterface);
if (curlSetupP->sslCert)
curl_easy_setopt(curlSessionP, CURLOPT_SSLCERT,
curlSetupP->sslCert);
if (curlSetupP->sslCertType)
curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTTYPE,
curlSetupP->sslCertType);
if (curlSetupP->sslCertPasswd)
curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTPASSWD,
curlSetupP->sslCertPasswd);
if (curlSetupP->sslKey)
curl_easy_setopt(curlSessionP, CURLOPT_SSLKEY,
curlSetupP->sslKey);
if (curlSetupP->sslKeyType)
curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYTYPE,
curlSetupP->sslKeyType);
if (curlSetupP->sslKeyPasswd)
curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYPASSWD,
curlSetupP->sslKeyPasswd);
if (curlSetupP->sslEngine)
curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE,
curlSetupP->sslEngine);
if (curlSetupP->sslEngineDefault)
/* 3rd argument seems to be required by some Curl */
curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE_DEFAULT, 1l);
if (curlSetupP->sslVersion != XMLRPC_SSLVERSION_DEFAULT)
curl_easy_setopt(curlSessionP, CURLOPT_SSLVERSION,
curlSetupP->sslVersion);
if (curlSetupP->caInfo)
curl_easy_setopt(curlSessionP, CURLOPT_CAINFO,
curlSetupP->caInfo);
if (curlSetupP->caPath)
curl_easy_setopt(curlSessionP, CURLOPT_CAPATH,
curlSetupP->caPath);
if (curlSetupP->randomFile)
curl_easy_setopt(curlSessionP, CURLOPT_RANDOM_FILE,
curlSetupP->randomFile);
if (curlSetupP->egdSocket)
curl_easy_setopt(curlSessionP, CURLOPT_EGDSOCKET,
curlSetupP->egdSocket);
if (curlSetupP->sslCipherList)
curl_easy_setopt(curlSessionP, CURLOPT_SSL_CIPHER_LIST,
curlSetupP->sslCipherList);
if (curlSetupP->timeout)
setCurlTimeout(curlSessionP, curlSetupP->timeout);
{
const char * authHdrValue;
/* NULL means we don't have to construct an explicit
Authorization: header. non-null means we have to
construct one with this as its value.
*/
setupAuth(envP, curlSessionP, serverInfoP, &authHdrValue);
if (!envP->fault_occurred) {
struct curl_slist * headerList;
createCurlHeaderList(envP, authHdrValue, userAgent,
&headerList);
if (!envP->fault_occurred) {
curl_easy_setopt(
curlSessionP, CURLOPT_HTTPHEADER, headerList);
curlTransactionP->headerList = headerList;
}
if (authHdrValue)
xmlrpc_strfree(authHdrValue);
}
}
}
}
void
curlTransaction_create(xmlrpc_env * const envP,
CURL * const curlSessionP,
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block * const responseXmlP,
const char * const userAgent,
const struct curlSetup * const curlSetupStuffP,
void * const userContextP,
curlt_finishFn * const finish,
curlt_progressFn * const progress,
curlTransaction ** const curlTransactionPP) {
curlTransaction * curlTransactionP;
MALLOCVAR(curlTransactionP);
if (curlTransactionP == NULL)
xmlrpc_faultf(envP, "No memory to create Curl transaction.");
else {
curlTransactionP->finish = finish;
curlTransactionP->curlSessionP = curlSessionP;
curlTransactionP->userContextP = userContextP;
curlTransactionP->progress = progress;
curlTransactionP->serverUrl = strdup(serverP->serverUrl);
if (curlTransactionP->serverUrl == NULL)
xmlrpc_faultf(envP, "Out of memory to store server URL.");
else {
setupCurlSession(envP, curlTransactionP,
callXmlP, responseXmlP,
serverP, userAgent,
curlSetupStuffP);
if (envP->fault_occurred)
xmlrpc_strfree(curlTransactionP->serverUrl);
}
if (envP->fault_occurred)
free(curlTransactionP);
}
*curlTransactionPP = curlTransactionP;
}
void
curlTransaction_destroy(curlTransaction * const curlTransactionP) {
curl_slist_free_all(curlTransactionP->headerList);
xmlrpc_strfree(curlTransactionP->serverUrl);
free(curlTransactionP);
}
static void
interpretCurlEasyError(const char ** const descriptionP,
CURLcode const code) {
#if HAVE_CURL_STRERROR
*descriptionP = strdup(curl_easy_strerror(code));
#else
xmlrpc_asprintf(descriptionP, "Curl error code (CURLcode) %d", code);
#endif
}
void
curlTransaction_getError(curlTransaction * const curlTransactionP,
xmlrpc_env * const envP) {
if (curlTransactionP->result != CURLE_OK) {
/* We've seen Curl just return a null string for an explanation
(e.g. when TCP connect() fails because IP address doesn't exist).
*/
const char * explanation;
if (strlen(curlTransactionP->curlError) == 0)
interpretCurlEasyError(&explanation, curlTransactionP->result);
else
xmlrpc_asprintf(&explanation, "%s", curlTransactionP->curlError);
xmlrpc_env_set_fault_formatted(
envP, XMLRPC_NETWORK_ERROR, "libcurl failed to execute the "
"HTTP POST transaction. %s", explanation);
xmlrpc_strfree(explanation);
} else {
CURLcode res;
long http_result;
res = curl_easy_getinfo(curlTransactionP->curlSessionP,
CURLINFO_HTTP_CODE, &http_result);
if (res != CURLE_OK)
xmlrpc_env_set_fault_formatted(
envP, XMLRPC_INTERNAL_ERROR,
"Curl performed the HTTP POST request, but was "
"unable to say what the HTTP result code was. "
"curl_easy_getinfo(CURLINFO_HTTP_CODE) says: %s",
curlTransactionP->curlError);
else {
if (http_result != 200)
xmlrpc_env_set_fault_formatted(
envP, XMLRPC_NETWORK_ERROR,
"HTTP response code is %ld, not 200",
http_result);
}
}
}
void
curlTransaction_finish(xmlrpc_env * const envP,
curlTransaction * const curlTransactionP,
CURLcode const result) {
curlTransactionP->result = result;
if (curlTransactionP->finish)
curlTransactionP->finish(envP, curlTransactionP->userContextP);
}
CURL *
curlTransaction_curlSession(curlTransaction * const curlTransactionP) {
return curlTransactionP->curlSessionP;
}

View File

@ -0,0 +1,106 @@
#ifndef CURLTRANSACTION_H_INCLUDED
#define CURLTRANSACTION_H_INCLUDED
#include "bool.h"
#include "xmlrpc-c/util.h"
#include "xmlrpc-c/client.h"
#include <curl/curl.h>
typedef struct curlTransaction curlTransaction;
typedef void curlt_finishFn(xmlrpc_env * const, void * const);
typedef void curlt_progressFn(void * const, bool * const);
struct curlSetup {
/* This is all client transport properties that are implemented as
simple Curl session properties (i.e. the transport basically just
passes them through to Curl without looking at them).
People occasionally want to replace all this with something where
the Xmlrpc-c user simply does the curl_easy_setopt() call and this
code need not know about all these options. Unfortunately, that's
a significant modularity violation. Either the Xmlrpc-c user
controls the Curl object or he doesn't. If he does, then he
shouldn't use libxmlrpc_client -- he should just copy some of this
code into his own program. If he doesn't, then he should never see
the Curl library.
Speaking of modularity: the only reason this is a separate struct
is to make the code easier to manage. Ideally, the fact that these
particular properties of the transport are implemented by simple
Curl session setup would be known only at the lowest level code
that does that setup.
*/
const char * networkInterface;
/* This identifies the network interface on the local side to
use for the session. It is an ASCIIZ string in the form
that the Curl recognizes for setting its CURLOPT_INTERFACE
option (also the --interface option of the Curl program).
E.g. "9.1.72.189" or "giraffe-data.com" or "eth0".
It isn't necessarily valid, but it does have a terminating NUL.
NULL means we have no preference.
*/
bool sslVerifyPeer;
/* In an SSL connection, we should authenticate the server's SSL
certificate -- refuse to talk to him if it isn't authentic.
This is equivalent to Curl's CURLOPT_SSL_VERIFY_PEER option.
*/
bool sslVerifyHost;
/* In an SSL connection, we should verify that the server's
certificate (independently of whether the certificate is
authentic) indicates the host name that is in the URL we
are using for the server.
*/
const char * sslCert;
const char * sslCertType;
const char * sslCertPasswd;
const char * sslKey;
const char * sslKeyType;
const char * sslKeyPasswd;
const char * sslEngine;
bool sslEngineDefault;
unsigned int sslVersion;
const char * caInfo;
const char * caPath;
const char * randomFile;
const char * egdSocket;
const char * sslCipherList;
unsigned int timeout;
/* 0 = no Curl timeout. This is in milliseconds. */
};
void
curlTransaction_create(xmlrpc_env * const envP,
CURL * const curlSessionP,
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block * const responseXmlP,
const char * const userAgent,
const struct curlSetup * const curlSetupStuffP,
void * const userContextP,
curlt_finishFn * const finish,
curlt_progressFn * const progress,
curlTransaction ** const curlTransactionPP);
void
curlTransaction_destroy(curlTransaction * const curlTransactionP);
void
curlTransaction_finish(xmlrpc_env * const envP,
curlTransaction * const curlTransactionP,
CURLcode const result);
void
curlTransaction_getError(curlTransaction * const curlTransactionP,
xmlrpc_env * const envP);
CURL *
curlTransaction_curlSession(curlTransaction * const curlTransactionP);
#endif

View File

@ -0,0 +1,20 @@
#ifndef CURLVERSION_H_INCLUDED
#define CURLVERSION_H_INCLUDED
#define CMAJOR LIBCURL_VERSION_MAJOR
#define CMINOR LIBCURL_VERSION_MINOR
#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 10)
#define HAVE_CURL_NOSIGNAL 1
#else
#define HAVE_CURL_NOSIGNAL 0
#endif
#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 12)
#define HAVE_CURL_STRERROR 1
#else
#define HAVE_CURL_STRERROR 0
#endif
#undef CMAJOR
#undef CMINOR
#endif

View File

@ -0,0 +1,24 @@
#ifndef CURL_LOCK_H_INCLUDED
#define CURL_LOCK_H_INCLUDED
#include <pthread.h>
typedef struct lock lock;
typedef void lockAcquireFn(lock *);
typedef void lockReleaseFn(lock *);
typedef void lockDestroyFn(lock *);
struct lock {
/* To finish the job of making an abstract lock class that can use locks
other than pthread mutexes, we need to replace 'theLock' with a
"void * implementationP" and make curlLock_create_pthread() malloc
the mutex.
*/
pthread_mutex_t theLock;
lockAcquireFn * acquire;
lockReleaseFn * release;
lockDestroyFn * destroy;
};
#endif

View File

@ -0,0 +1,49 @@
#include <stdlib.h>
#include "mallocvar.h"
#include "pthreadx.h"
#include "lock.h"
#include "lock_pthread.h"
static lockAcquireFn acquire;
static void
acquire(struct lock * const lockP) {
pthread_mutex_lock(&lockP->theLock);
}
static lockReleaseFn release;
static void
release(struct lock * const lockP) {
pthread_mutex_unlock(&lockP->theLock);
}
static lockDestroyFn destroy;
static void
destroy(struct lock * const lockP) {
pthread_mutex_destroy(&lockP->theLock);
free(lockP);
}
struct lock *
curlLock_create_pthread(void) {
struct lock * lockP;
MALLOCVAR(lockP);
if (lockP) {
pthread_mutex_init(&lockP->theLock, NULL);
lockP->acquire = &acquire;
lockP->release = &release;
lockP->destroy = &destroy;
}
return lockP;
}

View File

@ -0,0 +1,9 @@
#ifndef CURL_LOCK_PTHREAD_H_INCLUDED
#define CURL_LOCK_PTHREAD_H_INCLUDED
#include "lock.h"
lock *
curlLock_create_pthread(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<TITLE>expat</TITLE>
<BODY>
<H1>expat - XML Parser Toolkit</H1>
<p>This is outdated stuff from the independently developed Expat which
was forked in 2001 to make the Xmlrpc-c embedded version.
<H3>Version 1.2</H3>
<P>Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center
Ltd. Expat is freely available with source under a very liberal <a
href="copying.txt">license</a> (the MIT license).</P>
<P>This is a production version of expat. Relative to expat 1.1, it
adds support for parsing external DTDs and parameter entities.
Compiling with -DXML_DTD enables this support. There's a new
<CODE>-p</CODE> option for xmlwf which will cause it to process
external DTDs and parameter entities; this implies the <CODE>-x</CODE>
option. See the comment above <CODE>XML_SetParamEntityParsing</CODE>
in <CODE>xmlparse.h</CODE> for the API addition that enables this.</P>
<p>For Xmlrpc-c, we find no reason to exclude this function from the
library, and ifdefs make code harder to maintain, so we include the
function unconditionally. (i.e. -DXML_DTD does nothing).
<P>Expat is an <A
HREF="http://www.w3.org/TR/1998/REC-xml-19980210">XML 1.0</A> parser
written in C. It aims to be fully conforming. It is currently not a
validating XML processor. The current production version of expat 1.X
can be downloaded from <A href =
"ftp://ftp.jclark.com/pub/xml/expat.zip"
>ftp://ftp.jclark.com/pub/xml/expat.zip</A>.</P>
<P>Development of expat 2.0 is being handled by a team led by Clark
Cooper, hosted by <A
href="http://www.sourceforge.net">sourceforge.net</A>. See <A href=
"http://expat.sourceforge.net">http://expat.sourceforge.net</A> for
the latest on expat 2.0.</P>
<P>The directory <SAMP>xmltok</SAMP> contains a low-level library for
tokenizing XML. The interface is documented in
<SAMP>xmltok/xmltok.h</SAMP>.</P>
<P>The directory <SAMP>xmlparse</SAMP> contains an XML parser library
which is built on top of the <SAMP>xmltok</SAMP> library. The
interface is documented in <SAMP>xmlparse/xmlparse.h</SAMP>. The
directory <SAMP>sample</SAMP> contains a simple example program using
this interface; <SAMP>sample/build.bat</SAMP> is a batch file to build
the example using Visual C++.</P>
<P>The directory <SAMP>xmlwf</SAMP> contains the <SAMP>xmlwf</SAMP>
application, which uses the <SAMP>xmlparse</SAMP> library. The
arguments to <SAMP>xmlwf</SAMP> are one or more files which are each
to be checked for well-formedness. An option <SAMP>-d
<VAR>dir</VAR></SAMP> can be specified; for each well-formed input
file the corresponding <A
href="http://www.jclark.com/xml/canonxml.html">canonical XML</A> will
be written to <SAMP>dir/<VAR>f</VAR></SAMP>, where
<SAMP><VAR>f</VAR></SAMP> is the filename (without any path) of the
input file. A <CODE>-x</CODE> option will cause references to
external general entities to be processed. A <CODE>-s</CODE> option
will make documents that are not standalone cause an error (a document
is considered standalone if either it is intrinsically standalone
because it has no external subset and no references to parameter
entities in the internal subset or it is declared as standalone in the
XML declaration).</P>
<P>The <SAMP>bin</SAMP> directory contains Win32 executables. The
<SAMP>lib</SAMP> directory contains Win32 import libraries.</P>
<P>Answers to some frequently asked questions about expat can be found
in the <A
HREF="http://www.jclark.com/xml/expatfaq.html">expat
FAQ</A>.</P>
<P></P>
<ADDRESS>
<A HREF="mailto:jjc@jclark.com">James Clark</A>
</ADDRESS>
</BODY>
</HTML>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,556 @@
/*
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#ifndef XMLPARSE_H_INCLUDED
#define XMLPARSE_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XMLPARSEAPI
#define XMLPARSEAPI /* as nothing */
#endif
typedef void *XML_Parser;
#ifdef XML_UNICODE_WCHAR_T
/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
uses Unicode.
*/
/* Information is UTF-16 encoded as wchar_ts */
#ifndef XML_UNICODE
#define XML_UNICODE
#endif
#include <stddef.h>
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
#else /* not XML_UNICODE_WCHAR_T */
#ifdef XML_UNICODE
/* Information is UTF-16 encoded as unsigned shorts */
typedef unsigned short XML_Char;
typedef char XML_LChar;
#else /* not XML_UNICODE */
/* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* not XML_UNICODE */
#endif /* not XML_UNICODE_WCHAR_T */
/* Constructs a new parser; encoding is the encoding specified by the external
protocol or null if there is none specified. */
XML_Parser XMLPARSEAPI
xmlrpc_XML_ParserCreate(const XML_Char * const encoding);
/* Constructs a new parser and namespace processor. Element type names
and attribute names that belong to a namespace will be expanded;
unprefixed attribute names are never expanded; unprefixed element type
names are expanded only if there is a default namespace. The expanded
name is the concatenation of the namespace URI, the namespace separator character,
and the local part of the name. If the namespace separator is '\0' then
the namespace URI and the local part will be concatenated without any
separator. When a namespace is not declared, the name and prefix will be
passed through without expansion. */
XML_Parser XMLPARSEAPI
xmlrpc_XML_ParserCreateNS(const XML_Char * const encoding,
XML_Char const namespaceSeparator);
/* atts is array of name/value pairs, terminated by 0;
names and values are 0 terminated. */
typedef void (*XML_StartElementHandler)(void *userData,
const XML_Char *name,
const XML_Char **atts);
typedef void (*XML_EndElementHandler)(void *userData,
const XML_Char *name);
/* s is not 0 terminated. */
typedef void (*XML_CharacterDataHandler)(void *userData,
const XML_Char *s,
int len);
/* target and data are 0 terminated */
typedef void (*XML_ProcessingInstructionHandler)(void *userData,
const XML_Char *target,
const XML_Char *data);
/* data is 0 terminated */
typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
typedef void (*XML_StartCdataSectionHandler)(void *userData);
typedef void (*XML_EndCdataSectionHandler)(void *userData);
/* This is called for any characters in the XML document for
which there is no applicable handler. This includes both
characters that are part of markup which is of a kind that is
not reported (comments, markup declarations), or characters
that are part of a construct which could be reported but
for which no handler has been supplied. The characters are passed
exactly as they were in the XML document except that
they will be encoded in UTF-8. Line boundaries are not normalized.
Note that a byte order mark character is not passed to the default handler.
There are no guarantees about how characters are divided between calls
to the default handler: for example, a comment might be split between
multiple calls. */
typedef void (*XML_DefaultHandler)(void *userData,
const XML_Char *s,
int len);
/* This is called for the start of the DOCTYPE declaration when the
name of the DOCTYPE is encountered. */
typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
const XML_Char *doctypeName);
/* This is called for the start of the DOCTYPE declaration when the
closing > is encountered, but after processing any external subset. */
typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
/* This is called for a declaration of an unparsed (NDATA)
entity. The base argument is whatever was set by XML_SetBase.
The entityName, systemId and notationName arguments will never be null.
The other arguments may be. */
typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
/* This is called for a declaration of notation.
The base argument is whatever was set by XML_SetBase.
The notationName will never be null. The other arguments can be. */
typedef void (*XML_NotationDeclHandler)(void *userData,
const XML_Char *notationName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef void (*XML_ExternalParsedEntityDeclHandler)(void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef void (*XML_InternalParsedEntityDeclHandler)(void *userData,
const XML_Char *entityName,
const XML_Char *replacementText,
int replacementTextLength);
/* When namespace processing is enabled, these are called once for
each namespace declaration. The call to the start and end element
handlers occur between the calls to the start and end namespace
declaration handlers. For an xmlns attribute, prefix will be null.
For an xmlns="" attribute, uri will be null. */
typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
const XML_Char *prefix,
const XML_Char *uri);
typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
const XML_Char *prefix);
/* This is called if the document is not standalone (it has an
external subset or a reference to a parameter entity, but does not
have standalone="yes"). If this handler returns 0, then processing
will not continue, and the parser will return a
XML_ERROR_NOT_STANDALONE error. */
typedef int (*XML_NotStandaloneHandler)(void *userData);
/* This is called for a reference to an external parsed general entity.
The referenced entity is not automatically parsed.
The application can parse it immediately or later using
XML_ExternalEntityParserCreate.
The parser argument is the parser parsing the entity containing the reference;
it can be passed as the parser argument to XML_ExternalEntityParserCreate.
The systemId argument is the system identifier as specified in the entity declaration;
it will not be null.
The base argument is the system identifier that should be used as the base for
resolving systemId if systemId was relative; this is set by XML_SetBase;
it may be null.
The publicId argument is the public identifier as specified in the entity declaration,
or null if none was specified; the whitespace in the public identifier
will have been normalized as required by the XML spec.
The context argument specifies the parsing context in the format
expected by the context argument to
XML_ExternalEntityParserCreate; context is valid only until the handler
returns, so if the referenced entity is to be parsed later, it must be copied.
The handler should return 0 if processing should not continue because of
a fatal error in the handling of the external entity.
In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
error.
Note that unlike other handlers the first argument is the parser, not userData. */
typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* This structure is filled in by the XML_UnknownEncodingHandler
to provide information to the parser about encodings that are unknown
to the parser.
The map[b] member gives information about byte sequences
whose first byte is b.
If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
If map[b] is -1, then the byte sequence is malformed.
If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
sequence that encodes a single Unicode scalar value.
The data member will be passed as the first argument to the convert function.
The convert function is used to convert multibyte sequences;
s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
The convert function must return the Unicode scalar value
represented by this byte sequence or -1 if the byte sequence is malformed.
The convert function may be null if the encoding is a single-byte encoding,
that is if map[b] >= -1 for all bytes b.
When the parser is finished with the encoding, then if release is not null,
it will call release passing it the data member;
once release has been called, the convert function will not be called again.
Expat places certain restrictions on the encodings that are supported
using this mechanism.
1. Every ASCII character that can appear in a well-formed XML document,
other than the characters
$@\^`{}~
must be represented by a single byte, and that byte must be the
same byte that represents that character in ASCII.
2. No character may require more than 4 bytes to encode.
3. All characters encoded must have Unicode scalar values <= 0xFFFF,
(ie characters that would be encoded by surrogates in UTF-16
are not allowed). Note that this restriction doesn't apply to
the built-in support for UTF-8 and UTF-16.
4. No Unicode character may be encoded by more than one distinct sequence
of bytes. */
typedef struct {
int map[256];
void *data;
int (*convert)(void *data, const char *s);
void (*release)(void *data);
} XML_Encoding;
/* This is called for an encoding that is unknown to the parser.
The encodingHandlerData argument is that which was passed as the
second argument to XML_SetUnknownEncodingHandler.
The name argument gives the name of the encoding as specified in
the encoding declaration.
If the callback can provide information about the encoding,
it must fill in the XML_Encoding structure, and return 1.
Otherwise it must return 0.
If info does not describe a suitable encoding,
then the parser will return an XML_UNKNOWN_ENCODING error. */
typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info);
void XMLPARSEAPI
xmlrpc_XML_SetElementHandler(XML_Parser parser,
XML_StartElementHandler start,
XML_EndElementHandler end);
void XMLPARSEAPI
xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser,
XML_CharacterDataHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetProcessingInstructionHandler(
XML_Parser parser,
XML_ProcessingInstructionHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end);
/* This sets the default handler and also inhibits expansion of
internal entities. The entity reference will be passed to the default
handler.
*/
void XMLPARSEAPI
xmlrpc_XML_SetDefaultHandler(XML_Parser parser,
XML_DefaultHandler handler);
/* This sets the default handler but does not inhibit expansion of internal entities.
The entity reference will not be passed to the default handler. */
void XMLPARSEAPI
xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser,
XML_DefaultHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start,
XML_EndDoctypeDeclHandler end);
void XMLPARSEAPI
xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
XML_UnparsedEntityDeclHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser,
XML_NotationDeclHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetExternalParsedEntityDeclHandler(
XML_Parser parser,
XML_ExternalParsedEntityDeclHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetInternalParsedEntityDeclHandler(
XML_Parser parser,
XML_InternalParsedEntityDeclHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start,
XML_EndNamespaceDeclHandler end);
void XMLPARSEAPI
xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser,
XML_NotStandaloneHandler handler);
void XMLPARSEAPI
xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser,
XML_ExternalEntityRefHandler handler);
/* If a non-null value for arg is specified here, then it will be
passed as the first argument to the external entity ref handler
instead of the parser object.
*/
void XMLPARSEAPI
xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
void XMLPARSEAPI
xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser,
XML_UnknownEncodingHandler handler,
void *encodingHandlerData);
/* This can be called within a handler for a start element, end element,
processing instruction or character data. It causes the corresponding
markup to be passed to the default handler.
*/
void XMLPARSEAPI
xmlrpc_XML_DefaultCurrent(XML_Parser parser);
/* This value is passed as the userData argument to callbacks. */
void XMLPARSEAPI
xmlrpc_XML_SetUserData(XML_Parser parser, void *userData);
/* Returns the last value set by XML_SetUserData or null. */
#define XML_GetUserData(parser) (*(void **)(parser))
/* This is equivalent to supplying an encoding argument
to XML_ParserCreate. It must not be called after XML_Parse
or XML_ParseBuffer. */
int XMLPARSEAPI
xmlrpc_XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
/* If this function is called, then the parser will be passed
as the first argument to callbacks instead of userData.
The userData will still be accessible using XML_GetUserData.
*/
void XMLPARSEAPI
xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser);
/* Sets the base to be used for resolving relative URIs in system
identifiers in declarations. Resolving relative identifiers is left
to the application: this value will be passed through as the base
argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler
and XML_UnparsedEntityDeclHandler. The base argument will be copied.
Returns zero if out of memory, non-zero otherwise.
*/
int XMLPARSEAPI
xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *base);
const XML_Char XMLPARSEAPI *
xmlrpc_XML_GetBase(XML_Parser parser);
/* Returns the number of the attribute/value pairs passed in last call
to the XML_StartElementHandler that were specified in the start-tag
rather than defaulted. Each attribute/value pair counts as 2; thus
this correspondds to an index into the atts array passed to the
XML_StartElementHandler.
*/
int XMLPARSEAPI
xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser);
/* Returns the index of the ID attribute passed in the last call to
XML_StartElementHandler, or -1 if there is no ID attribute. Each
attribute/value pair counts as 2; thus this correspondds to an index
into the atts array passed to the XML_StartElementHandler.
*/
int XMLPARSEAPI
xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser);
/* Parses some input. Returns 0 if a fatal error is detected.
The last call to XML_Parse must have isFinal true;
len may be zero for this call (or any other).
*/
int XMLPARSEAPI
xmlrpc_XML_Parse(XML_Parser const parser, const char * const s, int const len, int const isFinal);
void XMLPARSEAPI *
xmlrpc_XML_GetBuffer(XML_Parser parser, int len);
int XMLPARSEAPI
xmlrpc_XML_ParseBuffer(XML_Parser const parser, int const len, int const isFinal);
/* Creates an XML_Parser object that can parse an external general
entity; context is a '\0'-terminated string specifying the parse
context; encoding is a '\0'-terminated string giving the name of the
externally specified encoding, or null if there is no externally
specified encoding. The context string consists of a sequence of
tokens separated by formfeeds (\f); a token consisting of a name
specifies that the general entity of the name is open; a token of the
form prefix=uri specifies the namespace for a particular prefix; a
token of the form =uri specifies the default namespace. This can be
called at any point after the first call to an
ExternalEntityRefHandler so longer as the parser has not yet been
freed. The new parser is completely independent and may safely be
used in a separate thread. The handlers and userData are initialized
from the parser argument. Returns 0 if out of memory. Otherwise
returns a new XML_Parser object.
*/
XML_Parser XMLPARSEAPI
xmlrpc_XML_ExternalEntityParserCreate(XML_Parser parser,
const XML_Char *context,
const XML_Char *encoding);
enum XML_ParamEntityParsing {
XML_PARAM_ENTITY_PARSING_NEVER,
XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
XML_PARAM_ENTITY_PARSING_ALWAYS
};
/* Controls parsing of parameter entities (including the external DTD
subset). If parsing of parameter entities is enabled, then references
to external parameter entities (including the external DTD subset)
will be passed to the handler set with
XML_SetExternalEntityRefHandler. The context passed will be 0.
Unlike external general entities, external parameter entities can only
be parsed synchronously. If the external parameter entity is to be
parsed, it must be parsed during the call to the external entity ref
handler: the complete sequence of XML_ExternalEntityParserCreate,
XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
this call. After XML_ExternalEntityParserCreate has been called to
create the parser for the external parameter entity (context must be 0
for this call), it is illegal to make any calls on the old parser
until XML_ParserFree has been called on the newly created parser. If
the library has been compiled without support for parameter entity
parsing (ie without XML_DTD being defined), then
XML_SetParamEntityParsing will return 0 if parsing of parameter
entities is requested; otherwise it will return non-zero.
*/
int XMLPARSEAPI
xmlrpc_XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing parsing);
enum XML_Error {
XML_ERROR_NONE,
XML_ERROR_NO_MEMORY,
XML_ERROR_SYNTAX,
XML_ERROR_NO_ELEMENTS,
XML_ERROR_INVALID_TOKEN,
XML_ERROR_UNCLOSED_TOKEN,
XML_ERROR_PARTIAL_CHAR,
XML_ERROR_TAG_MISMATCH,
XML_ERROR_DUPLICATE_ATTRIBUTE,
XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
XML_ERROR_PARAM_ENTITY_REF,
XML_ERROR_UNDEFINED_ENTITY,
XML_ERROR_RECURSIVE_ENTITY_REF,
XML_ERROR_ASYNC_ENTITY,
XML_ERROR_BAD_CHAR_REF,
XML_ERROR_BINARY_ENTITY_REF,
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
XML_ERROR_MISPLACED_XML_PI,
XML_ERROR_UNKNOWN_ENCODING,
XML_ERROR_INCORRECT_ENCODING,
XML_ERROR_UNCLOSED_CDATA_SECTION,
XML_ERROR_EXTERNAL_ENTITY_HANDLING,
XML_ERROR_NOT_STANDALONE
};
/* If xmlrpc_XML_Parse or xmlrpc_XML_ParseBuffer have returned 0, then
xmlrpc_XML_GetErrorString and xmlrpc_XML_GetErrorCode return
information about the error.
*/
enum XML_Error XMLPARSEAPI
xmlrpc_XML_GetErrorCode(XML_Parser const parser);
const char * XMLPARSEAPI
xmlrpc_XML_GetErrorString(XML_Parser const parser);
/* These functions return information about the current parse location.
They may be called when XML_Parse or XML_ParseBuffer return 0;
in this case the location is the location of the character at which
the error was detected.
They may also be called from any other callback called to report
some parse event; in this the location is the location of the first
of the sequence of characters that generated the event.
*/
int XMLPARSEAPI
xmlrpc_XML_GetCurrentLineNumber(XML_Parser parser);
int XMLPARSEAPI
xmlrpc_XML_GetCurrentColumnNumber(XML_Parser parser);
long XMLPARSEAPI
xmlrpc_XML_GetCurrentByteIndex(XML_Parser parser);
/* Return the number of bytes in the current event.
Returns 0 if the event is in an internal entity. */
int XMLPARSEAPI
xmlrpc_XML_GetCurrentByteCount(XML_Parser parser);
/* For backwards compatibility with previous versions. */
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
/* Frees memory used by the parser. */
void XMLPARSEAPI
xmlrpc_XML_ParserFree(XML_Parser parser);
/* Returns a string describing the error. */
const XML_LChar XMLPARSEAPI *
xmlrpc_XML_ErrorString(int const code);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,86 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#define ASCII_A 0x41
#define ASCII_B 0x42
#define ASCII_C 0x43
#define ASCII_D 0x44
#define ASCII_E 0x45
#define ASCII_F 0x46
#define ASCII_G 0x47
#define ASCII_H 0x48
#define ASCII_I 0x49
#define ASCII_J 0x4A
#define ASCII_K 0x4B
#define ASCII_L 0x4C
#define ASCII_M 0x4D
#define ASCII_N 0x4E
#define ASCII_O 0x4F
#define ASCII_P 0x50
#define ASCII_Q 0x51
#define ASCII_R 0x52
#define ASCII_S 0x53
#define ASCII_T 0x54
#define ASCII_U 0x55
#define ASCII_V 0x56
#define ASCII_W 0x57
#define ASCII_X 0x58
#define ASCII_Y 0x59
#define ASCII_Z 0x5A
#define ASCII_a 0x61
#define ASCII_b 0x62
#define ASCII_c 0x63
#define ASCII_d 0x64
#define ASCII_e 0x65
#define ASCII_f 0x66
#define ASCII_g 0x67
#define ASCII_h 0x68
#define ASCII_i 0x69
#define ASCII_j 0x6A
#define ASCII_k 0x6B
#define ASCII_l 0x6C
#define ASCII_m 0x6D
#define ASCII_n 0x6E
#define ASCII_o 0x6F
#define ASCII_p 0x70
#define ASCII_q 0x71
#define ASCII_r 0x72
#define ASCII_s 0x73
#define ASCII_t 0x74
#define ASCII_u 0x75
#define ASCII_v 0x76
#define ASCII_w 0x77
#define ASCII_x 0x78
#define ASCII_y 0x79
#define ASCII_z 0x7A
#define ASCII_0 0x30
#define ASCII_1 0x31
#define ASCII_2 0x32
#define ASCII_3 0x33
#define ASCII_4 0x34
#define ASCII_5 0x35
#define ASCII_6 0x36
#define ASCII_7 0x37
#define ASCII_8 0x38
#define ASCII_9 0x39
#define ASCII_TAB 0x09
#define ASCII_SPACE 0x20
#define ASCII_EXCL 0x21
#define ASCII_QUOT 0x22
#define ASCII_AMP 0x26
#define ASCII_APOS 0x27
#define ASCII_MINUS 0x2D
#define ASCII_PERIOD 0x2E
#define ASCII_COLON 0x3A
#define ASCII_SEMI 0x3B
#define ASCII_LT 0x3C
#define ASCII_EQUALS 0x3D
#define ASCII_GT 0x3E
#define ASCII_LSQB 0x5B
#define ASCII_RSQB 0x5D
#define ASCII_UNDERSCORE 0x5F

View File

@ -0,0 +1,37 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,

View File

@ -0,0 +1,15 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#define STRICT 1
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}

View File

@ -0,0 +1,38 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,

View File

@ -0,0 +1,37 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,

View File

@ -0,0 +1,150 @@
static const unsigned namingBitmap[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
0x40000000, 0xF580C900, 0x00000007, 0x02010800,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
0x00000000, 0x00004C40, 0x00000000, 0x00000000,
0x00000007, 0x00000000, 0x00000000, 0x00000000,
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
};
static const unsigned char nmstrtPages[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char namePages[] = {
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -0,0 +1,38 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,

View File

@ -0,0 +1,49 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <string.h>
#ifdef XML_WINLIB
#define WIN32_LEAN_AND_MEAN
#ifndef STRICT
#define STRICT 1
#endif
#include <windows.h>
#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y))
#define free(x) HeapFree(GetProcessHeap(), 0, (x))
#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y)
#define abort() /* as nothing */
#else /* not XML_WINLIB */
#include <stdlib.h>
#endif /* not XML_WINLIB */
/* This file can be used for any definitions needed in
particular environments. */
/* Mozilla specific defines */
#ifdef MOZILLA_CLIENT
#include "nspr.h"
#define malloc(x) PR_Malloc((size_t)(x))
#define realloc(x, y) PR_Realloc((x), (size_t)(y))
#define calloc(x, y) PR_Calloc((x),(y))
#define free(x) PR_Free(x)
#if PR_BYTES_PER_INT != 4
#define int int32
#endif
/* Enable Unicode string processing in expat. */
#ifndef XML_UNICODE
#define XML_UNICODE
#endif
#endif /* MOZILLA_CLIENT */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#ifndef XmlRole_INCLUDED
#define XmlRole_INCLUDED 1
#include "xmltok.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
XML_ROLE_ERROR = -1,
XML_ROLE_NONE = 0,
XML_ROLE_XML_DECL,
XML_ROLE_INSTANCE_START,
XML_ROLE_DOCTYPE_NAME,
XML_ROLE_DOCTYPE_SYSTEM_ID,
XML_ROLE_DOCTYPE_PUBLIC_ID,
XML_ROLE_DOCTYPE_CLOSE,
XML_ROLE_GENERAL_ENTITY_NAME,
XML_ROLE_PARAM_ENTITY_NAME,
XML_ROLE_ENTITY_VALUE,
XML_ROLE_ENTITY_SYSTEM_ID,
XML_ROLE_ENTITY_PUBLIC_ID,
XML_ROLE_ENTITY_NOTATION_NAME,
XML_ROLE_NOTATION_NAME,
XML_ROLE_NOTATION_SYSTEM_ID,
XML_ROLE_NOTATION_NO_SYSTEM_ID,
XML_ROLE_NOTATION_PUBLIC_ID,
XML_ROLE_ATTRIBUTE_NAME,
XML_ROLE_ATTRIBUTE_TYPE_CDATA,
XML_ROLE_ATTRIBUTE_TYPE_ID,
XML_ROLE_ATTRIBUTE_TYPE_IDREF,
XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
XML_ROLE_ATTRIBUTE_ENUM_VALUE,
XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
XML_ROLE_ATTLIST_ELEMENT_NAME,
XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
XML_ROLE_FIXED_ATTRIBUTE_VALUE,
XML_ROLE_ELEMENT_NAME,
XML_ROLE_CONTENT_ANY,
XML_ROLE_CONTENT_EMPTY,
XML_ROLE_CONTENT_PCDATA,
XML_ROLE_GROUP_OPEN,
XML_ROLE_GROUP_CLOSE,
XML_ROLE_GROUP_CLOSE_REP,
XML_ROLE_GROUP_CLOSE_OPT,
XML_ROLE_GROUP_CLOSE_PLUS,
XML_ROLE_GROUP_CHOICE,
XML_ROLE_GROUP_SEQUENCE,
XML_ROLE_CONTENT_ELEMENT,
XML_ROLE_CONTENT_ELEMENT_REP,
XML_ROLE_CONTENT_ELEMENT_OPT,
XML_ROLE_CONTENT_ELEMENT_PLUS,
XML_ROLE_TEXT_DECL,
XML_ROLE_IGNORE_SECT,
XML_ROLE_INNER_PARAM_ENTITY_REF,
XML_ROLE_PARAM_ENTITY_REF,
XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION
};
typedef struct prolog_state {
int (*handler)(struct prolog_state *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc);
unsigned level;
unsigned includeLevel;
int documentEntity;
} PROLOG_STATE;
XMLTOKAPI void
xmlrpc_XmlPrologStateInit(PROLOG_STATE * const state);
XMLTOKAPI void
xmlrpc_XmlPrologStateInitExternalEntity(PROLOG_STATE * const state);
#define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))
#ifdef __cplusplus
}
#endif
#endif /* not XmlRole_INCLUDED */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XMLTOKAPI
#define XMLTOKAPI /* as nothing */
#endif
/* The following token may be returned by XmlContentTok */
#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
illegal ]]> sequence */
/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
might be part of CRLF sequence */
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
#define XML_TOK_PARTIAL -1 /* only part of a token */
#define XML_TOK_INVALID 0
/* The following tokens are returned by XmlContentTok; some are also
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
#define XML_TOK_START_TAG_WITH_ATTS 1
#define XML_TOK_START_TAG_NO_ATTS 2
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
#define XML_TOK_END_TAG 5
#define XML_TOK_DATA_CHARS 6
#define XML_TOK_DATA_NEWLINE 7
#define XML_TOK_CDATA_SECT_OPEN 8
#define XML_TOK_ENTITY_REF 9
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
#define XML_TOK_PI 11 /* processing instruction */
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
#define XML_TOK_COMMENT 13
#define XML_TOK_BOM 14 /* Byte order mark */
/* The following tokens are returned only by XmlPrologTok */
#define XML_TOK_PROLOG_S 15
#define XML_TOK_DECL_OPEN 16 /* <!foo */
#define XML_TOK_DECL_CLOSE 17 /* > */
#define XML_TOK_NAME 18
#define XML_TOK_NMTOKEN 19
#define XML_TOK_POUND_NAME 20 /* #name */
#define XML_TOK_OR 21 /* | */
#define XML_TOK_PERCENT 22
#define XML_TOK_OPEN_PAREN 23
#define XML_TOK_CLOSE_PAREN 24
#define XML_TOK_OPEN_BRACKET 25
#define XML_TOK_CLOSE_BRACKET 26
#define XML_TOK_LITERAL 27
#define XML_TOK_PARAM_ENTITY_REF 28
#define XML_TOK_INSTANCE_START 29
/* The following occur only in element type declarations */
#define XML_TOK_NAME_QUESTION 30 /* name? */
#define XML_TOK_NAME_ASTERISK 31 /* name* */
#define XML_TOK_NAME_PLUS 32 /* name+ */
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
#define XML_TOK_COMMA 38
/* The following token is returned only by XmlAttributeValueTok */
#define XML_TOK_ATTRIBUTE_VALUE_S 39
/* The following token is returned only by XmlCdataSectionTok */
#define XML_TOK_CDATA_SECT_CLOSE 40
/* With namespace processing this is returned by XmlPrologTok
for a name with a colon. */
#define XML_TOK_PREFIXED_NAME 41
#define XML_TOK_IGNORE_SECT 42
#define XML_N_STATES 4
#define XML_PROLOG_STATE 0
#define XML_CONTENT_STATE 1
#define XML_CDATA_SECTION_STATE 2
#define XML_IGNORE_SECTION_STATE 3
#define XML_N_LITERAL_TYPES 2
#define XML_ATTRIBUTE_VALUE_LITERAL 0
#define XML_ENTITY_VALUE_LITERAL 1
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
#define XML_UTF8_ENCODE_MAX 4
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
#define XML_UTF16_ENCODE_MAX 2
typedef struct position {
/* first line and first column are 0 not 1 */
unsigned long lineNumber;
unsigned long columnNumber;
} POSITION;
typedef struct {
const char *name;
const char *valuePtr;
const char *valueEnd;
char normalized;
} ATTRIBUTE;
struct encoding;
typedef struct encoding ENCODING;
struct encoding {
int (*scanners[XML_N_STATES])(const ENCODING *,
const char *,
const char *,
const char **);
int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
const char *,
const char *,
const char **);
int (*sameName)(const ENCODING *,
const char *, const char *);
int (*nameMatchesAscii)(const ENCODING *,
const char *, const char *, const char *);
int (*nameLength)(const ENCODING *, const char *);
const char *(*skipS)(const ENCODING *, const char *);
int (*getAtts)(const ENCODING *enc, const char *ptr,
int attsMax, ATTRIBUTE *atts);
int (*charRefNumber)(const ENCODING *enc, const char *ptr);
int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
void (*updatePosition)(const ENCODING *,
const char *ptr,
const char *end,
POSITION *);
int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
const char **badPtr);
void (*utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
char **toP,
const char *toLim);
void (*utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
};
/*
Scan the string starting at ptr until the end of the next complete token,
but do not scan past eptr. Return an integer giving the type of token.
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
Return XML_TOK_PARTIAL when the string does not contain a complete token;
nextTokPtr will not be set.
Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
will be set to point to the character which made the token invalid.
Otherwise the string starts with a valid token; nextTokPtr will be set to point
to the character following the end of that token.
Each data character counts as a single token, but adjacent data characters
may be returned together. Similarly for characters in the prolog outside
literals, comments and processing instructions.
*/
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
/* This is used for performing a 2nd-level tokenization on
the content of a literal that has already been returned by XmlTok. */
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
#define XmlNameLength(enc, ptr) \
(((enc)->nameLength)(enc, ptr))
#define XmlSkipS(enc, ptr) \
(((enc)->skipS)(enc, ptr))
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
(((enc)->getAtts)(enc, ptr, attsMax, atts))
#define XmlCharRefNumber(enc, ptr) \
(((enc)->charRefNumber)(enc, ptr))
#define XmlPredefinedEntityName(enc, ptr, end) \
(((enc)->predefinedEntityName)(enc, ptr, end))
#define XmlUpdatePosition(enc, ptr, end, pos) \
(((enc)->updatePosition)(enc, ptr, end, pos))
#define XmlIsPublicId(enc, ptr, end, badPtr) \
(((enc)->isPublicId)(enc, ptr, end, badPtr))
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
typedef struct {
ENCODING initEnc;
const ENCODING **encPtr;
} INIT_ENCODING;
XMLTOKAPI int
xmlrpc_XmlParseXmlDecl(int const isGeneralTextEntity,
const ENCODING * const enc,
const char * const ptr,
const char * const end,
const char ** const badPtr,
const char ** const versionPtr,
const char ** const encodingNamePtr,
const ENCODING ** const namedEncodingPtr,
int * const standalonePtr);
XMLTOKAPI const ENCODING *
xmlrpc_XmlGetUtf8InternalEncoding(void);
XMLTOKAPI const ENCODING *
xmlrpc_XmlGetUtf16InternalEncoding(void);
XMLTOKAPI int
xmlrpc_XmlInitEncoding(INIT_ENCODING * const p,
const ENCODING ** const encPtr,
const char * const name);
XMLTOKAPI int
xmlrpc_XmlUtf8Encode(int const c,
char * const buf);
XMLTOKAPI int
xmlrpc_XmlUtf16Encode(int const charNum,
unsigned short * const buf);
XMLTOKAPI int
xmlrpc_XmlSizeOfUnknownEncoding(void);
XMLTOKAPI ENCODING *
xmlrpc_XmlInitUnknownEncoding(void * const mem,
int * const table,
int (*convert)(void *userData, const char *p),
void * const userData);
int
xmlrpc_XmlParseXmlDeclNS(int const isGeneralTextEntity,
const ENCODING * const enc,
const char * const ptr,
const char * const end,
const char ** const badPtr,
const char ** const versionPtr,
const char ** const encodingNamePtr,
const ENCODING ** const namedEncodingPtr,
int * const standalonePtr);
int
xmlrpc_XmlInitEncodingNS(INIT_ENCODING * const p,
const ENCODING ** const encPtr,
const char * const name);
const ENCODING *
xmlrpc_XmlGetUtf8InternalEncodingNS(void);
const ENCODING *
xmlrpc_XmlGetUtf16InternalEncodingNS(void);
ENCODING *
xmlrpc_XmlInitUnknownEncodingNS(void * const mem,
int * const table,
int (*convert)(void *userData, const char *p),
void * const userData);
#ifdef __cplusplus
}
#endif
#endif /* not XmlTok_INCLUDED */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
enum {
BT_NONXML,
BT_MALFORM,
BT_LT,
BT_AMP,
BT_RSQB,
BT_LEAD2,
BT_LEAD3,
BT_LEAD4,
BT_TRAIL,
BT_CR,
BT_LF,
BT_GT,
BT_QUOT,
BT_APOS,
BT_EQUALS,
BT_QUEST,
BT_EXCL,
BT_SOL,
BT_SEMI,
BT_NUM,
BT_LSQB,
BT_S,
BT_NMSTRT,
BT_COLON,
BT_HEX,
BT_DIGIT,
BT_NAME,
BT_MINUS,
BT_OTHER, /* known not to be a name or name start character */
BT_NONASCII, /* might be a name or name start character */
BT_PERCNT,
BT_LPAR,
BT_RPAR,
BT_AST,
BT_PLUS,
BT_COMMA,
BT_VERBAR
};
#include <stddef.h>

View File

@ -0,0 +1,112 @@
const ENCODING *
NS(xmlrpc_XmlGetUtf8InternalEncoding)(void) {
return &ns(internal_utf8_encoding).enc;
}
const ENCODING *
NS(xmlrpc_XmlGetUtf16InternalEncoding)(void) {
#if XML_BYTE_ORDER == 12
return &ns(internal_little2_encoding).enc;
#elif XML_BYTE_ORDER == 21
return &ns(internal_big2_encoding).enc;
#else
const short n = 1;
return *(const char *)&n ?
&ns(internal_little2_encoding).enc :
&ns(internal_big2_encoding).enc;
#endif
}
static
const ENCODING *NS(encodings)[] = {
&ns(latin1_encoding).enc,
&ns(ascii_encoding).enc,
&ns(utf8_encoding).enc,
&ns(big2_encoding).enc,
&ns(big2_encoding).enc,
&ns(little2_encoding).enc,
&ns(utf8_encoding).enc /* NO_ENC */
};
static
int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
}
static
int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
}
int
NS(xmlrpc_XmlInitEncoding)(INIT_ENCODING * const p,
const ENCODING ** const encPtr,
const char * const name) {
int i = getEncodingIndex(name);
if (i == UNKNOWN_ENC)
return 0;
SET_INIT_ENC_INDEX(p, i);
p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
p->initEnc.updatePosition = initUpdatePosition;
p->encPtr = encPtr;
*encPtr = &(p->initEnc);
return 1;
}
static
const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
{
#define ENCODING_MAX 128
char buf[ENCODING_MAX];
char *p = buf;
int i;
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
if (ptr != end)
return 0;
*p = 0;
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
return enc;
i = getEncodingIndex(buf);
if (i == UNKNOWN_ENC)
return 0;
return NS(encodings)[i];
}
int
NS(xmlrpc_XmlParseXmlDecl)(int const isGeneralTextEntity,
const ENCODING * const enc,
const char * const ptr,
const char * const end,
const char ** const badPtr,
const char ** const versionPtr,
const char ** const encodingName,
const ENCODING ** const encoding,
int * const standalone) {
return doParseXmlDecl(NS(findEncoding),
isGeneralTextEntity,
enc,
ptr,
end,
badPtr,
versionPtr,
encodingName,
encoding,
standalone);
}

View File

@ -0,0 +1,209 @@
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
ABYSS_SUBDIR = @ABYSS_SUBDIR@
AS = @AS@
ASYNCH_CLIENT = @ASYNCH_CLIENT@
AUTH_CLIENT = @AUTH_CLIENT@
AVAILABLE_MODULES = @AVAILABLE_MODULES@
CC = @CC@
CC_WARN_FLAGS = @CC_WARN_FLAGS@
CLIENTTEST = @CLIENTTEST@
CONFIGURE_DATE = @CONFIGURE_DATE@
CPPTEST = @CPPTEST@
CPP_WARN_FLAGS = @CPP_WARN_FLAGS@
CXX = @CXX@
DLLTOOL = @DLLTOOL@
EFRPCTEST = @EFRPCTEST@
EFRPCTEST_WRAPPER = @EFRPCTEST_WRAPPER@
INTEROP_CGI = @INTEROP_CGI@
INTEROP_CLIENT_SUBDIR = @INTEROP_CLIENT_SUBDIR@
LIBTOOL = @LIBTOOL@
LIBWWW_CFLAGS = @LIBWWW_CFLAGS@
LIBWWW_CONFIG = @LIBWWW_CONFIG@
LIBWWW_LDADD = @LIBWWW_LDADD@
LIBWWW_LIBDIR = @LIBWWW_LIBDIR@
LIBWWW_RPATH = @LIBWWW_RPATH@
LIBWWW_WL_RPATH = @LIBWWW_WL_RPATH@
LIBXMLRPC_ABYSS_SERVER_LA = @LIBXMLRPC_ABYSS_SERVER_LA@
LIBXMLRPC_CGI_LA = @LIBXMLRPC_CGI_LA@
LIBXMLRPC_CLIENT_LA = @LIBXMLRPC_CLIENT_LA@
LIBXMLRPC_CPP_A = @LIBXMLRPC_CPP_A@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
MEERKAT_APP_LIST = @MEERKAT_APP_LIST@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
QUERY_MEERKAT = @QUERY_MEERKAT@
RANLIB = @RANLIB@
SAMPLE_CGI_CGI = @SAMPLE_CGI_CGI@
SERVER = @SERVER@
SERVERTEST = @SERVERTEST@
SYNCH_CLIENT = @SYNCH_CLIENT@
VALIDATEE = @VALIDATEE@
VERSION = @VERSION@
VERSION_INFO = @VERSION_INFO@
XMLRPCCPP_H = @XMLRPCCPP_H@
XMLRPC_ABYSS_H = @XMLRPC_ABYSS_H@
XMLRPC_CGI_H = @XMLRPC_CGI_H@
XMLRPC_CLIENT_H = @XMLRPC_CLIENT_H@
XML_RPC_API2CPP_SUBDIR = @XML_RPC_API2CPP_SUBDIR@
EXTRA_DIST = codepage.c filemap.h unixfilemap.c xmlfile.c xmltchar.h xmlwf.dsp codepage.h readfilemap.c win32filemap.c xmlfile.h xmlwf.c
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../../xmlrpc_config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = lib/expat/xmlwf
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: tags distdir info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,65 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include "codepage.h"
#ifdef WIN32
#define STRICT 1
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
int codepageMap(int cp, int *map)
{
int i;
CPINFO info;
if (!GetCPInfo(cp, &info) || info.MaxCharSize > 2)
return 0;
for (i = 0; i < 256; i++)
map[i] = -1;
if (info.MaxCharSize > 1) {
for (i = 0; i < MAX_LEADBYTES; i++) {
int j, lim;
if (info.LeadByte[i] == 0 && info.LeadByte[i + 1] == 0)
break;
lim = info.LeadByte[i + 1];
for (j = info.LeadByte[i]; j < lim; j++)
map[j] = -2;
}
}
for (i = 0; i < 256; i++) {
if (map[i] == -1) {
char c = i;
unsigned short n;
if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
&c, 1, &n, 1) == 1)
map[i] = n;
}
}
return 1;
}
int codepageConvert(int cp, const char *p)
{
unsigned short c;
if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
p, 2, &c, 1) == 1)
return c;
return -1;
}
#else /* not WIN32 */
int codepageMap(int cp, int *map)
{
return 0;
}
int codepageConvert(int cp, const char *p)
{
return -1;
}
#endif /* not WIN32 */

View File

@ -0,0 +1,7 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
int codepageMap(int cp, int *map);
int codepageConvert(int cp, const char *p);

View File

@ -0,0 +1,17 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <stddef.h>
#ifdef XML_UNICODE
int filemap(const wchar_t *name,
void (*processor)(const void *, size_t, const wchar_t *, void *arg),
void *arg);
#else
int filemap(const char *name,
void (*processor)(const void *, size_t, const char *, void *arg),
void *arg);
#endif

View File

@ -0,0 +1,74 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef S_ISREG
#ifndef S_IFREG
#define S_IFREG _S_IFREG
#endif
#ifndef S_IFMT
#define S_IFMT _S_IFMT
#endif
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif /* not S_ISREG */
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif
int filemap(const char *name,
void (*processor)(const void *, size_t, const char *, void *arg),
void *arg)
{
size_t nbytes;
int fd;
int n;
struct stat sb;
void *p;
fd = open(name, O_RDONLY|O_BINARY);
if (fd < 0) {
perror(name);
return 0;
}
if (fstat(fd, &sb) < 0) {
perror(name);
return 0;
}
if (!S_ISREG(sb.st_mode)) {
fprintf(stderr, "%s: not a regular file\n", name);
return 0;
}
nbytes = sb.st_size;
p = malloc(nbytes);
if (!p) {
fprintf(stderr, "%s: out of memory\n", name);
return 0;
}
n = read(fd, p, nbytes);
if (n < 0) {
perror(name);
close(fd);
return 0;
}
if (n != nbytes) {
fprintf(stderr, "%s: read unexpected number of bytes\n", name);
close(fd);
return 0;
}
processor(p, nbytes, name, arg);
free(p);
close(fd);
return 1;
}

View File

@ -0,0 +1,57 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
#include "filemap.h"
int filemap(const char *name,
void (*processor)(const void *, size_t, const char *, void *arg),
void *arg)
{
int fd;
size_t nbytes;
struct stat sb;
void *p;
fd = open(name, O_RDONLY);
if (fd < 0) {
perror(name);
return 0;
}
if (fstat(fd, &sb) < 0) {
perror(name);
close(fd);
return 0;
}
if (!S_ISREG(sb.st_mode)) {
close(fd);
fprintf(stderr, "%s: not a regular file\n", name);
return 0;
}
nbytes = sb.st_size;
p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ,
MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
if (p == (void *)-1) {
perror(name);
close(fd);
return 0;
}
processor(p, nbytes, name, arg);
munmap((caddr_t)p, nbytes);
close(fd);
return 1;
}

View File

@ -0,0 +1,95 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#define STRICT 1
#define WIN32_LEAN_AND_MEAN 1
#ifdef XML_UNICODE_WCHAR_T
#ifndef XML_UNICODE
#define XML_UNICODE
#endif
#endif
#ifdef XML_UNICODE
#define UNICODE
#define _UNICODE
#endif /* XML_UNICODE */
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "filemap.h"
static void win32perror(const TCHAR *);
int filemap(const TCHAR *name,
void (*processor)(const void *, size_t, const TCHAR *, void *arg),
void *arg)
{
HANDLE f;
HANDLE m;
DWORD size;
DWORD sizeHi;
void *p;
f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (f == INVALID_HANDLE_VALUE) {
win32perror(name);
return 0;
}
size = GetFileSize(f, &sizeHi);
if (size == (DWORD)-1) {
win32perror(name);
return 0;
}
if (sizeHi) {
_ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name);
return 0;
}
/* CreateFileMapping barfs on zero length files */
if (size == 0) {
static const char c = '\0';
processor(&c, 0, name, arg);
CloseHandle(f);
return 1;
}
m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
if (m == NULL) {
win32perror(name);
CloseHandle(f);
return 0;
}
p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
if (p == NULL) {
win32perror(name);
CloseHandle(m);
CloseHandle(f);
return 0;
}
processor(p, size, name, arg);
UnmapViewOfFile(p);
CloseHandle(m);
CloseHandle(f);
return 1;
}
static
void win32perror(const TCHAR *s)
{
LPVOID buf;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &buf,
0,
NULL)) {
_ftprintf(stderr, _T("%s: %s"), s, buf);
fflush(stderr);
LocalFree(buf);
}
else
_ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
}

View File

@ -0,0 +1,217 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <fcntl.h>
#include "xmlparse.h"
#include "xmlfile.h"
#include "xmltchar.h"
#include "filemap.h"
#if MSVCRT
#include <io.h>
#endif
#ifdef _POSIX_SOURCE
#include <unistd.h>
#endif
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif
#ifdef _DEBUG
#define READ_SIZE 16
#else
#define READ_SIZE (1024*8)
#endif
typedef struct {
XML_Parser parser;
int *retPtr;
} PROCESS_ARGS;
static
void reportError(XML_Parser parser, const XML_Char *filename)
{
int code = XML_GetErrorCode(parser);
const XML_Char *message = XML_ErrorString(code);
if (message)
ftprintf(stdout, T("%s:%d:%d: %s\n"),
filename,
XML_GetErrorLineNumber(parser),
XML_GetErrorColumnNumber(parser),
message);
else
ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
}
static
void processFile(const void *data,
size_t size,
const XML_Char *filename,
void *args)
{
XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
if (!XML_Parse(parser, data, size, 1)) {
reportError(parser, filename);
*retPtr = 0;
}
else
*retPtr = 1;
}
#ifdef WIN32
static
int isAsciiLetter(XML_Char c)
{
return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
}
#endif /* WIN32 */
static
const XML_Char *resolveSystemId(const XML_Char *base, const XML_Char *systemId, XML_Char **toFree)
{
XML_Char *s;
*toFree = 0;
if (!base
|| *systemId == T('/')
#ifdef WIN32
|| *systemId == T('\\')
|| (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
#endif
)
return systemId;
*toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char));
if (!*toFree)
return systemId;
tcscpy(*toFree, base);
s = *toFree;
if (tcsrchr(s, T('/')))
s = tcsrchr(s, T('/')) + 1;
#ifdef WIN32
if (tcsrchr(s, T('\\')))
s = tcsrchr(s, T('\\')) + 1;
#endif
tcscpy(s, systemId);
return *toFree;
}
static
int externalEntityRefFilemap(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId)
{
int result;
XML_Char *s;
const XML_Char *filename;
XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
PROCESS_ARGS args;
args.retPtr = &result;
args.parser = entParser;
filename = resolveSystemId(base, systemId, &s);
XML_SetBase(entParser, filename);
if (!filemap(filename, processFile, &args))
result = 0;
free(s);
XML_ParserFree(entParser);
return result;
}
static
int processStream(const XML_Char *filename, XML_Parser parser)
{
int fd = topen(filename, O_BINARY|O_RDONLY);
if (fd < 0) {
tperror(filename);
return 0;
}
for (;;) {
int nread;
char *buf = XML_GetBuffer(parser, READ_SIZE);
if (!buf) {
close(fd);
ftprintf(stderr, T("%s: out of memory\n"), filename);
return 0;
}
nread = read(fd, buf, READ_SIZE);
if (nread < 0) {
tperror(filename);
close(fd);
return 0;
}
if (!XML_ParseBuffer(parser, nread, nread == 0)) {
reportError(parser, filename);
close(fd);
return 0;
}
if (nread == 0) {
close(fd);
break;;
}
}
return 1;
}
static
int externalEntityRefStream(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId)
{
XML_Char *s;
const XML_Char *filename;
int ret;
XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
filename = resolveSystemId(base, systemId, &s);
XML_SetBase(entParser, filename);
ret = processStream(filename, entParser);
free(s);
XML_ParserFree(entParser);
return ret;
}
int XML_ProcessFile(XML_Parser parser,
const XML_Char *filename,
unsigned flags)
{
int result;
if (!XML_SetBase(parser, filename)) {
ftprintf(stderr, T("%s: out of memory"), filename);
exit(1);
}
if (flags & XML_EXTERNAL_ENTITIES)
XML_SetExternalEntityRefHandler(parser,
(flags & XML_MAP_FILE)
? externalEntityRefFilemap
: externalEntityRefStream);
if (flags & XML_MAP_FILE) {
PROCESS_ARGS args;
args.retPtr = &result;
args.parser = parser;
if (!filemap(filename, processFile, &args))
result = 0;
}
else
result = processStream(filename, parser);
return result;
}

View File

@ -0,0 +1,11 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#define XML_MAP_FILE 01
#define XML_EXTERNAL_ENTITIES 02
extern int XML_ProcessFile(XML_Parser parser,
const XML_Char *filename,
unsigned flags);

View File

@ -0,0 +1,36 @@
#ifdef XML_UNICODE
#ifndef XML_UNICODE_WCHAR_T
#error xmlwf requires a 16-bit Unicode-compatible wchar_t
#endif
#define T(x) L ## x
#define ftprintf fwprintf
#define tfopen _wfopen
#define fputts fputws
#define puttc putwc
#define tcscmp wcscmp
#define tcscpy wcscpy
#define tcscat wcscat
#define tcschr wcschr
#define tcsrchr wcsrchr
#define tcslen wcslen
#define tperror _wperror
#define topen _wopen
#define tmain wmain
#define tremove _wremove
#else /* not XML_UNICODE */
#define T(x) x
#define ftprintf fprintf
#define tfopen fopen
#define fputts fputs
#define puttc putc
#define tcscmp strcmp
#define tcscpy strcpy
#define tcscat strcat
#define tcschr strchr
#define tcsrchr strrchr
#define tcslen strlen
#define tperror perror
#define topen open
#define tmain main
#define tremove remove
#endif /* not XML_UNICODE */

View File

@ -0,0 +1,766 @@
/*
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file copying.txt for copying permission.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "xmlparse.h"
#include "codepage.h"
#include "xmlfile.h"
#include "xmltchar.h"
#if MSVCRT
#include <crtdbg.h>
#endif
/* This ensures proper sorting. */
#define NSSEP T('\001')
static void characterData(void *userData, const XML_Char *s, int len)
{
FILE *fp = userData;
for (; len > 0; --len, ++s) {
switch (*s) {
case T('&'):
fputts(T("&amp;"), fp);
break;
case T('<'):
fputts(T("&lt;"), fp);
break;
case T('>'):
fputts(T("&gt;"), fp);
break;
#ifdef W3C14N
case 13:
fputts(T("&#xD;"), fp);
break;
#else
case T('"'):
fputts(T("&quot;"), fp);
break;
case 9:
case 10:
case 13:
ftprintf(fp, T("&#%d;"), *s);
break;
#endif
default:
puttc(*s, fp);
break;
}
}
}
static void attributeValue(FILE *fp, const XML_Char *s)
{
puttc(T('='), fp);
puttc(T('"'), fp);
for (;;) {
switch (*s) {
case 0:
case NSSEP:
puttc(T('"'), fp);
return;
case T('&'):
fputts(T("&amp;"), fp);
break;
case T('<'):
fputts(T("&lt;"), fp);
break;
case T('"'):
fputts(T("&quot;"), fp);
break;
#ifdef W3C14N
case 9:
fputts(T("&#x9;"), fp);
break;
case 10:
fputts(T("&#xA;"), fp);
break;
case 13:
fputts(T("&#xD;"), fp);
break;
#else
case T('>'):
fputts(T("&gt;"), fp);
break;
case 9:
case 10:
case 13:
ftprintf(fp, T("&#%d;"), *s);
break;
#endif
default:
puttc(*s, fp);
break;
}
s++;
}
}
/* Lexicographically comparing UTF-8 encoded attribute values,
is equivalent to lexicographically comparing based on the character number. */
static int attcmp(const void *att1, const void *att2)
{
return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
}
static void startElement(void *userData, const XML_Char *name, const XML_Char **atts)
{
int nAtts;
const XML_Char **p;
FILE *fp = userData;
puttc(T('<'), fp);
fputts(name, fp);
p = atts;
while (*p)
++p;
nAtts = (p - atts) >> 1;
if (nAtts > 1)
qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
while (*atts) {
puttc(T(' '), fp);
fputts(*atts++, fp);
attributeValue(fp, *atts);
atts++;
}
puttc(T('>'), fp);
}
static void endElement(void *userData, const XML_Char *name)
{
FILE *fp = userData;
puttc(T('<'), fp);
puttc(T('/'), fp);
fputts(name, fp);
puttc(T('>'), fp);
}
static int nsattcmp(const void *p1, const void *p2)
{
const XML_Char *att1 = *(const XML_Char **)p1;
const XML_Char *att2 = *(const XML_Char **)p2;
int sep1 = (tcsrchr(att1, NSSEP) != 0);
int sep2 = (tcsrchr(att1, NSSEP) != 0);
if (sep1 != sep2)
return sep1 - sep2;
return tcscmp(att1, att2);
}
static void startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
{
int nAtts;
int nsi;
const XML_Char **p;
FILE *fp = userData;
const XML_Char *sep;
puttc(T('<'), fp);
sep = tcsrchr(name, NSSEP);
if (sep) {
fputts(T("n1:"), fp);
fputts(sep + 1, fp);
fputts(T(" xmlns:n1"), fp);
attributeValue(fp, name);
nsi = 2;
}
else {
fputts(name, fp);
nsi = 1;
}
p = atts;
while (*p)
++p;
nAtts = (p - atts) >> 1;
if (nAtts > 1)
qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
while (*atts) {
name = *atts++;
sep = tcsrchr(name, NSSEP);
puttc(T(' '), fp);
if (sep) {
ftprintf(fp, T("n%d:"), nsi);
fputts(sep + 1, fp);
}
else
fputts(name, fp);
attributeValue(fp, *atts);
if (sep) {
ftprintf(fp, T(" xmlns:n%d"), nsi++);
attributeValue(fp, name);
}
atts++;
}
puttc(T('>'), fp);
}
static void endElementNS(void *userData, const XML_Char *name)
{
FILE *fp = userData;
const XML_Char *sep;
puttc(T('<'), fp);
puttc(T('/'), fp);
sep = tcsrchr(name, NSSEP);
if (sep) {
fputts(T("n1:"), fp);
fputts(sep + 1, fp);
}
else
fputts(name, fp);
puttc(T('>'), fp);
}
#ifndef W3C14N
static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data)
{
FILE *fp = userData;
puttc(T('<'), fp);
puttc(T('?'), fp);
fputts(target, fp);
puttc(T(' '), fp);
fputts(data, fp);
puttc(T('?'), fp);
puttc(T('>'), fp);
}
#endif /* not W3C14N */
static void defaultCharacterData(XML_Parser parser, const XML_Char *s, int len)
{
XML_DefaultCurrent(parser);
}
static void defaultStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
{
XML_DefaultCurrent(parser);
}
static void defaultEndElement(XML_Parser parser, const XML_Char *name)
{
XML_DefaultCurrent(parser);
}
static void defaultProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
{
XML_DefaultCurrent(parser);
}
static void nopCharacterData(XML_Parser parser, const XML_Char *s, int len)
{
}
static void nopStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
{
}
static void nopEndElement(XML_Parser parser, const XML_Char *name)
{
}
static void nopProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
{
}
static void markup(XML_Parser parser, const XML_Char *s, int len)
{
FILE *fp = XML_GetUserData(parser);
for (; len > 0; --len, ++s)
puttc(*s, fp);
}
static
void metaLocation(XML_Parser parser)
{
const XML_Char *uri = XML_GetBase(parser);
if (uri)
ftprintf(XML_GetUserData(parser), T(" uri=\"%s\""), uri);
ftprintf(XML_GetUserData(parser),
T(" byte=\"%ld\" nbytes=\"%d\" line=\"%d\" col=\"%d\""),
XML_GetCurrentByteIndex(parser),
XML_GetCurrentByteCount(parser),
XML_GetCurrentLineNumber(parser),
XML_GetCurrentColumnNumber(parser));
}
static
void metaStartDocument(XML_Parser parser)
{
fputts(T("<document>\n"), XML_GetUserData(parser));
}
static
void metaEndDocument(XML_Parser parser)
{
fputts(T("</document>\n"), XML_GetUserData(parser));
}
static
void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts)
{
FILE *fp = XML_GetUserData(parser);
const XML_Char **specifiedAttsEnd
= atts + XML_GetSpecifiedAttributeCount(parser);
const XML_Char **idAttPtr;
int idAttIndex = XML_GetIdAttributeIndex(parser);
if (idAttIndex < 0)
idAttPtr = 0;
else
idAttPtr = atts + idAttIndex;
ftprintf(fp, T("<starttag name=\"%s\""), name);
metaLocation(parser);
if (*atts) {
fputts(T(">\n"), fp);
do {
ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
characterData(fp, atts[1], tcslen(atts[1]));
if (atts >= specifiedAttsEnd)
fputts(T("\" defaulted=\"yes\"/>\n"), fp);
else if (atts == idAttPtr)
fputts(T("\" id=\"yes\"/>\n"), fp);
else
fputts(T("\"/>\n"), fp);
} while (*(atts += 2));
fputts(T("</starttag>\n"), fp);
}
else
fputts(T("/>\n"), fp);
}
static
void metaEndElement(XML_Parser parser, const XML_Char *name)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<endtag name=\"%s\""), name);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
characterData(fp, data, tcslen(data));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaComment(XML_Parser parser, const XML_Char *data)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<comment data=\""), fp);
characterData(fp, data, tcslen(data));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaStartCdataSection(XML_Parser parser)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<startcdata"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaEndCdataSection(XML_Parser parser)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<endcdata"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaCharacterData(XML_Parser parser, const XML_Char *s, int len)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<chars str=\""), fp);
characterData(fp, s, len);
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaStartDoctypeDecl(XML_Parser parser, const XML_Char *doctypeName)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaEndDoctypeDecl(XML_Parser parser)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<enddoctype"), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaUnparsedEntityDecl(XML_Parser parser,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<entity name=\"%s\""), entityName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
fputts(T(" system=\""), fp);
characterData(fp, systemId, tcslen(systemId));
puttc(T('"'), fp);
ftprintf(fp, T(" notation=\"%s\""), notationName);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaNotationDecl(XML_Parser parser,
const XML_Char *notationName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<notation name=\"%s\""), notationName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
if (systemId) {
fputts(T(" system=\""), fp);
characterData(fp, systemId, tcslen(systemId));
puttc(T('"'), fp);
}
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaExternalParsedEntityDecl(XML_Parser parser,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<entity name=\"%s\""), entityName);
if (publicId)
ftprintf(fp, T(" public=\"%s\""), publicId);
fputts(T(" system=\""), fp);
characterData(fp, systemId, tcslen(systemId));
puttc(T('"'), fp);
metaLocation(parser);
fputts(T("/>\n"), fp);
}
static
void metaInternalParsedEntityDecl(XML_Parser parser,
const XML_Char *entityName,
const XML_Char *text,
int textLen)
{
FILE *fp = XML_GetUserData(parser);
ftprintf(fp, T("<entity name=\"%s\""), entityName);
metaLocation(parser);
puttc(T('>'), fp);
characterData(fp, text, textLen);
fputts(T("</entity/>\n"), fp);
}
static
void metaStartNamespaceDecl(XML_Parser parser,
const XML_Char *prefix,
const XML_Char *uri)
{
FILE *fp = XML_GetUserData(parser);
fputts(T("<startns"), fp);
if (prefix)
ftprintf(fp, T(" prefix=\"%s\""), prefix);
if (uri) {
fputts(T(" ns=\""), fp);
characterData(fp, uri, tcslen(uri));
fputts(T("\"/>\n"), fp);
}
else
fputts(T("/>\n"), fp);
}
static
void metaEndNamespaceDecl(XML_Parser parser, const XML_Char *prefix)
{
FILE *fp = XML_GetUserData(parser);
if (!prefix)
fputts(T("<endns/>\n"), fp);
else
ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
}
static
int unknownEncodingConvert(void *data, const char *p)
{
return codepageConvert(*(int *)data, p);
}
static
int unknownEncoding(void *userData,
const XML_Char *name,
XML_Encoding *info)
{
int cp;
static const XML_Char prefixL[] = T("windows-");
static const XML_Char prefixU[] = T("WINDOWS-");
int i;
for (i = 0; prefixU[i]; i++)
if (name[i] != prefixU[i] && name[i] != prefixL[i])
return 0;
cp = 0;
for (; name[i]; i++) {
static const XML_Char digits[] = T("0123456789");
const XML_Char *s = tcschr(digits, name[i]);
if (!s)
return 0;
cp *= 10;
cp += s - digits;
if (cp >= 0x10000)
return 0;
}
if (!codepageMap(cp, info->map))
return 0;
info->convert = unknownEncodingConvert;
/* We could just cast the code page integer to a void *,
and avoid the use of release. */
info->release = free;
info->data = malloc(sizeof(int));
if (!info->data)
return 0;
*(int *)info->data = cp;
return 1;
}
static
int notStandalone(void *userData)
{
return 0;
}
static
void usage(const XML_Char *prog)
{
ftprintf(stderr, T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog);
exit(1);
}
int tmain(int argc, XML_Char **argv)
{
int i, j;
const XML_Char *outputDir = 0;
const XML_Char *encoding = 0;
unsigned processFlags = XML_MAP_FILE;
int windowsCodePages = 0;
int outputType = 0;
int useNamespaces = 0;
int requireStandalone = 0;
int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#if MSVCRT
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
#endif
i = 1;
j = 0;
while (i < argc) {
if (j == 0) {
if (argv[i][0] != T('-'))
break;
if (argv[i][1] == T('-') && argv[i][2] == T('\0')) {
i++;
break;
}
j++;
}
switch (argv[i][j]) {
case T('r'):
processFlags &= ~XML_MAP_FILE;
j++;
break;
case T('s'):
requireStandalone = 1;
j++;
break;
case T('n'):
useNamespaces = 1;
j++;
break;
case T('p'):
paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
/* fall through */
case T('x'):
processFlags |= XML_EXTERNAL_ENTITIES;
j++;
break;
case T('w'):
windowsCodePages = 1;
j++;
break;
case T('m'):
outputType = 'm';
j++;
break;
case T('c'):
outputType = 'c';
useNamespaces = 0;
j++;
break;
case T('t'):
outputType = 't';
j++;
break;
case T('d'):
if (argv[i][j + 1] == T('\0')) {
if (++i == argc)
usage(argv[0]);
outputDir = argv[i];
}
else
outputDir = argv[i] + j + 1;
i++;
j = 0;
break;
case T('e'):
if (argv[i][j + 1] == T('\0')) {
if (++i == argc)
usage(argv[0]);
encoding = argv[i];
}
else
encoding = argv[i] + j + 1;
i++;
j = 0;
break;
case T('\0'):
if (j > 1) {
i++;
j = 0;
break;
}
/* fall through */
default:
usage(argv[0]);
}
}
if (i == argc)
usage(argv[0]);
for (; i < argc; i++) {
FILE *fp = 0;
XML_Char *outName = 0;
int result;
XML_Parser parser;
if (useNamespaces)
parser = XML_ParserCreateNS(encoding, NSSEP);
else
parser = XML_ParserCreate(encoding);
if (requireStandalone)
XML_SetNotStandaloneHandler(parser, notStandalone);
XML_SetParamEntityParsing(parser, paramEntityParsing);
if (outputType == 't') {
/* This is for doing timings; this gives a more realistic estimate of
the parsing time. */
outputDir = 0;
XML_SetElementHandler(parser, nopStartElement, nopEndElement);
XML_SetCharacterDataHandler(parser, nopCharacterData);
XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
}
else if (outputDir) {
const XML_Char *file = argv[i];
if (tcsrchr(file, T('/')))
file = tcsrchr(file, T('/')) + 1;
#ifdef WIN32
if (tcsrchr(file, T('\\')))
file = tcsrchr(file, T('\\')) + 1;
#endif
outName = malloc((tcslen(outputDir) + tcslen(file) + 2) * sizeof(XML_Char));
tcscpy(outName, outputDir);
tcscat(outName, T("/"));
tcscat(outName, file);
fp = tfopen(outName, T("wb"));
if (!fp) {
tperror(outName);
exit(1);
}
setvbuf(fp, NULL, _IOFBF, 16384);
#ifdef XML_UNICODE
puttc(0xFEFF, fp);
#endif
XML_SetUserData(parser, fp);
switch (outputType) {
case 'm':
XML_UseParserAsHandlerArg(parser);
XML_SetElementHandler(parser, metaStartElement, metaEndElement);
XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction);
XML_SetCommentHandler(parser, metaComment);
XML_SetCdataSectionHandler(parser, metaStartCdataSection, metaEndCdataSection);
XML_SetCharacterDataHandler(parser, metaCharacterData);
XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, metaEndDoctypeDecl);
XML_SetUnparsedEntityDeclHandler(parser, metaUnparsedEntityDecl);
XML_SetNotationDeclHandler(parser, metaNotationDecl);
XML_SetExternalParsedEntityDeclHandler(parser, metaExternalParsedEntityDecl);
XML_SetInternalParsedEntityDeclHandler(parser, metaInternalParsedEntityDecl);
XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, metaEndNamespaceDecl);
metaStartDocument(parser);
break;
case 'c':
XML_UseParserAsHandlerArg(parser);
XML_SetDefaultHandler(parser, markup);
XML_SetElementHandler(parser, defaultStartElement, defaultEndElement);
XML_SetCharacterDataHandler(parser, defaultCharacterData);
XML_SetProcessingInstructionHandler(parser, defaultProcessingInstruction);
break;
default:
if (useNamespaces)
XML_SetElementHandler(parser, startElementNS, endElementNS);
else
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, characterData);
#ifndef W3C14N
XML_SetProcessingInstructionHandler(parser, processingInstruction);
#endif /* not W3C14N */
break;
}
}
if (windowsCodePages)
XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
result = XML_ProcessFile(parser, argv[i], processFlags);
if (outputDir) {
if (outputType == 'm')
metaEndDocument(parser);
fclose(fp);
if (!result)
tremove(outName);
free(outName);
}
XML_ParserFree(parser);
}
return 0;
}

View File

@ -0,0 +1,136 @@
# Microsoft Developer Studio Project File - Name="xmlwf" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=xmlwf - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "xmlwf.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "xmlwf.mak" CFG="xmlwf - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "xmlwf - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "xmlwf - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "xmlwf - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\xmlparse" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\xmlwf.exe"
!ELSEIF "$(CFG)" == "xmlwf - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir "."
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir "."
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".\xmlparse" /I "..\xmlparse" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\dbgbin\xmlwf.exe"
!ENDIF
# Begin Target
# Name "xmlwf - Win32 Release"
# Name "xmlwf - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\codepage.c
# End Source File
# Begin Source File
SOURCE=.\readfilemap.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\unixfilemap.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=.\win32filemap.c
# End Source File
# Begin Source File
SOURCE=.\xmlfile.c
# End Source File
# Begin Source File
SOURCE=.\xmlwf.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\codepage.h
# End Source File
# Begin Source File
SOURCE=.\xmlfile.h
# End Source File
# Begin Source File
SOURCE=.\xmltchar.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,116 @@
#define _GNU_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */
#include "xmlrpc-c/string_int.h"
static __inline__ void
simpleVasprintf(char ** const retvalP,
const char * const fmt,
va_list varargs) {
/*----------------------------------------------------------------------------
This is a poor man's implementation of vasprintf(), of GNU fame.
-----------------------------------------------------------------------------*/
size_t const initialSize = 4096;
char * result;
result = malloc(initialSize);
if (result != NULL) {
size_t bytesNeeded;
bytesNeeded = XMLRPC_VSNPRINTF(result, initialSize, fmt, varargs);
if (bytesNeeded > initialSize) {
free(result);
result = malloc(bytesNeeded);
if (result != NULL)
XMLRPC_VSNPRINTF(result, bytesNeeded, fmt, varargs);
} else if (bytesNeeded == initialSize) {
if (result[initialSize-1] != '\0') {
/* This is one of those old systems where vsnprintf()
returns the number of bytes it used, instead of the
number that it needed, and it in fact needed more than
we gave it. Rather than mess with this highly unlikely
case (old system and string > 4095 characters), we just
treat this like an out of memory failure.
*/
free(result);
result = NULL;
}
}
}
*retvalP = result;
}
const char * const xmlrpc_strsol = "[insufficient memory to build string]";
void
xmlrpc_vasprintf(const char ** const retvalP,
const char * const fmt,
va_list varargs) {
char * string;
#if HAVE_ASPRINTF
vasprintf(&string, fmt, varargs);
#else
simpleVasprintf(&string, fmt, varargs);
#endif
if (string == NULL)
*retvalP = xmlrpc_strsol;
else
*retvalP = string;
}
void GNU_PRINTF_ATTR(2,3)
xmlrpc_asprintf(const char ** const retvalP, const char * const fmt, ...) {
va_list varargs; /* mysterious structure used by variable arg facility */
va_start(varargs, fmt); /* start up the mysterious variable arg facility */
xmlrpc_vasprintf(retvalP, fmt, varargs);
va_end(varargs);
}
const char *
xmlrpc_strdupnull(const char * const string) {
if (string)
return strdup(string);
else
return NULL;
}
void
xmlrpc_strfree(const char * const string) {
if (string != xmlrpc_strsol)
free((void *)string);
}
void
xmlrpc_strfreenull(const char * const string) {
if (string)
xmlrpc_strfree(string);
}

View File

@ -0,0 +1,163 @@
/* Copyright information is at end of file */
#include "xmlrpc_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "xmlrpc-c/util_int.h"
#include "xmlrpc-c/string_int.h"
#include "xmlrpc-c/util.h"
void
xmlrpc_assertion_failed(const char * const fileName,
int const lineNumber) {
fprintf(stderr, "%s:%d: assertion failed\n", fileName, lineNumber);
abort();
}
static const char * const default_fault_string =
"Not enough memory for error message";
void xmlrpc_env_init (xmlrpc_env* env)
{
XMLRPC_ASSERT(env != NULL);
env->fault_occurred = 0;
env->fault_code = 0;
env->fault_string = NULL;
}
void
xmlrpc_env_clean(xmlrpc_env * const envP) {
XMLRPC_ASSERT(envP != NULL);
XMLRPC_ASSERT(envP->fault_string != XMLRPC_BAD_POINTER);
/* env->fault_string may be one of three things:
** 1) a NULL pointer
** 2) a pointer to the default_fault_string
** 3) a pointer to a malloc'd fault string
** If we have case (3), we'll need to free it. */
if (envP->fault_string && envP->fault_string != default_fault_string)
free(envP->fault_string);
envP->fault_string = XMLRPC_BAD_POINTER;
}
void
xmlrpc_env_set_fault(xmlrpc_env * const envP,
int const faultCode,
const char * const faultDescription) {
char * buffer;
XMLRPC_ASSERT(envP != NULL);
XMLRPC_ASSERT(faultDescription != NULL);
/* Clean up any leftover pointers. */
xmlrpc_env_clean(envP);
envP->fault_occurred = 1;
envP->fault_code = faultCode;
/* Try to copy the fault string. If this fails, use a default. */
buffer = strdup(faultDescription);
if (buffer == NULL)
envP->fault_string = (char *)default_fault_string;
else {
xmlrpc_force_to_utf8(buffer);
xmlrpc_force_to_xml_chars(buffer);
envP->fault_string = buffer;
}
}
void
xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP,
int const code,
const char * const format,
va_list const args) {
const char * faultDescription;
xmlrpc_vasprintf(&faultDescription, format, args);
xmlrpc_env_set_fault(envP, code, faultDescription);
xmlrpc_strfree(faultDescription);
}
void
xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP,
int const code,
const char * const format,
...) {
va_list args;
XMLRPC_ASSERT(envP != NULL);
XMLRPC_ASSERT(format != NULL);
/* Print our error message to the buffer. */
va_start(args, format);
xmlrpc_set_fault_formatted_v(envP, code, format, args);
va_end(args);
}
void
xmlrpc_faultf(xmlrpc_env * const envP,
const char * const format,
...) {
va_list args;
XMLRPC_ASSERT(envP != NULL);
XMLRPC_ASSERT(format != NULL);
/* Print our error message to the buffer. */
va_start(args, format);
xmlrpc_set_fault_formatted_v(envP, XMLRPC_INTERNAL_ERROR, format, args);
va_end(args);
}
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */

View File

@ -0,0 +1,101 @@
#define _GNU_SOURCE
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "xmlrpc_config.h"
#include "xmlrpc-c/string_int.h"
const char *
xmlrpc_makePrintable_lp(const char * const input,
size_t const inputLength) {
/*----------------------------------------------------------------------------
Convert an arbitrary string of characters in length-pointer form to
printable ASCII. E.g. convert newlines to "\n".
Return the result in newly malloc'ed storage. Return NULL if we can't
get the storage.
-----------------------------------------------------------------------------*/
char * output;
output = malloc(inputLength*4+1);
/* Worst case, we render a character like \x01 -- 4 characters */
if (output != NULL) {
unsigned int inputCursor, outputCursor;
for (inputCursor = 0, outputCursor = 0;
inputCursor < inputLength;
++inputCursor) {
if (0) {
} else if (input[inputCursor] == '\\') {
output[outputCursor++] = '\\';
output[outputCursor++] = '\\';
} else if (input[inputCursor] == '\n') {
output[outputCursor++] = '\\';
output[outputCursor++] = 'n';
} else if (input[inputCursor] == '\t') {
output[outputCursor++] = '\\';
output[outputCursor++] = 't';
} else if (input[inputCursor] == '\a') {
output[outputCursor++] = '\\';
output[outputCursor++] = 'a';
} else if (input[inputCursor] == '\r') {
output[outputCursor++] = '\\';
output[outputCursor++] = 'r';
} else if (isprint(input[inputCursor])) {
output[outputCursor++] = input[inputCursor];
} else {
snprintf(&output[outputCursor], 5, "\\x%02x",
input[inputCursor]);
outputCursor += 4;
}
}
output[outputCursor++] = '\0';
}
return output;
}
const char *
xmlrpc_makePrintable(const char * const input) {
/*----------------------------------------------------------------------------
Convert an arbitrary string of characters (NUL-terminated, though) to
printable ASCII. E.g. convert newlines to "\n".
Return the result in newly malloc'ed storage. Return NULL if we can't
get the storage.
-----------------------------------------------------------------------------*/
return xmlrpc_makePrintable_lp(input, strlen(input));
}
const char *
xmlrpc_makePrintableChar(char const input) {
/*----------------------------------------------------------------------------
Return an ASCIIZ string consisting of the character 'input',
properly escaped so as to be printable. E.g., in C notation, '\n'
turns into "\\n"
-----------------------------------------------------------------------------*/
const char * retval;
if (input == '\0')
retval = strdup("\\0");
else {
char buffer[2];
buffer[0] = input;
buffer[1] = '\0';
retval = xmlrpc_makePrintable(buffer);
}
return retval;
}

View File

@ -0,0 +1,214 @@
/* Copyright information is at end of file */
#include "xmlrpc_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "xmlrpc-c/util_int.h"
#include "xmlrpc-c/util.h"
#ifdef EFENCE
/* when looking for corruption don't allocate extra slop */
#define BLOCK_ALLOC_MIN (1)
#else
#define BLOCK_ALLOC_MIN (16)
#endif
#define BLOCK_ALLOC_MAX (128 * 1024 * 1024)
xmlrpc_mem_block *
xmlrpc_mem_block_new(xmlrpc_env * const env,
size_t const size) {
xmlrpc_mem_block* block;
XMLRPC_ASSERT_ENV_OK(env);
block = (xmlrpc_mem_block*) malloc(sizeof(xmlrpc_mem_block));
XMLRPC_FAIL_IF_NULL(block, env, XMLRPC_INTERNAL_ERROR,
"Can't allocate memory block");
xmlrpc_mem_block_init(env, block, size);
XMLRPC_FAIL_IF_FAULT(env);
cleanup:
if (env->fault_occurred) {
if (block)
free(block);
return NULL;
} else {
return block;
}
}
/* Destroy an existing xmlrpc_mem_block, and everything it contains. */
void
xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) {
XMLRPC_ASSERT(blockP != NULL);
XMLRPC_ASSERT(blockP->_block != NULL);
xmlrpc_mem_block_clean(blockP);
free(blockP);
}
/* Initialize the contents of the provided xmlrpc_mem_block. */
void
xmlrpc_mem_block_init(xmlrpc_env * const envP,
xmlrpc_mem_block * const blockP,
size_t const size) {
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT(blockP != NULL);
blockP->_size = size;
if (size < BLOCK_ALLOC_MIN)
blockP->_allocated = BLOCK_ALLOC_MIN;
else
blockP->_allocated = size;
blockP->_block = (void*) malloc(blockP->_allocated);
if (!blockP->_block)
xmlrpc_faultf(envP, "Can't allocate %u-byte memory block",
blockP->_allocated);
}
/* Deallocate the contents of the provided xmlrpc_mem_block, but not
the block itself.
*/
void
xmlrpc_mem_block_clean(xmlrpc_mem_block * const blockP) {
XMLRPC_ASSERT(blockP != NULL);
XMLRPC_ASSERT(blockP->_block != NULL);
free(blockP->_block);
blockP->_block = XMLRPC_BAD_POINTER;
}
/* Get the size of the xmlrpc_mem_block. */
size_t
xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) {
XMLRPC_ASSERT(blockP != NULL);
return blockP->_size;
}
/* Get the contents of the xmlrpc_mem_block. */
void *
xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) {
XMLRPC_ASSERT(blockP != NULL);
return blockP->_block;
}
/* Resize an xmlrpc_mem_block, preserving as much of the contents as
possible.
*/
void
xmlrpc_mem_block_resize (xmlrpc_env * const envP,
xmlrpc_mem_block * const blockP,
size_t const size) {
size_t proposed_alloc;
void* new_block;
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT(blockP != NULL);
/* Check to see if we already have enough space. Maybe we'll get lucky. */
if (size <= blockP->_allocated) {
blockP->_size = size;
return;
}
/* Calculate a new allocation size. */
#ifdef EFENCE
proposed_alloc = size;
#else
proposed_alloc = blockP->_allocated;
while (proposed_alloc < size && proposed_alloc <= BLOCK_ALLOC_MAX)
proposed_alloc *= 2;
#endif /* DEBUG_MEM_ERRORS */
if (proposed_alloc > BLOCK_ALLOC_MAX)
XMLRPC_FAIL(envP, XMLRPC_INTERNAL_ERROR, "Memory block too large");
/* Allocate our new memory block. */
new_block = (void*) malloc(proposed_alloc);
XMLRPC_FAIL_IF_NULL(new_block, envP, XMLRPC_INTERNAL_ERROR,
"Can't resize memory block");
/* Copy over our data and update the xmlrpc_mem_block struct. */
memcpy(new_block, blockP->_block, blockP->_size);
free(blockP->_block);
blockP->_block = new_block;
blockP->_size = size;
blockP->_allocated = proposed_alloc;
cleanup:
return;
}
void
xmlrpc_mem_block_append(xmlrpc_env * const envP,
xmlrpc_mem_block * const blockP,
const void * const data,
size_t const len) {
int size;
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT(blockP != NULL);
size = blockP->_size;
xmlrpc_mem_block_resize(envP, blockP, size + len);
XMLRPC_FAIL_IF_FAULT(envP);
memcpy(((unsigned char*) blockP->_block) + size, data, len);
cleanup:
return;
}
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
*/

View File

@ -0,0 +1,59 @@
#define _XOPEN_SOURCE 600 /* Get pselect() in <sys/select.h> */
#ifdef WIN32
#include <winsock.h>
#else
/* In some systems (SUS), the select() interface comes from <sys/time.h>;
in others, from <sys/select.h>, and other from both. Including both
in this order appears to work on all.
*/
#include <sys/time.h>
#include <sys/select.h>
#endif
#include <signal.h>
#include "xmlrpc_config.h"
#include "xmlrpc-c/select_int.h"
/* xmlrpc_pselect() is just for use with sockets. In a POSIX system,
it technically works for any file descriptor, but in Windows, select()
is part of the socket facility.
*/
int
xmlrpc_pselect(int const n,
fd_set * const readfdsP,
fd_set * const writefdsP,
fd_set * const exceptfdsP,
const xmlrpc_timespec * const timeoutP,
sigset_t * const sigmaskP) {
int retval;
#if HAVE_PSELECT
#if !HAVE_TIMESPEC
#error "Impossible configuration -- has pselect(), but not struct timespec"
#else
retval = pselect(n, readfdsP, writefdsP, exceptfdsP, timeoutP, sigmaskP);
#endif
#else /* HAVE_PSELECT */
struct timeval timeout;
timeout.tv_sec = timeoutP->tv_sec;
timeout.tv_usec = timeoutP->tv_nsec/1000;
#ifdef WIN32
retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout);
#else
{
sigset_t origmask;
sigprocmask(SIG_SETMASK, sigmaskP, &origmask);
retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL);
}
#endif
#endif
return retval;
}

View File

@ -0,0 +1,21 @@
#include "bool.h"
#include "xmlrpc-c/sleep_int.h"
#ifdef WIN32
#include <windows.h>
#include <process.h>
#else
#include <unistd.h>
#endif
void
xmlrpc_millisecond_sleep(unsigned int const milliseconds) {
#ifdef WIN32
SleepEx(milliseconds, true);
#else
usleep(milliseconds * 1000);
#endif
}

View File

@ -0,0 +1,173 @@
#include "xmlrpc_config.h"
#include <assert.h>
#include <time.h>
#if !MSVCRT
#include <sys/time.h>
#endif
#if MSVCRT
#include <windows.h>
#endif
#include "xmlrpc-c/string_int.h"
#include "xmlrpc-c/time_int.h"
/* A note about struct timeval and Windows: There is a 'struct
timeval' type in Windows, but it is just an argument to select(),
which is just part of the sockets interface. It's defined
identically to the POSIX type of the same name, but not meant for
general timekeeping as the POSIX type is.
*/
#if HAVE_GETTIMEOFDAY
static void
gettimeofdayPosix(xmlrpc_timespec * const todP) {
struct timeval tv;
gettimeofday(&tv, NULL);
todP->tv_sec = tv.tv_sec;
todP->tv_nsec = tv.tv_usec * 1000;
}
#endif
#if MSVCRT
static void
gettimeofdayWindows(xmlrpc_timespec * const todP) {
__int64 const epochOffset = 116444736000000000i64;
/* Number of 100-nanosecond units between the beginning of the
Windows epoch (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
*/
FILETIME ft;
LARGE_INTEGER li;
__int64 t;
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
t = (li.QuadPart - epochOffset) * 100; /* nanoseconds */
todP->tv_sec = (long)(t / 1E9);
todP->tv_nsec = (long)(t - (__int64)todP->tv_sec * 1E9);
}
#endif
void
xmlrpc_gettimeofday(xmlrpc_timespec * const todP) {
assert(todP);
#if HAVE_GETTIMEOFDAY
gettimeofdayPosix(todP);
#else
#if MSVCRT
gettimeofdayWindows(todP);
#else
#error "We don't know how to get the time of day on this system"
#endif
#endif /* HAVE_GETTIMEOFDAY */
}
static bool
isLeapYear(unsigned int const yearOfAd) {
return
(yearOfAd % 4) == 0 &&
((yearOfAd % 100) != 0 || (yearOfAd % 400) == 0);
}
void
xmlrpc_timegm(const struct tm * const tmP,
time_t * const timeValueP,
const char ** const errorP) {
/*----------------------------------------------------------------------------
This does what GNU libc's timegm() does.
-----------------------------------------------------------------------------*/
if (tmP->tm_year < 70 ||
tmP->tm_mon > 11 ||
tmP->tm_mon < 0 ||
tmP->tm_mday > 31 ||
tmP->tm_min > 60 ||
tmP->tm_sec > 60 ||
tmP->tm_hour > 24) {
xmlrpc_asprintf(errorP, "Invalid time specification; a member "
"of struct tm is out of range");
} else {
static unsigned int const monthDaysNonLeap[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
unsigned int totalDays;
unsigned int year;
unsigned int month;
totalDays = 0; /* initial value */
for (year = 70; year < (unsigned int)tmP->tm_year; ++year)
totalDays += isLeapYear(1900 + year) ? 366 : 365;
for (month = 0; month < (unsigned int)tmP->tm_mon; ++month)
totalDays += monthDaysNonLeap[month];
if (tmP->tm_mon > 1 && isLeapYear(1900 + tmP->tm_year))
totalDays += 1;
totalDays += tmP->tm_mday - 1;
*errorP = NULL;
*timeValueP = ((totalDays * 24 +
tmP->tm_hour) * 60 +
tmP->tm_min) * 60 +
tmP->tm_sec;
}
}
void
xmlrpc_localtime(time_t const datetime,
struct tm * const tmP) {
/*----------------------------------------------------------------------------
Convert datetime from standard to broken-down format in the local
time zone.
For Windows, this is not thread-safe. If you run a version of Abyss
with multiple threads, you can get arbitrary results here.
-----------------------------------------------------------------------------*/
#if HAVE_LOCALTIME_R
localtime_r(&datetime, tmP);
#else
*tmP = *localtime(&datetime);
#endif
}
void
xmlrpc_gmtime(time_t const datetime,
struct tm * const resultP) {
/*----------------------------------------------------------------------------
Convert datetime from standard to broken-down UTC format.
For Windows, this is not thread-safe. If you run a version of Abyss
with multiple threads, you can get arbitrary results here.
-----------------------------------------------------------------------------*/
#if HAVE_GMTIME_R
gmtime_r(&datetime, resultP);
#else
*resultP = *gmtime(&datetime);
#endif
}

View File

@ -0,0 +1,510 @@
/* Copyright (C) 2001 by Eric Kidd. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
/*=========================================================================
** XML-RPC UTF-8 Utilities
**=========================================================================
** Routines for validating, encoding and decoding UTF-8 data. We try to
** be very, very strict about invalid UTF-8 data.
**
** All of the code in this file assumes that your machine represents
** wchar_t as a 16-bit (or wider) character containing UCS-2 data. If this
** assumption is incorrect, you may need to replace this file.
**
** For lots of information on Unicode and UTF-8 decoding, see:
** http://www.cl.cam.ac.uk/~mgk25/unicode.html
*/
#include "int.h"
#include "xmlrpc_config.h"
#include "bool.h"
#include "xmlrpc-c/base.h"
/*=========================================================================
** Tables and Constants
**=========================================================================
** We use a variety of tables and constants to help decode and validate
** UTF-8 data.
*/
/* The number of bytes in a UTF-8 sequence starting with the character used
** as the array index. A zero entry indicates an illegal initial byte.
** This table was generated using a Perl script and information from the
** UTF-8 standard.
**
** Fredrik Lundh's UTF-8 decoder Python 2.0 uses a similar table. But
** since Python 2.0 has the icky CNRI license, I regenerated this
** table from scratch and wrote my own decoder. */
static unsigned char utf8_seq_length[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
};
/* The minimum legal character value for a UTF-8 sequence of the given
** length. We have to check this to avoid accepting "overlong" UTF-8
** sequences, which use more bytes than necessary to encode a given
** character. Such sequences are commonly used by evil people to bypass
** filters and security checks. This table is based on the UTF-8-test.txt
** file by Markus Kuhn <mkuhn@acm.org>. */
static uint32_t const utf8_min_char_for_length[] = {
0, /* Length 0: Not used (meaningless) */
0x0000, /* Length 1: Not used (special-cased) */
0x0080, /* Length 2 */
0x0800, /* Length 3 */
0x00010000, /* Length 4 */
0x00200000, /* Length 5 */
0x04000000 /* Length 6 */
};
/* This is the maximum legal 16-byte (UCS-2) character. Again, this
** information is based on UTF-8-test.txt. */
#define UCS2_MAX_LEGAL_CHARACTER (0xFFFD)
/* First and last UTF-16 surrogate characters. These are *not* legal UCS-2
** characters--they're used to code for UCS-4 characters when using
** UTF-16. They should never appear in decoded UTF-8 data! Again, these
** could hypothetically be used to bypass security measures on some machines.
** Based on UTF-8-test.txt. */
#define UTF16_FIRST_SURROGATE (0xD800)
#define UTF16_LAST_SURROGATE (0xDFFF)
/* Is the character 'c' a UTF-8 continuation character? */
#define IS_CONTINUATION(c) (((c) & 0xC0) == 0x80)
#define MAX_ENCODED_BYTES (3)
/* Maximum number of bytes needed to encode in UTF-8 a character
in the Basic Multilingual Plane.
*/
#if HAVE_UNICODE_WCHAR
static void
decode_utf8(xmlrpc_env * const envP,
const char * const utf8_data,
size_t const utf8_len,
wchar_t * const ioBuff,
size_t * const outBuffLenP) {
/*----------------------------------------------------------------------------
Decode to UCS-2 (or validates as UTF-8 that can be decoded to UCS-2)
a UTF-8 string. To validate, set ioBuff and outBuffLenP to NULL.
To decode, allocate a sufficiently large buffer, pass it as ioBuff,
and pass a pointer as as outBuffLenP. The data will be written to
the buffer, and the length to outBuffLenP.
We assume that wchar_t holds a single UCS-2 character in native-endian
byte ordering.
-----------------------------------------------------------------------------*/
size_t i, length, out_pos;
char init, con1, con2;
wchar_t wc;
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT_PTR_OK(utf8_data);
XMLRPC_ASSERT((!ioBuff && !outBuffLenP) ||
(ioBuff && outBuffLenP));
/* Suppress GCC warning about possibly undefined variable. */
wc = 0;
i = 0;
out_pos = 0;
while (i < utf8_len) {
init = utf8_data[i];
if ((init & 0x80) == 0x00) {
/* Convert ASCII character to wide character. */
wc = init;
i++;
} else {
/* Look up the length of this UTF-8 sequence. */
length = utf8_seq_length[(unsigned char) init];
/* Check to make sure we have enough bytes to convert. */
if (i + length > utf8_len)
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"Truncated UTF-8 sequence");
/* Decode a multibyte UTF-8 sequence. */
switch (length) {
case 0:
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"Invalid UTF-8 initial byte");
case 2:
/* 110xxxxx 10xxxxxx */
con1 = utf8_data[i+1];
if (!IS_CONTINUATION(con1))
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"UTF-8 sequence too short");
wc = ((((wchar_t) (init & 0x1F)) << 6) |
(((wchar_t) (con1 & 0x3F))));
break;
case 3:
/* 1110xxxx 10xxxxxx 10xxxxxx */
con1 = utf8_data[i+1];
con2 = utf8_data[i+2];
if (!IS_CONTINUATION(con1) || !IS_CONTINUATION(con2))
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"UTF-8 sequence too short");
wc = ((((wchar_t) (init & 0x0F)) << 12) |
(((wchar_t) (con1 & 0x3F)) << 6) |
(((wchar_t) (con2 & 0x3F))));
break;
case 4:
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
case 5:
/* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
case 6:
/* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
/* This would require more than 16 bits in UTF-16, so
it can't be represented in UCS-2, so it's beyond
our capability. Characters in the BMP fit in 16
bits.
*/
xmlrpc_env_set_fault_formatted(
envP, XMLRPC_INVALID_UTF8_ERROR,
"UTF-8 string contains a character not in the "
"Basic Multilingual Plane (first byte %08x)",
init);
goto cleanup;
default:
XMLRPC_ASSERT("Error in UTF-8 decoder tables");
}
/* Advance to the end of the sequence. */
i += length;
/* Check for illegal UCS-2 characters. */
if (wc > UCS2_MAX_LEGAL_CHARACTER)
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"UCS-2 characters > U+FFFD are illegal");
/* Check for UTF-16 surrogates. */
if (UTF16_FIRST_SURROGATE <= wc && wc <= UTF16_LAST_SURROGATE)
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"UTF-16 surrogates may not appear in UTF-8 data");
/* Check for overlong sequences. */
if ((uint32_t)wc < utf8_min_char_for_length[length])
XMLRPC_FAIL(envP, XMLRPC_INVALID_UTF8_ERROR,
"Overlong UTF-8 sequence not allowed");
}
/* If we have a buffer, write our character to it. */
if (ioBuff) {
ioBuff[out_pos++] = wc;
}
}
/* Record the number of characters we found. */
if (outBuffLenP)
*outBuffLenP = out_pos;
cleanup:
if (envP->fault_occurred) {
if (outBuffLenP)
*outBuffLenP = 0;
}
}
xmlrpc_mem_block *
xmlrpc_utf8_to_wcs(xmlrpc_env * const envP,
const char * const utf8_data,
size_t const utf8_len) {
/*----------------------------------------------------------------------------
Decode UTF-8 string to a "wide character string". This function
returns an xmlrpc_mem_block with an element type of wchar_t. Don't
try to intepret the block in a bytewise fashion--it won't work in
any useful or portable fashion.
For backward compatibility, we return a meaningful value even when we
fail. We return NULL when we fail.
-----------------------------------------------------------------------------*/
xmlrpc_mem_block * wcsP;
size_t wcs_length;
/* Allocate a memory block large enough to hold any possible output.
We assume that each byte of the input may decode to a whcar_t.
*/
wcsP = XMLRPC_MEMBLOCK_NEW(wchar_t, envP, utf8_len);
if (!envP->fault_occurred) {
/* Decode the UTF-8 data. */
decode_utf8(envP, utf8_data, utf8_len,
XMLRPC_MEMBLOCK_CONTENTS(wchar_t, wcsP),
&wcs_length);
if (!envP->fault_occurred) {
/* We can't have overrun our buffer. */
XMLRPC_ASSERT(wcs_length <= utf8_len);
/* Correct the length of the memory block. */
XMLRPC_MEMBLOCK_RESIZE(wchar_t, envP, wcsP, wcs_length);
}
if (envP->fault_occurred)
XMLRPC_MEMBLOCK_FREE(wchar_t, wcsP);
}
if (envP->fault_occurred)
return NULL;
else
return wcsP;
}
xmlrpc_mem_block *
xmlrpc_wcs_to_utf8(xmlrpc_env * const envP,
const wchar_t * const wcs_data,
size_t const wcs_len) {
/*----------------------------------------------------------------------------
Encode a "wide character string" as UTF-8.
For backward compatibility, we return a meaningful value even when we
fail. We return NULL when we fail.
-----------------------------------------------------------------------------*/
size_t const estimate = wcs_len * MAX_ENCODED_BYTES;
/* Our conservative estimate of how big the output will be;
i.e. we know it won't be larger than this. For the estimate,
we assume that every wchar might encode to the maximum length.
*/
xmlrpc_mem_block * utf8P;
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT_PTR_OK(wcs_data);
utf8P = XMLRPC_MEMBLOCK_NEW(char, envP, estimate);
if (!envP->fault_occurred) {
unsigned char * const buffer =
XMLRPC_MEMBLOCK_CONTENTS(unsigned char, utf8P);
size_t bytesUsed;
size_t i;
bytesUsed = 0;
for (i = 0; i < wcs_len && !envP->fault_occurred; ++i) {
wchar_t const wc = wcs_data[i];
if (wc <= 0x007F)
buffer[bytesUsed++] = wc & 0x7F;
else if (wc <= 0x07FF) {
/* 110xxxxx 10xxxxxx */
buffer[bytesUsed++] = 0xC0 | (wc >> 6);
buffer[bytesUsed++] = 0x80 | (wc & 0x3F);
} else if (wc <= 0xFFFF) {
/* 1110xxxx 10xxxxxx 10xxxxxx */
buffer[bytesUsed++] = 0xE0 | (wc >> 12);
buffer[bytesUsed++] = 0x80 | ((wc >> 6) & 0x3F);
buffer[bytesUsed++] = 0x80 | (wc & 0x3F);
} else
xmlrpc_faultf(envP,
"Don't know how to encode UCS-4 characters yet");
}
if (!envP->fault_occurred) {
XMLRPC_ASSERT(bytesUsed <= estimate);
XMLRPC_MEMBLOCK_RESIZE(char, envP, utf8P, bytesUsed);
}
if (envP->fault_occurred)
XMLRPC_MEMBLOCK_FREE(char, utf8P);
}
if (envP->fault_occurred)
return NULL;
else
return utf8P;
}
#else /* HAVE_UNICODE_WCHAR */
xmlrpc_mem_block *
xmlrpc_utf8_to_wcs(xmlrpc_env * const envP,
const char * const utf8_data ATTR_UNUSED,
size_t const utf8_len ATTR_UNUSED) {
xmlrpc_faultf(envP, "INTERNAL ERROR: xmlrpc_utf8_to_wcs() called "
"on a system that doesn't do Unicode!");
return NULL;
}
#endif /* HAVE_UNICODE_WCHAR */
void
xmlrpc_force_to_utf8(char * const buffer) {
/*----------------------------------------------------------------------------
Force the contents of 'buffer' to be valid UTF-8, any way possible.
The buffer ends with a NUL character, and the mutation does not make
it longer.
The most common reason for a string that's supposed to be UTF-8 not
to be UTF-8 is that it was supposed to be ASCII but instead
includes garbage with the high bit on (ASCII characters always have
the high bit off), or maybe a primitive 8-bit ASCII extension.
Therefore, we force it to UTF-8 by replacing some bytes that have
the high bit set with DEL (0x7F). That would leave the other
characters meaningful.
-----------------------------------------------------------------------------*/
char * p;
for (p = &buffer[0]; *p;) {
unsigned int const length = utf8_seq_length[(unsigned char) *p];
bool forceDel;
uint32_t decoded;
forceDel = false;
decoded = 0; /* suppress compiler warning; valid when !forceDel */
switch (length) {
case 1:
/* One-byte UTF-8 characters are easy. */
decoded = *p;
break;
case 2:
/* 110xxxxx 10xxxxxx */
if (!*(p+1) || !(*p+2))
forceDel = true;
else if (!IS_CONTINUATION(*(p+1)))
forceDel = true;
else
decoded =
((uint32_t)(*(p+0) & 0x1F) << 6) |
((uint32_t)(*(p+1) & 0x3F) << 0);
break;
case 3:
/* 1110xxxx 10xxxxxx 10xxxxxx */
if (!*(p+1) || !(*p+2) || !(*p+3))
forceDel = true;
else if (!IS_CONTINUATION(*(p+1)) || !IS_CONTINUATION(*(p+2)))
forceDel = true;
else
decoded =
((uint32_t)(*(p+0) & 0x0F) << 12) |
((uint32_t)(*(p+1) & 0x3F) << 6) |
((uint32_t)(*(p+2) & 0x3F) << 0);
break;
default:
forceDel = true;
}
if (!forceDel) {
if (decoded > UCS2_MAX_LEGAL_CHARACTER)
forceDel = true;
else if (UTF16_FIRST_SURROGATE <= decoded &&
decoded <= UTF16_LAST_SURROGATE)
forceDel = true;
else if (decoded < utf8_min_char_for_length[length])
forceDel = true;
}
if (forceDel) {
/* Not a valid UTF-8 character, so replace the first byte
with a nice simple ASCII DEL.
*/
*p = 0x7F;
p += 1;
} else
p += length;
}
}
void
xmlrpc_force_to_xml_chars(char * const buffer) {
/*----------------------------------------------------------------------------
Modify 'buffer' so that it contains nothing but valid XML
characters. The buffer ends with a NUL character, and the mutation
does not make it longer.
Note that the valid characters in an XML document are all Unicode
codepoints except the ASCII control characters, plus CR, LF, and
Tab.
We change all non-XML characters to DEL (0x7F).
Assume input is valid UTF-8.
-----------------------------------------------------------------------------*/
char * p;
for (p = &buffer[0]; *p;) {
unsigned int const length = utf8_seq_length[(unsigned char) *p];
if (length == 1) {
if (*p < 0x20 && *p != '\r' && *p != '\n' && *p != '\t')
/* Not valid XML. Force to DEL */
*p = 0x7f;
} else {
/* We assume here that all other UTF-8 characters are
valid XML, but it's apparently not actually true.
*/
}
{
unsigned int i;
/* Advance to next UTF-8 character */
for (i = 0; i < length && *p; ++i)
++p;
}
}
}
void
xmlrpc_validate_utf8(xmlrpc_env * const env,
const char * const utf8_data,
size_t const utf8_len) {
/*----------------------------------------------------------------------------
Validate that a string is valid UTF-8.
-----------------------------------------------------------------------------*/
#if HAVE_UNICODE_WCHAR
decode_utf8(env, utf8_data, utf8_len, NULL, NULL);
#else
/* We don't have a convenient way to validate, so we just fake it and
call it valid.
*/
#endif
}

View File

@ -0,0 +1,93 @@
#define _GNU_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */
#include "casprintf.h"
static __inline__ void
simpleVasprintf(char ** const retvalP,
const char * const fmt,
va_list varargs) {
/*----------------------------------------------------------------------------
This is a poor man's implementation of vasprintf(), of GNU fame.
-----------------------------------------------------------------------------*/
size_t const initialSize = 4096;
char * result;
result = malloc(initialSize);
if (result != NULL) {
size_t bytesNeeded;
bytesNeeded = XMLRPC_VSNPRINTF(result, initialSize, fmt, varargs);
if (bytesNeeded > initialSize) {
free(result);
result = malloc(bytesNeeded);
if (result != NULL)
XMLRPC_VSNPRINTF(result, bytesNeeded, fmt, varargs);
} else if (bytesNeeded == initialSize) {
if (result[initialSize-1] != '\0') {
/* This is one of those old systems where vsnprintf()
returns the number of bytes it used, instead of the
number that it needed, and it in fact needed more than
we gave it. Rather than mess with this highly unlikely
case (old system and string > 4095 characters), we just
treat this like an out of memory failure.
*/
free(result);
result = NULL;
}
}
}
*retvalP = result;
}
const char * const strsol = "[Insufficient memory to build string]";
void
cvasprintf(const char ** const retvalP,
const char * const fmt,
va_list varargs) {
char * string;
#if HAVE_ASPRINTF
vasprintf(&string, fmt, varargs);
#else
simpleVasprintf(&string, fmt, varargs);
#endif
if (string == NULL)
*retvalP = strsol;
else
*retvalP = string;
}
void GNU_PRINTF_ATTR(2,3)
casprintf(const char ** const retvalP, const char * const fmt, ...) {
va_list varargs; /* mysterious structure used by variable arg facility */
va_start(varargs, fmt); /* start up the mysterious variable arg facility */
cvasprintf(retvalP, fmt, varargs);
va_end(varargs);
}
void
strfree(const char * const string) {
if (string != strsol)
free((void *)string);
}

View File

@ -0,0 +1,587 @@
#include "xmlrpc_config.h" /* prereq for mallocvar.h -- defines __inline__ */
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include "bool.h"
#include "int.h"
#include "mallocvar.h"
#include "casprintf.h"
#include "getoptx.h"
#include "string_parser.h"
#include "cmdline_parser.h"
#define MAXOPTS 100
struct optionDesc {
const char * name;
enum optiontype type;
bool present;
union {
unsigned int u;
int i;
const char * s;
uint64_t llu;
double d;
} value;
};
struct cmdlineParserCtl {
struct optionDesc * optionDescArray;
unsigned int numOptions;
const char ** argumentArray;
unsigned int numArguments;
};
static struct optionx *
createLongOptsArray(struct optionDesc * const optionDescArray,
unsigned int const numOptions) {
struct optionx * longopts;
MALLOCARRAY(longopts, numOptions+1);
if (longopts != NULL) {
unsigned int i;
for (i = 0; i < numOptions; ++i) {
longopts[i].name = optionDescArray[i].name;
/* If the option takes a value, we say it is optional even
though it never is. That's because if we say it is
mandatory, getopt_long_only() pretends it doesn't even
recognize the option if the user doesn't give a value.
We prefer to generate a meaningful error message when
the user omits a required option value.
*/
longopts[i].has_arg =
optionDescArray[i].type == OPTTYPE_FLAG ?
no_argument : optional_argument;
longopts[i].flag = NULL;
longopts[i].val = i;
}
longopts[numOptions].name = 0;
longopts[numOptions].has_arg = 0;
longopts[numOptions].flag = 0;
longopts[numOptions].val = 0;
}
return longopts;
}
static void
parseInt(enum optiontype const type,
const char * const optarg,
unsigned int * const valueUintP,
int * const valueIntP,
const char ** const errorP) {
if (optarg == NULL)
casprintf(errorP, "Option requires a value");
else if (strlen(optarg) == 0)
casprintf(errorP, "Numeric option value is null string");
else {
char * tailptr;
long const longvalue = strtol(optarg, &tailptr, 10);
if (*tailptr != '\0')
casprintf(errorP, "Non-numeric value "
"for numeric option value: '%s'", optarg);
else if (errno == ERANGE || longvalue > INT_MAX)
casprintf(errorP, "Numeric value out of range: %s", optarg);
else {
if (type == OPTTYPE_UINT) {
if (longvalue < 0)
casprintf(errorP, "Unsigned numeric value is "
"negative: %ld", longvalue);
else {
*errorP = NULL;
*valueUintP = (unsigned int) longvalue;
}
} else {
*errorP = NULL;
*valueIntP = (int) longvalue;
}
}
}
}
static void
parseBinUint(const char * const optarg,
uint64_t * const valueP,
const char ** const errorP) {
if (optarg == NULL)
casprintf(errorP, "Option requires a value");
else if (strlen(optarg) == 0)
casprintf(errorP, "Numeric option value is null string");
else {
const char * error;
interpretBinUint(optarg, valueP, &error);
if (error) {
casprintf(errorP, "Invalid numeric option value '%s'. %s",
optarg, error);
strfree(error);
}
}
}
static void
parseFloat(const char * const optarg,
double * const valueP,
const char ** const errorP) {
if (optarg == NULL)
casprintf(errorP, "Option requires a value");
else if (strlen(optarg) == 0)
casprintf(errorP, "Numeric option value is null string");
else {
char * tailptr;
double const doublevalue = strtod(optarg, &tailptr);
if (*tailptr != '\0')
casprintf(errorP, "Non-numeric value "
"for numeric option value: '%s'", optarg);
else if (errno == ERANGE)
casprintf(errorP, "Numeric value out of range: %s", optarg);
else {
*errorP = NULL;
*valueP = doublevalue;
}
}
}
static void
parseOptionValue(const char * const optarg,
struct optionDesc * const optionP,
const char ** const errorP) {
switch (optionP->type) {
case OPTTYPE_FLAG:
*errorP = NULL;
break;
case OPTTYPE_INT:
case OPTTYPE_UINT:
parseInt(optionP->type, optarg, &optionP->value.u, &optionP->value.i,
errorP);
break;
case OPTTYPE_STRING:
if (optarg == NULL)
casprintf(errorP, "Option requires a value");
else {
*errorP = NULL;
optionP->value.s = strdup(optarg);
}
break;
case OPTTYPE_BINUINT:
parseBinUint(optarg, &optionP->value.llu, errorP);
break;
case OPTTYPE_FLOAT:
parseFloat(optarg, &optionP->value.d, errorP);
break;
}
}
static void
processOption(struct optionDesc * const optionP,
const char * const optarg,
const char ** const errorP) {
const char * error;
parseOptionValue(optarg, optionP, &error);
if (error)
casprintf(errorP, "Error in '%s' option: %s", optionP->name, error);
else
optionP->present = true;
}
static void
extractArguments(struct cmdlineParserCtl * const cpP,
unsigned int const argc,
const char ** const argv) {
cpP->numArguments = argc - getopt_argstart();
MALLOCARRAY(cpP->argumentArray, cpP->numArguments);
if (cpP->argumentArray == NULL) {
fprintf(stderr, "Unable to allocate memory for argument array "
"(%u arguments)\n", cpP->numArguments);
abort();
} else {
unsigned int i;
for (i = 0; i < cpP->numArguments; ++i) {
cpP->argumentArray[i] = strdup(argv[getopt_argstart() + i]);
if (cpP->argumentArray[i] == NULL) {
fprintf(stderr, "Unable to allocate memory for Argument %u\n",
i);
abort();
}
}
}
}
void
cmd_processOptions(cmdlineParser const cpP,
int const argc,
const char ** const argv,
const char ** const errorP) {
struct optionx * longopts;
longopts = createLongOptsArray(cpP->optionDescArray, cpP->numOptions);
if (longopts == NULL)
casprintf(errorP, "Unable to get memory for longopts array");
else {
int endOfOptions;
unsigned int i;
*errorP = NULL;
/* Set up initial assumption: No options present */
for (i = 0; i < cpP->numOptions; ++i)
cpP->optionDescArray[i].present = false;
endOfOptions = false; /* initial value */
while (!endOfOptions && !*errorP) {
int const opterr0 = 0;
/* Don't let getopt_long_only() print an error message */
unsigned int longoptsIndex;
const char * unrecognizedOption;
const char * optarg;
getopt_long_onlyx(argc, (char**) argv, "", longopts,
&longoptsIndex, opterr0,
&endOfOptions, &optarg, &unrecognizedOption);
if (unrecognizedOption)
casprintf(errorP, "Unrecognized option: '%s'",
unrecognizedOption);
else {
if (!endOfOptions)
processOption(&cpP->optionDescArray[longoptsIndex], optarg,
errorP);
}
}
if (!*errorP)
extractArguments(cpP, argc, argv);
free(longopts);
}
}
cmdlineParser
cmd_createOptionParser(void) {
struct cmdlineParserCtl * cpP;
MALLOCVAR(cpP);
if (cpP != NULL) {
struct optionDesc * optionDescArray;
cpP->numOptions = 0;
MALLOCARRAY(optionDescArray, MAXOPTS);
if (optionDescArray == NULL) {
free(cpP);
cpP = NULL;
} else
cpP->optionDescArray = optionDescArray;
}
return cpP;
}
void
cmd_destroyOptionParser(cmdlineParser const cpP) {
unsigned int i;
for (i = 0; i < cpP->numOptions; ++i) {
struct optionDesc const option = cpP->optionDescArray[i];
if (option.type == OPTTYPE_STRING && option.present)
strfree(option.value.s);
strfree(option.name);
}
for (i = 0; i < cpP->numArguments; ++i)
strfree(cpP->argumentArray[i]);
free(cpP->optionDescArray);
free(cpP);
}
void
cmd_defineOption(cmdlineParser const cpP,
const char * const name,
enum optiontype const type) {
if (cpP->numOptions < MAXOPTS) {
cpP->optionDescArray[cpP->numOptions].name = strdup(name);
cpP->optionDescArray[cpP->numOptions].type = type;
++cpP->numOptions;
}
}
static struct optionDesc *
findOptionDesc(struct cmdlineParserCtl * const cpP,
const char * const name) {
struct optionDesc * retval;
unsigned int i;
retval = NULL;
for (i = 0; i < cpP->numOptions && !retval; ++i)
if (strcmp(cpP->optionDescArray[i].name, name) == 0)
retval = &cpP->optionDescArray[i];
return retval;
}
int
cmd_optionIsPresent(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
bool present;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"optionIsPresent() called for undefined option '%s'\n",
name);
abort();
} else
present = optionDescP->present;
return present;
}
unsigned int
cmd_getOptionValueUint(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
unsigned int retval;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueUint() called for undefined option '%s'\n",
name);
abort();
} else {
if (optionDescP->type != OPTTYPE_UINT) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueUint() called for non-unsigned integer "
"option '%s'\n", optionDescP->name);
abort();
} else {
if (optionDescP->present)
retval = optionDescP->value.u;
else
retval = 0;
}
}
return retval;
}
int
cmd_getOptionValueInt(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
int retval;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueInt() called for undefined option '%s'\n",
name);
abort();
} else {
if (optionDescP->type != OPTTYPE_INT) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueInt() called for non-integer "
"option '%s'\n", optionDescP->name);
abort();
} else {
if (optionDescP->present)
retval = optionDescP->value.i;
else
retval = 0;
}
}
return retval;
}
const char *
cmd_getOptionValueString(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
const char * retval;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueString() called for "
"undefined option '%s'\n",
name);
abort();
} else {
if (optionDescP->type != OPTTYPE_STRING) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"getOptionValueString() called for non-string "
"option '%s'\n", optionDescP->name);
abort();
} else {
if (optionDescP->present) {
retval = strdup(optionDescP->value.s);
if (retval == NULL) {
fprintf(stderr,
"out of memory in cmd_getOptionValueString()\n");
abort();
}
} else
retval = NULL;
}
}
return retval;
}
uint64_t
cmd_getOptionValueBinUint(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
uint64_t retval;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueUint() called for undefined option '%s'\n",
name);
abort();
} else {
if (optionDescP->type != OPTTYPE_BINUINT) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueBinUint() called for "
"non-OPTTYPE_BINUINT "
"option '%s'\n", optionDescP->name);
abort();
} else {
if (optionDescP->present)
retval = optionDescP->value.llu;
else
retval = 0;
}
}
return retval;
}
double
cmd_getOptionValueFloat(cmdlineParser const cpP,
const char * const name) {
struct optionDesc * const optionDescP = findOptionDesc(cpP, name);
double retval;
if (!optionDescP) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueInt() called for undefined option '%s'\n",
name);
abort();
} else {
if (optionDescP->type != OPTTYPE_FLOAT) {
fprintf(stderr, "cmdlineParser called incorrectly. "
"cmd_getOptionValueInt() called for non-float "
"option '%s'\n", optionDescP->name);
abort();
} else {
if (optionDescP->present)
retval = optionDescP->value.d;
else
retval = 0.0;
}
}
return retval;
}
unsigned int
cmd_argumentCount(cmdlineParser const cpP) {
return cpP->numArguments;
}
const char *
cmd_getArgument(cmdlineParser const cpP,
unsigned int const argNumber) {
const char * retval;
if (argNumber >= cpP->numArguments)
retval = NULL;
else {
retval = strdup(cpP->argumentArray[argNumber]);
if (retval == NULL) {
fprintf(stderr,
"out of memory in cmd_getArgument()\n");
abort();
}
}
return retval;
}

View File

@ -0,0 +1,157 @@
#include <string>
#include <stdexcept>
#include "girstring.h"
#include "casprintf.h"
#include "cmdline_parser.h"
#include "cmdline_parser.hpp"
using namespace std;
static enum optiontype
optTypeConvert(
CmdlineParser::optType const arg) {
enum optiontype retval;
retval = OPTTYPE_FLAG; // defeat compiler warning
switch (arg) {
case CmdlineParser::FLAG: retval = OPTTYPE_FLAG; break;
case CmdlineParser::INT: retval = OPTTYPE_INT; break;
case CmdlineParser::UINT: retval = OPTTYPE_UINT; break;
case CmdlineParser::STRING: retval = OPTTYPE_STRING; break;
case CmdlineParser::BINUINT: retval = OPTTYPE_BINUINT; break;
case CmdlineParser::FLOAT: retval = OPTTYPE_FLOAT; break;
}
return retval;
}
CmdlineParser::CmdlineParser() {
this->cp = cmd_createOptionParser();
}
CmdlineParser::~CmdlineParser() {
cmd_destroyOptionParser(this->cp);
}
void
CmdlineParser::defineOption(
string const optionName,
optType const optionType) {
cmd_defineOption(this->cp, optionName.c_str(),
optTypeConvert(optionType));
}
void
CmdlineParser::processOptions(
int const argc,
const char ** const argv) {
const char * error;
cmd_processOptions(this->cp, argc, argv, &error);
if (error) {
string const errorS(error);
strfree(error);
throw(runtime_error(errorS));
}
}
bool
CmdlineParser::optionIsPresent(
string const optionName) const {
return (cmd_optionIsPresent(this->cp, optionName.c_str()) ? true : false);
}
int
CmdlineParser::getOptionValueInt(
string const optionName) const {
return cmd_getOptionValueInt(this->cp, optionName.c_str());
}
unsigned int
CmdlineParser::getOptionValueUint(
string const optionName) const {
return cmd_getOptionValueUint(this->cp, optionName.c_str());
}
unsigned long long
CmdlineParser::getOptionValueBinUint(
string const optionName) const {
return cmd_getOptionValueBinUint(this->cp, optionName.c_str());
}
double
CmdlineParser::getOptionValueFloat(
string const optionName) const {
return cmd_getOptionValueFloat(this->cp, optionName.c_str());
}
string
CmdlineParser::getOptionValueString(
string const optionName) const {
const char * const value =
cmd_getOptionValueString(this->cp, optionName.c_str());
string retval;
if (value) {
retval = string(value);
strfree(value);
} else
retval = "";
return retval;
}
unsigned int
CmdlineParser::argumentCount() const {
return cmd_argumentCount(this->cp);
}
string
CmdlineParser::getArgument(
unsigned int const argNumber) const {
const char * const value = cmd_getArgument(this->cp, argNumber);
string const retval(value);
strfree(value);
return retval;
}

View File

@ -0,0 +1,466 @@
/* This version of `getopt' appears to the caller like standard Unix getopt()
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As getopt() works, it permutes the elements of `argv' so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getoptx.h"
/* Note that on some systems, the header files above declare variables
for use with their native getopt facilities, and those variables have
the same names as we'd like to use. So we use things like optargx
instead of optarg to avoid the collision.
*/
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
*/
static char *optargx = 0;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to getoptx().
On entry to getoptx(), zero means this is the first call; initialize.
When getoptx() returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optindx' communicates from one call to the next
how much of ARGV has been scanned so far.
*/
static int optindx = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options.
*/
static int opterrx;
/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found.
Only valid when a long-named option was found. */
static int option_index;
struct optionx * _getopt_long_options;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optindx), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void
exchange(char ** const argv) {
unsigned int const nonopts_size =
(last_nonopt - first_nonopt) * sizeof (char *);
char **temp = (char **) malloc (nonopts_size);
if (temp == NULL)
abort();
/* Interchange the two blocks of data in argv. */
memcpy (temp, &argv[first_nonopt], nonopts_size);
memcpy (&argv[first_nonopt], &argv[last_nonopt],
(optindx - last_nonopt) * sizeof (char *));
memcpy (&argv[first_nonopt + optindx - last_nonopt], temp,
nonopts_size);
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optindx - last_nonopt);
last_nonopt = optindx;
free(temp);
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If getoptx()
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If getoptx() finds another option character, it returns that character,
updating `optindx' and `nextchar' so that the next call to getoptx() can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, getoptx() returns `EOF'.
Then `optindx' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterrx' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optargx'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optargx', otherwise `optargx' is set to zero.
If OPTSTRING starts with `-', it requests a different method of handling the
non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above.
Long-named options begin with `+' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
getoptx() returns 0 when it finds a long-named option. */
static int
getoptx(int const argc,
char ** const argv,
const char * const optstring) {
optargx = 0;
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
if (optindx == 0)
{
first_nonopt = last_nonopt = optindx = 1;
nextchar = 0;
}
if (nextchar == 0 || *nextchar == 0)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optindx)
exchange (argv);
else if (last_nonopt != optindx)
first_nonopt = optindx;
/* Now skip any additional non-options
and extend the range of non-options previously skipped. */
while (optindx < argc
&& (argv[optindx][0] != '-'|| argv[optindx][1] == 0)
&& (argv[optindx][0] != '+'|| argv[optindx][1] == 0))
optindx++;
last_nonopt = optindx;
/* Special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optindx != argc && !strcmp (argv[optindx], "--"))
{
optindx++;
if (first_nonopt != last_nonopt && last_nonopt != optindx)
exchange (argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optindx;
last_nonopt = argc;
optindx = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optindx == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optindx = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass
it by.
*/
if ((argv[optindx][0] != '-' || argv[optindx][1] == 0)
&& (argv[optindx][0] != '+' || argv[optindx][1] == 0))
{
optargx = argv[optindx++];
return 1;
}
/* We have found another option-ARGV-element.
Start decoding its characters. */
nextchar = argv[optindx] + 1;
}
if ((argv[optindx][0] == '+' || (argv[optindx][0] == '-'))
)
{
struct optionx *p;
char *s = nextchar;
int exact = 0;
int ambig = 0;
struct optionx * pfound;
int indfound;
while (*s && *s != '=') s++;
indfound = 0; /* quite compiler warning */
/* Test all options for either exact match or abbreviated matches. */
for (p = _getopt_long_options, option_index = 0, pfound = NULL;
p->name;
p++, option_index++)
if (!strncmp (p->name, nextchar, s - nextchar))
{
if ((unsigned int)(s - nextchar) == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (!pfound)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
fprintf (stderr, "%s: option `%s' is ambiguous\n",
argv[0], argv[optindx]);
nextchar += strlen (nextchar);
return '?';
}
if (pfound)
{
option_index = indfound;
optindx++;
if (*s)
{
if (pfound->has_arg > 0)
optargx = s + 1;
else
{
fprintf (stderr,
"%s: option `%c%s' doesn't allow an argument\n",
argv[0], argv[optindx - 1][0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg)
{
if (optindx < argc)
optargx = argv[optindx++];
else if (pfound->has_arg != 2)
{
fprintf (stderr, "%s: option `%s' requires an argument\n",
argv[0], argv[optindx - 1]);
nextchar += strlen (nextchar);
return '?';
}
}
nextchar += strlen (nextchar);
if (pfound->flag)
*(pfound->flag) = pfound->val;
return 0;
}
if (argv[optindx][0] == '+' || strchr (optstring, *nextchar) == 0)
{
if (opterrx != 0)
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
argv[0], argv[optindx][0], nextchar);
nextchar += strlen (nextchar);
return '?';
}
}
/* Look at and handle the next option-character. */
{
char c = *nextchar++;
char *temp = strchr (optstring, c);
/* Increment `optindx' when we start to process its last character. */
if (*nextchar == 0)
optindx++;
if (temp == 0 || c == ':')
{
if (opterrx != 0)
{
if (c < 040 || c >= 0177)
fprintf (stderr, "%s: unrecognized option, "
"character code 0%o\n",
argv[0], c);
else
fprintf (stderr, "%s: unrecognized option `-%c'\n",
argv[0], c);
}
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != 0)
{
optargx = nextchar;
optindx++;
}
else
optargx = 0;
nextchar = 0;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != 0)
{
optargx = nextchar;
/* If we end this ARGV-element by taking the rest
as an arg, we must advance to the next element
now.
*/
optindx++;
}
else if (optindx == argc)
{
if (opterrx != 0)
fprintf (stderr,
"%s: option `-%c' requires an argument\n",
argv[0], c);
c = '?';
}
else
/* We already incremented `optindx' once;
increment it again when taking next ARGV-elt as
argument.
*/
optargx = argv[optindx++];
nextchar = 0;
}
}
return c;
}
}
void
getopt_long_onlyx(int const argc,
char ** const argv,
const char * const options,
struct optionx * const long_options,
unsigned int * const opt_index,
int const opterrArg,
int * const end_of_options,
const char ** const optarg_arg,
const char ** const unrecognized_option) {
int rc;
opterrx = opterrArg;
_getopt_long_options = long_options;
rc = getoptx(argc, argv, options);
if (rc == 0)
*opt_index = option_index;
if (rc == '?')
*unrecognized_option = argv[optindx];
else
*unrecognized_option = NULL;
if (rc < 0)
*end_of_options = 1;
else
*end_of_options = 0;
*optarg_arg = optargx;
}
unsigned int
getopt_argstart(void) {
/*----------------------------------------------------------------------------
This is a replacement for what traditional getopt does with global
variables.
You call this after getopt_long_onlyx() has returned "end of
options"
-----------------------------------------------------------------------------*/
return optindx;
}
/* Getopt for GNU.
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

View File

@ -0,0 +1,51 @@
/* Interface to getopt_long_onlyx() */
enum argreq {no_argument, required_argument, optional_argument};
struct optionx {
/* This describes an option. If the field `flag' is nonzero, it
points to a variable that is to be set to the value given in
the field `val' when the option is found, but left unchanged if
the option is not found.
*/
const char * name;
enum argreq has_arg;
int * flag;
int val;
};
/* long_options[] is a list terminated by an element that contains
a NULL 'name' member.
*/
void
getopt_long_onlyx(int const argc,
char ** const argv,
const char * const options,
struct optionx * const long_options,
unsigned int * const opt_index,
int const opterrArg,
int * const end_of_options,
const char ** const optarg_arg,
const char ** const unrecognized_option);
unsigned int
getopt_argstart(void);
/*
Copyright (C) 1989 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

View File

@ -0,0 +1,27 @@
#ifndef ASSERTX_HPP_INCLUDED
#define ASSERTX_HPP_INCLUDED
#include <cassert>
/* The compiler often warns you if you give a function formal parameter a
name, but don't use it. But because assert() disappears when doing an
optimized build, the compiler doesn't recognize your reference to the
parameter in the assert() argument. To avoid the bogus warning in
this case, we have ASSERT_ONLY_ARG(), which declares a name for a
formal parameter for purposes of assert() only. In cases where an
assert() would disappear, ASSERT_ONLY_ARG() disappears too.
E.g.
void foo(int const ASSERT_ONLY_ARG(arg1)) {
assert(arg1 > 0);
}
*/
#ifdef NDEBUG
#define ASSERT_ONLY_ARG(x)
#else
#define ASSERT_ONLY_ARG(x) x
#endif
#endif

View File

@ -0,0 +1,18 @@
/* This takes the place of C99 stdbool.h, which at least some Windows
compilers don't have. (October 2005).
One must not also include <stdbool.h>, because it might cause a name
collision.
*/
#ifndef __cplusplus
/* At least the GNU compiler defines __bool_true_false_are_defined */
#ifndef __bool_true_false_are_defined
#define __bool_true_false_are_defined
typedef enum {
false = 0,
true = 1
} bool;
#endif
#endif

View File

@ -0,0 +1,19 @@
#ifndef C_UTIL_H_INCLUDED
#define C_UTIL_H_INCLUDED
/* C language stuff. Doesn't involve any libraries that aren't part of
the compiler.
*/
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
/* GNU_PRINTF_ATTR lets the GNU compiler check printf-type
calls to be sure the arguments match the format string, thus preventing
runtime segmentation faults and incorrect messages.
*/
#ifdef __GNUC__
#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
#else
#define GNU_PRINTF_ATTR(a,b)
#endif
#endif

View File

@ -0,0 +1,29 @@
#ifndef CASPRINTF_H_INCLUDED
#define CASPRINTF_H_INCLUDED
#include <stdarg.h>
#include "c_util.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const char * const strsol;
void
cvasprintf(const char ** const retvalP,
const char * const fmt,
va_list varargs);
void GNU_PRINTF_ATTR(2,3)
casprintf(const char ** const retvalP, const char * const fmt, ...);
void
strfree(const char * const string);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,86 @@
#ifndef CMDLINE_PARSER_H
#define CMDLINE_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
#if 0
} /* to fake out automatic code indenters */
#endif
#include "int.h"
/*
NOTE NOTE NOTE: cmd_getOptionValueString() and
cmd_getArgument() return malloc'ed memory (and abort the program if
out of memory). You must free it.
*/
enum optiontype {
OPTTYPE_FLAG,
OPTTYPE_INT,
OPTTYPE_UINT,
OPTTYPE_STRING,
OPTTYPE_BINUINT,
OPTTYPE_FLOAT
};
struct cmdlineParserCtl;
typedef struct cmdlineParserCtl * cmdlineParser;
void
cmd_processOptions(cmdlineParser const cpP,
int const argc,
const char ** const argv,
const char ** const errorP);
cmdlineParser
cmd_createOptionParser(void);
void
cmd_destroyOptionParser(cmdlineParser const cpP);
void
cmd_defineOption(cmdlineParser const cpP,
const char * const name,
enum optiontype const type);
int
cmd_optionIsPresent(cmdlineParser const cpP,
const char * const name);
int
cmd_getOptionValueInt(cmdlineParser const cpP,
const char * const name);
unsigned int
cmd_getOptionValueUint(cmdlineParser const cpP,
const char * const name);
const char *
cmd_getOptionValueString(cmdlineParser const cpP,
const char * const name);
uint64_t
cmd_getOptionValueBinUint(cmdlineParser const cpP,
const char * const name);
double
cmd_getOptionValueFloat(cmdlineParser const cpP,
const char * const name);
unsigned int
cmd_argumentCount(cmdlineParser const cpP);
const char *
cmd_getArgument(cmdlineParser const cpP,
unsigned int const argNumber);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,59 @@
#ifndef CMDLINE_PARSER_HPP_INCLUDED
#define CMDLINE_PARSER_HPP_INCLUDED
#include <string>
struct cmdlineParserCtl;
class CmdlineParser {
public:
CmdlineParser();
~CmdlineParser();
enum optType {FLAG, INT, UINT, STRING, BINUINT, FLOAT};
void
defineOption(std::string const optionName,
optType const optionType);
void
processOptions(int const argc,
const char ** const argv);
bool
optionIsPresent(std::string const optionName) const;
int
getOptionValueInt(std::string const optionName) const;
unsigned int
getOptionValueUint(std::string const optionName) const;
std::string
getOptionValueString(std::string const optionName) const;
unsigned long long
getOptionValueBinUint(std::string const optionName) const;
double
getOptionValueFloat(std::string const optionName) const;
unsigned int
argumentCount() const;
std::string
getArgument(unsigned int const argNumber) const;
private:
struct cmdlineParserCtl * cp;
// Make sure no one can copy this object, because if there are two
// copies, there will be two attempts to destroy *cp.
CmdlineParser(CmdlineParser const&) {};
CmdlineParser&
operator=(CmdlineParser const&) {return *this;}
};
#endif

View File

@ -0,0 +1,8 @@
#ifndef __GIRMATH_H
#define __GIRMATH_H
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

View File

@ -0,0 +1,51 @@
#ifndef GIRSTRING_H_INCLUDED
#define GIRSTRING_H_INCLUDED
#include <string.h>
#include "xmlrpc_config.h"
#include "bool.h"
bool
stripcaseeq(const char * const comparand,
const char * const comparator);
static __inline__ bool
streq(const char * const comparator,
const char * const comparand) {
return (strcmp(comparand, comparator) == 0);
}
static __inline__ bool
memeq(const void * const comparator,
const void * const comparand,
size_t const size) {
return (memcmp(comparator, comparand, size) == 0);
}
#define MEMEQ(a,b,c) (memcmp(a, b, c) == 0)
#define MEMSSET(a,b) (memset(a, b, sizeof(*a)))
#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*a)))
#define MEMSZERO(a) (MEMSSET(a, 0))
static __inline__ const char *
sdup(const char * const input) {
return (const char *) strdup(input);
}
/* Copy string pointed by B to array A with size checking. */
#define STRSCPY(A,B) \
(strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0')
#define STRSCMP(A,B) \
(strncmp((A), (B), sizeof(A)))
/* Concatenate string B onto string in array A with size checking */
#define STRSCAT(A,B) \
(strncat((A), (B), sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0')
#endif

View File

@ -0,0 +1,19 @@
#ifndef XMLRPC_INLINE_H_INCLUDED
#define XMLRPC_INLINE_H_INCLUDED
/* Xmlrpc-c uses __inline__ to declare functions that should be
compiled as inline code. Some compilers, e.g. GNU, recognize the
__inline__ keyword.
*/
#ifndef __GNUC__
#ifndef __inline__
#ifdef __sgi
#define __inline__ __inline
#else
#define __inline__
#endif
#endif
#endif
#endif

View File

@ -0,0 +1,58 @@
/* This takes the place of C99 inttypes.h, which at least some Windows
compilers don't have. (October 2007).
*/
/* PRId64 is the printf-style format specifier for a long long type, as in
long long mynumber = 5;
printf("My number is %" PRId64 ".\n", mynumber);
The LL/ULL macro is for 64 bit integer literals, like this:
long long mask= ULL(1) << 33;
*/
/* 'uint' is quite convenient, but there's no simple way have it everywhere.
Some systems have it in the base system (e.g. GNU C library has it in
<sys/types.h>, and others (e.g. Solaris - 08.12.02) don't. Since we
can't define it unless we know it's not defined already, and we don't
want to burden the reader with a special Xmlrpc-c name such as xuint,
we just use standard "unsigned int" instead.
*/
#ifdef _MSC_VER
# define PRId64 "I64d"
# define PRIu64 "I64u"
#ifndef int16_t
typedef short int16_t;
#endif
#ifndef uint16_t
typedef unsigned short uint16_t;
#endif
#ifndef int32_t
typedef int int32_t;
#endif
#ifndef uint32_t
typedef unsigned int uint32_t;
#endif
#ifndef int64_t
typedef __int64 int64_t;
#endif
#ifndef uint64_t
typedef unsigned __int64 uint64_t;
#endif
#ifndef uint8_t
typedef unsigned char uint8_t;
#endif
/* Older Microsoft compilers don't know the standard ll/ull suffixes */
#define LL(x) x ## i64
#define ULL(x) x ## u64
#else
/* Not Microsoft compiler */
#include <inttypes.h>
#define LL(x) x ## ll
#define ULL(x) x ## ull
#endif

View File

@ -0,0 +1,193 @@
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
#include "inline.h"
struct list_head {
/*----------------------------------------------------------------------------
This is a header for an element of a doubly linked list, or an anchor
for such a list.
itemP == NULL means it's an anchor; otherwise it's a header.
Initialize a list header with list_init_header(). You don't have to
do anything to terminate a list header.
Initialize an anchor with list_make_emtpy(). You don't have to do anything
to terminate a list header.
-----------------------------------------------------------------------------*/
struct list_head * nextP;
/* For a header, this is the address of the list header for
the next element in the list. If there is no next element,
it points to the anchor. If the header is not in a list at
all, it is NULL.
For an anchor, it is the address of the list header of the
first element. If the list is empty, it points to the
anchor itself.
*/
struct list_head * prevP;
/* For a header, this is the address of the list header for
the previous element in the list. If there is no previous element,
it points to the anchor. If the header is not in a list at
all, it is NULL.
For an anchor, it is the address of the list header of the
last element. If the list is empty, it points to the
anchor itself.
*/
void * itemP;
/* For a header, this is the address of the list element to which it
belongs. For an anchor, this is NULL.
*/
};
static __inline__ void
list_init_header(struct list_head * const headerP,
void * const itemP) {
headerP->prevP = NULL;
headerP->nextP = NULL;
headerP->itemP = itemP;
}
static __inline__ int
list_is_linked(struct list_head * headerP) {
return headerP->prevP != NULL;
}
static __inline__ int
list_is_empty(struct list_head * const anchorP) {
return anchorP->nextP == anchorP;
}
static __inline__ unsigned int
list_count(struct list_head * const anchorP) {
unsigned int count;
struct list_head * p;
for (p = anchorP->nextP, count = 0;
p != anchorP;
p = p->nextP, ++count);
return count;
}
static __inline__ void
list_make_empty(struct list_head * const anchorP) {
anchorP->prevP = anchorP;
anchorP->nextP = anchorP;
anchorP->itemP = NULL;
}
static __inline__ void
list_insert_after(struct list_head * const beforeHeaderP,
struct list_head * const newHeaderP) {
newHeaderP->prevP = beforeHeaderP;
newHeaderP->nextP = beforeHeaderP->nextP;
beforeHeaderP->nextP = newHeaderP;
newHeaderP->nextP->prevP = newHeaderP;
}
static __inline__ void
list_add_tail(struct list_head * const anchorP,
struct list_head * const headerP) {
list_insert_after(anchorP->prevP, headerP);
}
static __inline__ void
list_add_head(struct list_head * const anchorP,
struct list_head * const headerP) {
list_insert_after(anchorP, headerP);
}
static __inline__ void
list_remove(struct list_head * const headerP) {
headerP->prevP->nextP = headerP->nextP;
headerP->nextP->prevP = headerP->prevP;
headerP->prevP = NULL;
headerP->nextP = NULL;
}
static __inline__ struct list_head *
list_remove_head(struct list_head * const anchorP) {
struct list_head * retval;
if (list_is_empty(anchorP))
retval = NULL;
else {
retval = anchorP->nextP;
list_remove(retval);
}
return retval;
}
static __inline__ struct list_head *
list_remove_tail(struct list_head * const anchorP) {
struct list_head * retval;
if (list_is_empty(anchorP))
retval = NULL;
else {
retval = anchorP->prevP;
list_remove(retval);
}
return retval;
}
static __inline__ void *
list_foreach(struct list_head * const anchorP,
void * functionP(struct list_head *, void *),
void * const context) {
struct list_head * p;
struct list_head * nextP;
void * result;
for (p = anchorP->nextP, nextP = p->nextP, result=NULL;
p != anchorP && result == NULL;
p = nextP, nextP = p->nextP)
result = (*functionP)(p, context);
return result;
}
static __inline__ void
list_append(struct list_head * const newAnchorP,
struct list_head * const baseAnchorP) {
if (!list_is_empty(newAnchorP)) {
baseAnchorP->prevP->nextP = newAnchorP->nextP;
newAnchorP->nextP->prevP = baseAnchorP->prevP;
newAnchorP->prevP->nextP = baseAnchorP;
baseAnchorP->prevP = newAnchorP->prevP;
}
}
#endif

View File

@ -0,0 +1,111 @@
/* These are some dynamic memory allocation facilities. They are essentially
an extension to C, as they do allocations with a cognizance of C
variables. You can use them to make C read more like a high level
language.
Before including this, you must define an __inline__ macro if your
compiler doesn't recognize it as a keyword.
*/
#ifndef MALLOCVAR_INCLUDED
#define MALLOCVAR_INCLUDED
#include "xmlrpc_config.h"
#include <limits.h>
#include <stdlib.h>
static __inline__ void
mallocProduct(void ** const resultP,
unsigned int const factor1,
unsigned int const factor2) {
/*----------------------------------------------------------------------------
malloc a space whose size in bytes is the product of 'factor1' and
'factor2'. But if that size cannot be represented as an unsigned int,
return NULL without allocating anything. Also return NULL if the malloc
fails.
If either factor is zero, malloc a single byte.
Note that malloc() actually takes a size_t size argument, so the
proper test would be whether the size can be represented by size_t,
not unsigned int. But there is no reliable indication available to
us, like UINT_MAX, of what the limitations of size_t are. We
assume size_t is at least as expressive as unsigned int and that
nobody really needs to allocate more than 4GB of memory.
-----------------------------------------------------------------------------*/
if (factor1 == 0 || factor2 == 0)
*resultP = malloc(1);
else {
if (UINT_MAX / factor2 < factor1)
*resultP = NULL;
else
*resultP = malloc(factor1 * factor2);
}
}
static __inline__ void
reallocProduct(void ** const blockP,
unsigned int const factor1,
unsigned int const factor2) {
void * const oldBlockP = *blockP;
void * newBlockP;
if (UINT_MAX / factor2 < factor1)
newBlockP = NULL;
else
newBlockP = realloc(oldBlockP, factor1 * factor2);
if (newBlockP)
*blockP = newBlockP;
else {
free(oldBlockP);
*blockP = NULL;
}
}
/* IMPLEMENTATION NOTE: There are huge strict aliasing pitfalls here
if you cast pointers, e.g. (void **)
*/
#define MALLOCARRAY(arrayName, nElements) do { \
void * array; \
mallocProduct(&array, nElements, sizeof(arrayName[0])); \
arrayName = array; \
} while (0)
#define REALLOCARRAY(arrayName, nElements) do { \
void * array = arrayName; \
reallocProduct(&array, nElements, sizeof(arrayName[0])); \
arrayName = array; \
} while (0)
#define MALLOCARRAY_NOFAIL(arrayName, nElements) \
do { \
MALLOCARRAY(arrayName, nElements); \
if ((arrayName) == NULL) \
abort(); \
} while(0)
#define REALLOCARRAY_NOFAIL(arrayName, nElements) \
do { \
REALLOCARRAY(arrayName, nElements); \
if ((arrayName) == NULL) \
abort(); \
} while(0)
#define MALLOCVAR(varName) \
varName = malloc(sizeof(*varName))
#define MALLOCVAR_NOFAIL(varName) \
do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0)
#endif

View File

@ -0,0 +1,80 @@
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#ifndef PTHREADX_H_INCLUDED
#define PTHREADX_H_INCLUDED
#ifndef WIN32
# define _REENTRANT
# include <pthread.h>
#elif defined (WIN32)
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef HANDLE pthread_t;
typedef CRITICAL_SECTION pthread_mutex_t;
#define PTHREAD_MUTEX_INITIALIZER NULL
/* usage: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; */
typedef
struct {
int attrs; /* currently unused. placeholder. */
} pthread_attr_t;
typedef
struct {
int attrs; /* currently unused. placeholder. */
} pthread_mutexattr_t;
/* We make pthread_func identical to a Windows thread start function
so we can use Windows thread functions to implement these pthread
functions directly.
*/
typedef unsigned (WINAPI pthread_func)(void *);
extern int pthread_create(pthread_t * const new_thread_ID,
const pthread_attr_t * const attr,
pthread_func * start_func,
void * const arg);
extern int pthread_cancel(pthread_t target_thread);
extern int pthread_join(pthread_t target_thread, void **status);
extern int pthread_detach(pthread_t target_thread);
extern int pthread_mutex_init(pthread_mutex_t * const mp,
const pthread_mutexattr_t * const attr);
extern int pthread_mutex_lock(pthread_mutex_t * const mp);
extern int pthread_mutex_unlock(pthread_mutex_t * const mp);
extern int pthread_mutex_destroy(pthread_mutex_t * const mp);
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */
#endif

View File

@ -0,0 +1,67 @@
#ifndef STDARGX_H_INCLUDED
#define STDARGX_H_INCLUDED
#include "xmlrpc_config.h"
#include <stdarg.h>
#include <string.h>
/*----------------------------------------------------------------------------
We need a special version of va_list in order to pass around the
variable argument heap by reference, thus allowing a subroutine to
advance the heap's pointer.
On some systems (e.g. Gcc for PPC or AMD64), va_list is an array.
That invites the scourge of array-to-pointer degeneration if you try
to take its address. Burying it inside a struct as we do with out
va_listx type makes it immune.
Example of what would happen if we used va_list instead of va_listx,
on a system where va_list is an array:
void sub2(va_list * argsP) [
...
}
void sub1(va_list args) {
sub2(&args);
}
This doesn't work. '&args' is the same thing as 'args', so is
va_list, not va_list *. The compiler will even warn you about the
pointer type mismatch.
To use va_listx:
void sub1_va(char * format, va_list args) {
va_listx argsx;
init_va_listx(&argsx, args);
sub2(format, &argsx);
}
-----------------------------------------------------------------------------*/
typedef struct {
/*----------------------------------------------------------------------------
Same thing as va_list, but in a form that works everywhere. See above.
-----------------------------------------------------------------------------*/
va_list v;
} va_listx;
static __inline__ void
init_va_listx(va_listx * const argsxP,
va_list const args) {
#if VA_LIST_IS_ARRAY
/* 'args' is NOT a va_list. It is a pointer to the first element of a
'va_list', which is the same address as a pointer to the va_list
itself.
*/
memcpy(&argsxP->v, args, sizeof(argsxP->v));
#else
argsxP->v = args;
#endif
}
#endif

View File

@ -0,0 +1,31 @@
#ifndef STRING_PARSER_H_INCLUDED
#define STRING_PARSER_H_INCLUDED
#include "int.h"
void
interpretUll(const char * const string,
uint64_t * const ullP,
const char ** const errorP);
void
interpretLl(const char * const string,
int64_t * const llP,
const char ** const errorP);
void
interpretUint(const char * const string,
unsigned int * const uintP,
const char ** const errorP);
void
interpretInt(const char * const string,
int * const uintP,
const char ** const errorP);
void
interpretBinUint(const char * const string,
uint64_t * const valueP,
const char ** const errorP);
#endif

View File

@ -0,0 +1,14 @@
#ifndef UNISTDX_H_INCLUDED
#define UNISTDX_H_INCLUDED
/* Xmlrpc-c code #includes "unistdx.h" instead of <unistd.h> because
<unistd.h> does not exist on WIN32.
*/
#ifndef WIN32
# include <unistd.h>
#else
#endif /* WIN32 */
#endif

View File

@ -0,0 +1,123 @@
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#include "xmlrpc_config.h"
#ifdef WIN32
#include "pthreadx.h"
#include <process.h>
#undef PACKAGE
#undef VERSION
int
pthread_create(pthread_t * const new_thread_ID,
const pthread_attr_t * const attr,
pthread_func * func,
void * const arg) {
HANDLE hThread;
DWORD dwThreadID;
hThread = (HANDLE) _beginthreadex (
NULL, 0, func, (LPVOID)arg, CREATE_SUSPENDED, &dwThreadID);
SetThreadPriority (hThread, THREAD_PRIORITY_NORMAL);
ResumeThread (hThread);
*new_thread_ID = hThread;
return hThread ? 0 : -1;
}
/* Just kill it. */
int
pthread_cancel(pthread_t const target_thread) {
CloseHandle(target_thread);
return 0;
}
/* Waits for the thread to exit before continuing. */
int
pthread_join(pthread_t const target_thread,
void ** const statusP) {
DWORD dwResult = WaitForSingleObject(target_thread, INFINITE);
*statusP = (void *)dwResult;
return 0;
}
int
pthread_detach(pthread_t const target_thread) {
return 0;
}
int
pthread_mutex_init(pthread_mutex_t * const mp,
const pthread_mutexattr_t * const attr) {
InitializeCriticalSection(mp);
return 0;
}
int
pthread_mutex_lock(pthread_mutex_t * const mp) {
EnterCriticalSection(mp);
return 0;
}
int
pthread_mutex_unlock(pthread_mutex_t * const mp) {
LeaveCriticalSection(mp);
return 0;
}
int
pthread_mutex_destroy(pthread_mutex_t * const mp) {
DeleteCriticalSection(mp);
return 0;
}
#endif

View File

@ -0,0 +1,226 @@
#include <sys/types.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include "int.h"
#include "girstring.h"
#include "casprintf.h"
#include "string_parser.h"
static const char *
strippedSubstring(const char * const string) {
const char * p;
for (p = &string[0]; isspace(*p); ++p);
return p;
}
void
interpretUll(const char * const string,
uint64_t * const ullP,
const char ** const errorP) {
/* strtoull() has the same disappointing weaknesses of strtoul().
See interpretUint().
*/
const char * const strippedString = strippedSubstring(string);
if (strippedString[0] == '\0')
casprintf(errorP, "Null (or all whitespace) string.");
else if (!isdigit(strippedString[0]))
casprintf(errorP, "First non-blank character is '%c', not a digit.",
strippedString[0]);
else {
/* strtoull() does a bizarre thing where if the number is out
of range, it returns a clamped value but tells you about it
by setting errno = ERANGE. If it is not out of range,
strtoull() leaves errno alone.
*/
char * tail;
errno = 0; /* So we can tell if strtoull() overflowed */
*ullP = strtoull(strippedString, &tail, 10);
if (tail[0] != '\0')
casprintf(errorP, "Non-digit stuff in string: %s", tail);
else if (errno == ERANGE)
casprintf(errorP, "Number too large");
else
*errorP = NULL;
}
}
void
interpretLl(const char * const string,
int64_t * const llP,
const char ** const errorP) {
if (string[0] == '\0')
casprintf(errorP, "Null string.");
else {
/* strtoll() does a bizarre thing where if the number is out
of range, it returns a clamped value but tells you about it
by setting errno = ERANGE. If it is not out of range,
strtoll() leaves errno alone.
*/
char * tail;
errno = 0; /* So we can tell if strtoll() overflowed */
*llP = strtoll(string, &tail, 10);
if (tail[0] != '\0')
casprintf(errorP, "Non-digit stuff in string: %s", tail);
else if (errno == ERANGE)
casprintf(errorP, "Number too large");
else
*errorP = NULL;
}
}
void
interpretUint(const char * const string,
unsigned int * const uintP,
const char ** const errorP) {
/* strtoul() does a lousy job of dealing with invalid numbers. A null
string is just zero; a negative number is a large positive one; a
positive (cf unsigned) number is accepted. strtoul is inconsistent
in its treatment of the tail; if there is no valid number at all,
it returns the entire string as the tail, including leading white
space and sign, which are not themselves invalid.
*/
const char * const strippedString = strippedSubstring(string);
if (strippedString[0] == '\0')
casprintf(errorP, "Null (or all whitespace) string.");
else if (!isdigit(strippedString[0]))
casprintf(errorP, "First non-blank character is '%c', not a digit.",
strippedString[0]);
else {
/* strtoul() does a bizarre thing where if the number is out
of range, it returns a clamped value but tells you about it
by setting errno = ERANGE. If it is not out of range,
strtoul() leaves errno alone.
*/
char * tail;
unsigned long ulongValue;
errno = 0; /* So we can tell if strtoul() overflowed */
ulongValue = strtoul(strippedString, &tail, 10);
if (tail[0] != '\0')
casprintf(errorP, "Non-digit stuff in string: %s", tail);
else if (errno == ERANGE)
casprintf(errorP, "Number too large");
else if (ulongValue > UINT_MAX)
casprintf(errorP, "Number too large");
else {
*uintP = ulongValue;
*errorP = NULL;
}
}
}
void
interpretInt(const char * const string,
int * const intP,
const char ** const errorP) {
if (string[0] == '\0')
casprintf(errorP, "Null string.");
else {
/* strtol() does a bizarre thing where if the number is out
of range, it returns a clamped value but tells you about it
by setting errno = ERANGE. If it is not out of range,
strtol() leaves errno alone.
*/
char * tail;
long longValue;
errno = 0; /* So we can tell if strtol() overflowed */
longValue = strtol(string, &tail, 10);
if (tail[0] != '\0')
casprintf(errorP, "Non-digit stuff in string: %s", tail);
else if (errno == ERANGE)
casprintf(errorP, "Number too large");
else if (longValue > INT_MAX)
casprintf(errorP, "Number too large");
else if (longValue < INT_MIN)
casprintf(errorP, "Number too negative");
else {
*intP = longValue;
*errorP = NULL;
}
}
}
void
interpretBinUint(const char * const string,
uint64_t * const valueP,
const char ** const errorP) {
char * tailptr;
long const mantissa_long = strtol(string, &tailptr, 10);
if (errno == ERANGE)
casprintf(errorP,
"Numeric value out of range for computation: '%s'. "
"Try a smaller number with a K, M, G, etc. suffix.",
string);
else {
int64_t const mantissa = mantissa_long;
int64_t argNumber;
*errorP = NULL; /* initial assumption */
if (*tailptr == '\0')
/* There's no suffix. A pure number */
argNumber = mantissa * 1;
else if (stripcaseeq(tailptr, "K"))
argNumber = mantissa * 1024;
else if (stripcaseeq(tailptr, "M"))
argNumber = mantissa * 1024 * 1024;
else if (stripcaseeq(tailptr, "G"))
argNumber = mantissa * 1024 * 1024 * 1024;
else if (stripcaseeq(tailptr, "T"))
argNumber = mantissa * 1024 * 1024 * 1024 * 1024;
else if (stripcaseeq(tailptr, "P"))
argNumber = mantissa * 1024 * 1024 * 1024 * 1024 * 1024;
else {
argNumber = 0; /* quiet compiler warning */
casprintf(errorP, "Garbage suffix '%s' on number", tailptr);
}
if (!*errorP) {
if (argNumber < 0)
casprintf(errorP, "Unsigned numeric value is "
"negative: %" PRId64, argNumber);
else
*valueP = (uint64_t) argNumber;
}
}
}

View File

@ -0,0 +1,69 @@
#define _GNU_SOURCE
#include <ctype.h>
#include "bool.h"
#include "girstring.h"
bool
stripcaseeq(const char * const comparand,
const char * const comparator) {
/*----------------------------------------------------------------------------
Compare two strings, ignoring leading and trailing blanks and case.
Return true if the strings are identical, false otherwise.
-----------------------------------------------------------------------------*/
const char *p, *q, *px, *qx;
bool equal;
/* Make p and q point to the first non-blank character in each string.
If there are no non-blank characters, make them point to the terminating
NULL.
*/
p = &comparand[0];
while (*p == ' ')
++p;
q = &comparator[0];
while (*q == ' ')
++q;
/* Make px and qx point to the last non-blank character in each string.
If there are no nonblank characters (which implies the string is
null), make them point to the terminating NULL.
*/
if (*p == '\0')
px = p;
else {
px = p + strlen(p) - 1;
while (*px == ' ')
--px;
}
if (*q == '\0')
qx = q;
else {
qx = q + strlen(q) - 1;
while (*qx == ' ')
--qx;
}
equal = true; /* initial assumption */
/* If the stripped strings aren't the same length,
we know they aren't equal
*/
if (px - p != qx - q)
equal = false;
while (p <= px) {
if (toupper(*p) != toupper(*q))
equal = false;
++p; ++q;
}
return equal;
}

View File

@ -0,0 +1,757 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_H_INCLUDED
#define XMLRPC_H_INCLUDED
#include <stddef.h>
#include <stdarg.h>
#include <time.h>
#include <xmlrpc-c/util.h>
#include <xmlrpc-c/config.h>
/* Defines XMLRPC_HAVE_WCHAR, XMLRPC_INT64, XMLRPC_HAVE_TIMEVAL */
#if XMLRPC_HAVE_WCHAR
#include <wchar.h>
#endif
#if XMLRPC_HAVE_TIMEVAL
#include <sys/time.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*=========================================================================
** Version of libxmlrpc
**=======================================================================*/
extern unsigned int const xmlrpc_version_major;
extern unsigned int const xmlrpc_version_minor;
extern unsigned int const xmlrpc_version_point;
/*=========================================================================
** C types equivalent to XML-RPC types
**=======================================================================*/
/* We define names for these types, because they may change from platform
to platform.
*/
typedef signed int xmlrpc_int;
/* An integer of the type defined by XML-RPC <int>; i.e. 32 bit */
typedef XMLRPC_INT32 xmlrpc_int32;
/* An integer of the type defined by XML-RPC <i4>; i.e. 32 bit */
typedef XMLRPC_INT64 xmlrpc_int64;
/* An integer of the type defined by "XML-RPC" <i8>; i.e. 64 bit */
typedef int xmlrpc_bool;
/* A boolean (of the type defined by XML-RPC <boolean>, but there's
really only one kind)
*/
typedef double xmlrpc_double;
/* A double precision floating point number as defined by
XML-RPC <float>. But the C "double" type is universally the same,
so it's probably clearer just to use that. This typedef is here
for mathematical completeness.
*/
/* xmlrpc_socket is just for backward compatibility, in case someone decided
to use this in user code. New code should use the native type for a
socket (e.g. int or SOCKET). (We stopped using this because for winsock
users, we would have to #include <winsock.h> in every file that
#includes <xmlrpc-c/base.h> and we don't want that).
*/
typedef int xmlrpc_socket;
#define XMLRPC_INT32_MAX 0x7fffffff
#define XMLRPC_INT32_MIN (-XMLRPC_INT32_MAX - 1)
#define XMLRPC_INT64_MAX 0x7fffffffffffffffll
#define XMLRPC_INT64_MIN (-XMLRPC_INT64_MAX - 1)
/*=========================================================================
** xmlrpc_value
**=========================================================================
** An XML-RPC value (of any type).
*/
typedef enum {
XMLRPC_TYPE_INT = 0,
XMLRPC_TYPE_BOOL = 1,
XMLRPC_TYPE_DOUBLE = 2,
XMLRPC_TYPE_DATETIME = 3,
XMLRPC_TYPE_STRING = 4,
XMLRPC_TYPE_BASE64 = 5,
XMLRPC_TYPE_ARRAY = 6,
XMLRPC_TYPE_STRUCT = 7,
XMLRPC_TYPE_C_PTR = 8,
XMLRPC_TYPE_NIL = 9,
XMLRPC_TYPE_I8 = 10,
XMLRPC_TYPE_DEAD = 0xDEAD
} xmlrpc_type;
#define XMLRPC_HAVE_I8 1
/* These are *always* allocated on the heap. No exceptions. */
typedef struct _xmlrpc_value xmlrpc_value;
const char *
xmlrpc_type_name(xmlrpc_type const type);
void
xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP);
#define XMLRPC_ASSERT_ARRAY_OK(val) \
xmlrpc_abort_if_array_bad(val)
/* Increment the reference count of an xmlrpc_value. */
extern void xmlrpc_INCREF (xmlrpc_value* const value);
/* Decrement the reference count of an xmlrpc_value. If there
** are no more references, free it. */
extern void xmlrpc_DECREF (xmlrpc_value* const value);
/* Get the type of an XML-RPC value. */
extern xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value);
xmlrpc_value *
xmlrpc_int_new(xmlrpc_env * const envP,
int const intValue);
xmlrpc_value *
xmlrpc_i8_new(xmlrpc_env * const envP,
xmlrpc_int64 const value);
void
xmlrpc_read_int(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
int * const intValueP);
xmlrpc_value *
xmlrpc_bool_new(xmlrpc_env * const envP,
xmlrpc_bool const boolValue);
void
xmlrpc_read_bool(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_bool * const boolValueP);
xmlrpc_value *
xmlrpc_double_new(xmlrpc_env * const envP,
double const doubleValue);
void
xmlrpc_read_double(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_double * const doubleValueP);
xmlrpc_value *
xmlrpc_datetime_new_str(xmlrpc_env * const envP,
const char * const value);
xmlrpc_value *
xmlrpc_datetime_new_sec(xmlrpc_env * const envP,
time_t const value);
xmlrpc_value*
xmlrpc_datetime_new_usec(xmlrpc_env * const envP,
time_t const secs,
unsigned int const usecs);
#if XMLRPC_HAVE_TIMEVAL
xmlrpc_value *
xmlrpc_datetime_new_timeval(xmlrpc_env * const envP,
struct timeval const value);
#endif
#if XMLRPC_HAVE_TIMESPEC
xmlrpc_value *
xmlrpc_datetime_new_timespec(xmlrpc_env * const envP,
struct timespec const value);
#endif
void
xmlrpc_read_datetime_str(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_datetime_sec(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
time_t * const timeValueP);
void
xmlrpc_read_datetime_usec(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
time_t * const secsP,
unsigned int * const usecsP);
#if XMLRPC_HAVE_TIMEVAL
void
xmlrpc_read_datetime_timeval(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
struct timeval * const timeValueP);
#endif
#if XMLRPC_HAVE_TIMESPEC
void
xmlrpc_read_datetime_timespec(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
struct timespec * const timeValueP);
#endif
xmlrpc_value *
xmlrpc_string_new(xmlrpc_env * const envP,
const char * const stringValue);
xmlrpc_value *
xmlrpc_string_new_lp(xmlrpc_env * const envP,
size_t const length,
const char * const stringValue);
xmlrpc_value *
xmlrpc_string_new_va(xmlrpc_env * const envP,
const char * const format,
va_list args);
xmlrpc_value *
xmlrpc_string_new_f(xmlrpc_env * const envP,
const char * const format,
...);
xmlrpc_value *
xmlrpc_string_new_lp_cr(xmlrpc_env * const envP,
size_t const length,
const char * const value);
xmlrpc_value *
xmlrpc_string_new_cr(xmlrpc_env * const envP,
const char * const value);
void
xmlrpc_read_string(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_crlf(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const char ** const stringValueP);
void
xmlrpc_read_string_lp(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const char ** const stringValueP);
#if XMLRPC_HAVE_WCHAR
xmlrpc_value *
xmlrpc_string_w_new(xmlrpc_env * const envP,
const wchar_t * const stringValue);
xmlrpc_value *
xmlrpc_string_w_new_lp(xmlrpc_env * const envP,
size_t const length,
const wchar_t * const stringValue);
void
xmlrpc_read_string_w(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_crlf(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_lp(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
xmlrpc_value *
xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP,
size_t const length,
const wchar_t * const value);
xmlrpc_value *
xmlrpc_string_w_new_cr(xmlrpc_env * const envP,
const wchar_t * const value);
#endif /* XMLRPC_HAVE_WCHAR */
xmlrpc_value *
xmlrpc_base64_new(xmlrpc_env * const envP,
size_t const length,
const unsigned char * const value);
void
xmlrpc_read_base64(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const unsigned char ** const bytestringValueP);
void
xmlrpc_read_base64_size(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP);
xmlrpc_value *
xmlrpc_array_new(xmlrpc_env * const envP);
/* Return the number of elements in an XML-RPC array.
** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */
int
xmlrpc_array_size(xmlrpc_env * const env,
const xmlrpc_value * const array);
/* Append an item to an XML-RPC array.
** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */
extern void
xmlrpc_array_append_item (xmlrpc_env * const envP,
xmlrpc_value * const arrayP,
xmlrpc_value * const valueP);
void
xmlrpc_array_read_item(xmlrpc_env * const envP,
const xmlrpc_value * const arrayP,
unsigned int const index,
xmlrpc_value ** const valuePP);
/* Deprecated. Use xmlrpc_array_read_item() instead.
Get an item from an XML-RPC array.
Does not increment the reference count of the returned value.
Sets XMLRPC_TYPE_ERROR if 'array' is not an array.
Sets XMLRPC_INDEX_ERROR if 'index' is out of bounds.
*/
xmlrpc_value *
xmlrpc_array_get_item(xmlrpc_env * const envP,
const xmlrpc_value * const arrayP,
int const index);
/* Not implemented--we don't need it yet.
extern
int xmlrpc_array_set_item (xmlrpc_env* env,
xmlrpc_value* array,
int index,
xmlrpc_value* value);
*/
xmlrpc_value *
xmlrpc_struct_new(xmlrpc_env * const env);
/* Return the number of key/value pairs in a struct.
** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */
int
xmlrpc_struct_size (xmlrpc_env * env,
xmlrpc_value * strct);
/* Returns true iff 'strct' contains 'key'.
** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */
int
xmlrpc_struct_has_key(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
const char * const key);
/* The same as the above, but the key may contain zero bytes.
Deprecated. xmlrpc_struct_get_value_v() is more general, and this
case is not common enough to warrant a shortcut.
*/
int
xmlrpc_struct_has_key_n(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
const char * const key,
size_t const key_len);
#if 0
/* Not implemented yet, but needed for completeness. */
int
xmlrpc_struct_has_key_v(xmlrpc_env * env,
xmlrpc_value * strct,
xmlrpc_value * const keyval);
#endif
void
xmlrpc_struct_find_value(xmlrpc_env * const envP,
xmlrpc_value * const structP,
const char * const key,
xmlrpc_value ** const valuePP);
void
xmlrpc_struct_find_value_v(xmlrpc_env * const envP,
xmlrpc_value * const structP,
xmlrpc_value * const keyP,
xmlrpc_value ** const valuePP);
void
xmlrpc_struct_read_value(xmlrpc_env * const envP,
xmlrpc_value * const structP,
const char * const key,
xmlrpc_value ** const valuePP);
void
xmlrpc_struct_read_value_v(xmlrpc_env * const envP,
xmlrpc_value * const structP,
xmlrpc_value * const keyP,
xmlrpc_value ** const valuePP);
/* The "get_value" functions are deprecated. Use the "find_value"
and "read_value" functions instead.
*/
xmlrpc_value *
xmlrpc_struct_get_value(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
const char * const key);
/* The same as above, but the key may contain zero bytes.
Deprecated. xmlrpc_struct_get_value_v() is more general, and this
case is not common enough to warrant a shortcut.
*/
xmlrpc_value *
xmlrpc_struct_get_value_n(xmlrpc_env * const envP,
xmlrpc_value * const strctP,
const char * const key,
size_t const key_len);
/* Set the value associated with 'key' in 'strct' to 'value'.
Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct.
*/
void
xmlrpc_struct_set_value(xmlrpc_env * const env,
xmlrpc_value * const strct,
const char * const key,
xmlrpc_value * const value);
/* The same as above, but the key may contain zero bytes. Deprecated.
The general way to set a structure value is xmlrpc_struct_set_value_v(),
and this case is not common enough to deserve a shortcut.
*/
void
xmlrpc_struct_set_value_n(xmlrpc_env * const env,
xmlrpc_value * const strct,
const char * const key,
size_t const key_len,
xmlrpc_value * const value);
/* The same as above, but the key must be an XML-RPC string.
** Fails with XMLRPC_TYPE_ERROR if 'keyval' is not a string. */
void
xmlrpc_struct_set_value_v(xmlrpc_env * const env,
xmlrpc_value * const strct,
xmlrpc_value * const keyval,
xmlrpc_value * const value);
/* Given a zero-based index, return the matching key and value. This
** is normally used in conjunction with xmlrpc_struct_size.
** Fails with XMLRPC_TYPE_ERROR if 'struct' is not a struct.
** Fails with XMLRPC_INDEX_ERROR if 'index' is out of bounds. */
void
xmlrpc_struct_read_member(xmlrpc_env * const envP,
xmlrpc_value * const structP,
unsigned int const index,
xmlrpc_value ** const keyvalP,
xmlrpc_value ** const valueP);
/* The same as above, but does not increment the reference count of the
two values it returns, and return NULL for both if it fails, and
takes a signed integer for the index (but fails if it is negative).
Deprecated. Use xmlrpc_struct_read_member() instead.
*/
void
xmlrpc_struct_get_key_and_value(xmlrpc_env * const env,
xmlrpc_value * const strct,
int const index,
xmlrpc_value ** const out_keyval,
xmlrpc_value ** const out_value);
void
xmlrpc_read_cptr(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
void ** const ptrValueP);
void
xmlrpc_read_nil(xmlrpc_env * const envP,
xmlrpc_value * const valueP);
void
xmlrpc_read_i8(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_int64 * const intValueP);
xmlrpc_value *
xmlrpc_cptr_new(xmlrpc_env * const envP,
void * const value);
xmlrpc_value *
xmlrpc_nil_new(xmlrpc_env * const envP);
/* Build an xmlrpc_value from a format string. */
xmlrpc_value *
xmlrpc_build_value(xmlrpc_env * const env,
const char * const format,
...);
/* The same as the above, but using a va_list and more general */
void
xmlrpc_build_value_va(xmlrpc_env * const env,
const char * const format,
va_list const args,
xmlrpc_value ** const valPP,
const char ** const tailP);
void
xmlrpc_decompose_value(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
...);
void
xmlrpc_decompose_value_va(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
va_list const args);
/* xmlrpc_parse_value... is the same as xmlrpc_decompose_value... except
that it doesn't do proper memory management -- it returns xmlrpc_value's
without incrementing the reference count and returns pointers to data
inside an xmlrpc_value structure.
These are deprecated. Use xmlrpc_decompose_value... instead.
*/
void
xmlrpc_parse_value(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
...);
/* The same as the above, but using a va_list. */
void
xmlrpc_parse_value_va(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
va_list const args);
/*=========================================================================
** Encoding XML
**=======================================================================*/
typedef enum xmlrpc_dialect {
xmlrpc_dialect_i8,
xmlrpc_dialect_apache
} xmlrpc_dialect;
void
xmlrpc_serialize_value2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP,
xmlrpc_dialect const dialect);
void
xmlrpc_serialize_value(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP);
void
xmlrpc_serialize_params2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const paramArrayP,
xmlrpc_dialect const dialect);
void
xmlrpc_serialize_params(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const paramArrayP);
void
xmlrpc_serialize_call2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
const char * const methodName,
xmlrpc_value * const paramArrayP,
xmlrpc_dialect const dialect);
void
xmlrpc_serialize_call(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
const char * const methodName,
xmlrpc_value * const paramArrayP);
void
xmlrpc_serialize_response2(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP,
xmlrpc_dialect const dialect);
void
xmlrpc_serialize_response(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
xmlrpc_value * const valueP);
void
xmlrpc_serialize_fault(xmlrpc_env * const envP,
xmlrpc_mem_block * const outputP,
const xmlrpc_env * const faultP);
/*=========================================================================
** Decoding XML
**=======================================================================*/
/* Parse an XML-RPC call. If an error occurs, set a fault and set
** the output variables to NULL.
** The caller is responsible for calling free(*out_method_name) and
** xmlrpc_DECREF(*out_param_array). */
void
xmlrpc_parse_call(xmlrpc_env * const envP,
const char * const xml_data,
size_t const xml_len,
const char ** const out_method_name,
xmlrpc_value ** const out_param_array);
void
xmlrpc_parse_response2(xmlrpc_env * const envP,
const char * const xmlData,
size_t const xmlDataLen,
xmlrpc_value ** const resultPP,
int * const faultCodeP,
const char ** const faultStringP);
/* xmlrpc_parse_response() is for backward compatibility */
xmlrpc_value *
xmlrpc_parse_response(xmlrpc_env * const envP,
const char * const xmlData,
size_t const xmlDataLen);
/*=========================================================================
** XML-RPC Base64 Utilities
**=========================================================================
** Here are some lightweight utilities which can be used to encode and
** decode Base64 data. These are exported mainly for testing purposes.
*/
/* This routine inserts newlines every 76 characters, as required by the
** Base64 specification. */
xmlrpc_mem_block *
xmlrpc_base64_encode(xmlrpc_env * env,
unsigned char * bin_data,
size_t bin_len);
/* This routine encodes everything in one line. This is needed for HTTP
** authentication and similar tasks. */
xmlrpc_mem_block *
xmlrpc_base64_encode_without_newlines(xmlrpc_env * env,
unsigned char * bin_data,
size_t bin_len);
/* This decodes Base64 data with or without newlines. */
extern xmlrpc_mem_block *
xmlrpc_base64_decode(xmlrpc_env * const envP,
const char * const ascii_data,
size_t const ascii_len);
/*=========================================================================
** Authorization Cookie Handling
**=========================================================================
** Routines to get and set values for authorizing via authorization
** cookies. Both the client and server use HTTP_COOKIE_AUTH to store
** the representation of the authorization value, which is actually
** just a base64 hash of username:password. (This entire method is
** a cookie replacement of basic authentication.)
**/
extern void xmlrpc_authcookie_set(xmlrpc_env * const env,
const char * const username,
const char * const password);
char *xmlrpc_authcookie(void);
/*=========================================================================
Resource Limits
Ideally, there would be enough resource limits to ensure that
XML-RPC partners cannot cause libxmlrpc objects and routines to use
more resource than is available for them (either by accident or
malice). We have a long way to go to get there.
=========================================================================*/
/* These functions are _not_ re-entrant and the limits are per-process
(i.e. their values live in static global variables).
*/
/* Limit IDs. There will be more of these as time goes on. */
#define XMLRPC_NESTING_LIMIT_ID (0)
#define XMLRPC_XML_SIZE_LIMIT_ID (1)
#define XMLRPC_LAST_LIMIT_ID (XMLRPC_XML_SIZE_LIMIT_ID)
/* By default, deserialized data may be no more than 64 levels deep. */
#define XMLRPC_NESTING_LIMIT_DEFAULT (64)
/* By default, XML data from the network may be no larger than 512K.
** Some client and server modules may fail to enforce this properly. */
#define XMLRPC_XML_SIZE_LIMIT_DEFAULT (512*1024)
/* Set a specific limit to the specified value. */
extern void xmlrpc_limit_set (int const limit_id, size_t const value);
/* Get the value of a specified limit. */
extern size_t xmlrpc_limit_get (int const limit_id);
#ifdef __cplusplus
}
#endif
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#endif

View File

@ -0,0 +1,198 @@
/*============================================================================
base_int.h
==============================================================================
This header file defines the interface between modules inside
xmlrpc-c.
Use this in addition to xmlrpc.h, which defines the external
interface.
Copyright information is at the end of the file.
============================================================================*/
#ifndef XMLRPC_C_BASE_INT_H_INCLUDED
#define XMLRPC_C_BASE_INT_H_INCLUDED
#include "xmlrpc_config.h"
#include "bool.h"
#include "int.h"
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/util_int.h>
#ifdef __cplusplus
extern "C" {
#endif
struct _xmlrpc_value {
xmlrpc_type _type;
int _refcount;
/* Certain data types store their data directly in the xmlrpc_value. */
union {
xmlrpc_int32 i;
xmlrpc_int64 i8;
xmlrpc_bool b;
double d;
/* time_t t */
void * c_ptr;
} _value;
/* Other data types use a memory block.
For a string, this is the characters of the lines of the string
in UTF-8, with lines delimited by either CR, LF, or CRLF, plus
a NUL added to the end. The characters of the lines may be any
character representable in UTF-8, even the ones that are not
legal XML (XML doesn't allow ASCII control characters except
tab, CR, LF). But note that a line can't contain CR or LF
because that would form a line delimiter. To disambiguate:
CRLF together is always one line delimiter.
This format for string is quite convenient because it is also
the format of that part of an XML document which is the
contents of a <string> element (except of course that for the
non-XML characters, we have to stretch the definition of XML).
For base64, this is bytes of the byte string, directly.
For datetime, this is in the same format as the contents of
a <dateTime.iso8601> XML element. That really ought to be changed
to time_t some day.
*/
xmlrpc_mem_block _block;
xmlrpc_mem_block *_wcs_block;
/* This is a copy of the string value in _block, but in UTF-16
instead of UTF-8. This member is not always present. If NULL,
it is not present.
We keep this copy for convenience. The value is totally
redundant with _block.
This member is always NULL when the data type is not string.
This member is always NULL on a system that does not have
Unicode wchar functions.
*/
};
#define XMLRPC_ASSERT_VALUE_OK(val) \
XMLRPC_ASSERT((val) != NULL && (val)->_type != XMLRPC_TYPE_DEAD)
/* A handy type-checking routine. */
#define XMLRPC_TYPE_CHECK(env,v,t) \
do \
if ((v)->_type != (t)) \
XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Expected " #t); \
while (0)
typedef struct {
uint32_t keyHash;
xmlrpc_value * key;
xmlrpc_value * value;
} _struct_member;
void
xmlrpc_createXmlrpcValue(xmlrpc_env * const envP,
xmlrpc_value ** const valPP);
const char *
xmlrpc_typeName(xmlrpc_type const type);
void
xmlrpc_traceXml(const char * const label,
const char * const xml,
unsigned int const xmlLength);
void
xmlrpc_destroyString(xmlrpc_value * const stringP);
void
xmlrpc_destroyStruct(xmlrpc_value * const structP);
void
xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP);
/*----------------------------------------------------------------------------
The following are for use by the legacy xmlrpc_parse_value(). They don't
do proper memory management, so they aren't appropriate for general use,
but there are old users that do xmlrpc_parse_value() and compensate for
the memory management, so we have to continue to offer this style of
memory management.
In particular, the functions that return xmlrpc_values don't increment
the reference count, and the functions that return strings don't allocate
new memory for them.
-----------------------------------------------------------------------------*/
void
xmlrpc_read_datetime_str_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_lp_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const char ** const stringValueP);
#if XMLRPC_HAVE_WCHAR
void
xmlrpc_read_string_w_old(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_lp_old(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
#endif
void
xmlrpc_read_base64_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const unsigned char ** const byteStringValueP);
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,20 @@
#ifndef XMLRPC_C_C_UTIL_H_INCLUDED
#define XMLRPC_C_C_UTIL_H_INCLUDED
/* C language stuff. Doesn't involve any libraries that aren't part of
the compiler.
*/
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
/* GNU_PRINTF_ATTR lets the GNU compiler check printf-type
calls to be sure the arguments match the format string, thus preventing
runtime segmentation faults and incorrect messages.
*/
#ifdef __GNUC__
#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
#else
#define GNU_PRINTF_ATTR(a,b)
#endif
#endif

View File

@ -0,0 +1,316 @@
/*============================================================================
xmlrpc_client.h
==============================================================================
This header file defines the interface between xmlrpc.c and its users,
related to clients.
Copyright information is at the end of the file.
============================================================================*/
#ifndef XMLRPC_CLIENT_H_INCLUDED
#define XMLRPC_CLIENT_H_INCLUDED
#include <xmlrpc-c/base.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct xmlrpc_client;
struct xmlrpc_client_transport;
struct xmlrpc_client_transport_ops;
#ifndef __cplusplus
typedef struct xmlrpc_client xmlrpc_client;
typedef struct xmlrpc_client_transport xmlrpc_client_transport;
typedef struct xmlrpc_client_transport_ops xmlrpc_client_transport_ops;
#endif
/* libxmlrpc_client typically does _not_ actually include all of the
XML transports declared here by xmlrpc_*_transport_ops.
Use 'xmlrpc-c-config --features' to determine which features are
installed.
*/
/* Before Xmlrpc-c 1.13 (December 2007), we declared struct
xmlrpc_xportparms, as a sort of "base class." The struct was never
complete -- you just cast pointer to it it to pointers to other
types. It turned out not to be really helpful and casts are ugly,
so now we just use void * as a base class pointer.
*/
extern struct xmlrpc_client_transport_ops xmlrpc_libwww_transport_ops;
extern struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops;
extern struct xmlrpc_client_transport_ops xmlrpc_curl_transport_ops;
enum xmlrpc_sslversion {
XMLRPC_SSLVERSION_DEFAULT,
XMLRPC_SSLVERSION_TLSv1,
XMLRPC_SSLVERSION_SSLv2,
XMLRPC_SSLVERSION_SSLv3
};
struct xmlrpc_curl_xportparms {
/* This is designed so that zero values are always the defaults. */
const char * network_interface;
xmlrpc_bool no_ssl_verifypeer;
xmlrpc_bool no_ssl_verifyhost;
const char * user_agent;
const char * ssl_cert;
const char * sslcerttype;
const char * sslcertpasswd;
const char * sslkey;
const char * sslkeytype;
const char * sslkeypasswd;
const char * sslengine;
xmlrpc_bool sslengine_default;
enum xmlrpc_sslversion sslversion;
const char * cainfo;
const char * capath;
const char * randomfile;
const char * egdsocket;
const char * ssl_cipher_list;
unsigned int timeout;
};
#define XMLRPC_CXPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_curl_xportparms, mbrname)
/* XMLRPC_CXPSIZE(xyz) is analogous to XMLRPC_CPSIZE, below */
struct xmlrpc_wininet_xportparms {
int allowInvalidSSLCerts;
};
#define XMLRPC_WXPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_wininet_xportparms, mbrname)
/* XMLRPC_WXPSIZE(xyz) is analogous to XMLRPC_CPSIZE, below */
struct xmlrpc_clientparms {
/* (transport, transportparmsP, transportparm_size) and
(transportOpsP, transportP) are mutually exclusive.
*/
const char * transport;
const void * transportparmsP;
/* This should be type "const struct ..._xportparms *" */
size_t transportparm_size;
const struct xmlrpc_client_transport_ops * transportOpsP;
xmlrpc_client_transport * transportP;
xmlrpc_dialect dialect;
};
#define XMLRPC_CPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_clientparms, mbrname)
/* XMLRPC_CPSIZE(xyz) is the minimum size a struct xmlrpc_clientparms
must be to include the 'xyz' member. This is essential to forward and
backward compatbility, as new members will be added to the end of the
struct in future releases. This is how the callee knows whether or
not the caller is new enough to have supplied a certain parameter.
*/
const char *
xmlrpc_client_get_default_transport(xmlrpc_env * const env);
/* A callback function to handle the response to an asynchronous call.
** If 'fault->fault_occurred' is true, then response will be NULL. All
** arguments except 'user_data' will be deallocated internally; please do
** not free any of them yourself.
** WARNING: param_array may (or may not) be NULL if fault->fault_occurred
** is true, and you set up the call using xmlrpc_client_call_asynch.
** WARNING: If asynchronous calls are still pending when the library is
** shut down, your handler may (or may not) be called with a fault. */
typedef void (*xmlrpc_response_handler) (const char *server_url,
const char *method_name,
xmlrpc_value *param_array,
void *user_data,
xmlrpc_env *fault,
xmlrpc_value *result);
/*=========================================================================
xmlrpc_server_info
===========================================================================
We normally refer to servers by URL. But sometimes we need to do extra
setup for particular servers. In that case, we can create an
xmlrpc_server_info object, configure it in various ways, and call the
remote server.
(This interface is also designed to discourage further multiplication
of xmlrpc_client_call APIs. We have enough of those already. Please
add future options and flags using xmlrpc_server_info.)
=========================================================================*/
typedef struct _xmlrpc_server_info xmlrpc_server_info;
/* Create a new server info record, pointing to the specified server. */
xmlrpc_server_info *
xmlrpc_server_info_new(xmlrpc_env * const envP,
const char * const serverUrl);
/* Create a new server info record, with a copy of the old server. */
extern xmlrpc_server_info *
xmlrpc_server_info_copy(xmlrpc_env * const envP,
xmlrpc_server_info * const srcP);
void
xmlrpc_server_info_free(xmlrpc_server_info * const serverP);
void
xmlrpc_server_info_set_user(xmlrpc_env * const envP,
xmlrpc_server_info * const serverInfoP,
const char * const username,
const char * const password);
void
xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP,
xmlrpc_server_info * const serverP,
const char * const username,
const char * const password);
void
xmlrpc_server_info_allow_auth_basic(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_disallow_auth_basic(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_allow_auth_digest(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_disallow_auth_digest(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_allow_auth_negotiate(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_disallow_auth_negotiate(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_allow_auth_ntlm(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
void
xmlrpc_server_info_disallow_auth_ntlm(xmlrpc_env * const envP,
xmlrpc_server_info * const sP);
extern unsigned int const xmlrpc_client_version_major;
extern unsigned int const xmlrpc_client_version_minor;
extern unsigned int const xmlrpc_client_version_point;
void
xmlrpc_client_setup_global_const(xmlrpc_env * const envP);
void
xmlrpc_client_teardown_global_const(void);
void
xmlrpc_client_create(xmlrpc_env * const envP,
int const flags,
const char * const appname,
const char * const appversion,
const struct xmlrpc_clientparms * const clientparmsP,
unsigned int const parmSize,
xmlrpc_client ** const clientPP);
void
xmlrpc_client_destroy(xmlrpc_client * const clientP);
void
xmlrpc_client_transport_call2(
xmlrpc_env * const envP,
xmlrpc_client * const clientP,
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block ** const respXmlPP);
void
xmlrpc_client_call2(xmlrpc_env * const envP,
struct xmlrpc_client * const clientP,
const xmlrpc_server_info * const serverInfoP,
const char * const methodName,
xmlrpc_value * const paramArrayP,
xmlrpc_value ** const resultPP);
void
xmlrpc_client_call2f(xmlrpc_env * const envP,
xmlrpc_client * const clientP,
const char * const serverUrl,
const char * const methodName,
xmlrpc_value ** const resultPP,
const char * const format,
...);
void
xmlrpc_client_event_loop_finish(xmlrpc_client * const clientP);
void
xmlrpc_client_event_loop_finish_timeout(xmlrpc_client * const clientP,
unsigned long const milliseconds);
void
xmlrpc_client_start_rpc(xmlrpc_env * const envP,
struct xmlrpc_client * const clientP,
xmlrpc_server_info * const serverInfoP,
const char * const methodName,
xmlrpc_value * const argP,
xmlrpc_response_handler responseHandler,
void * const userData);
void
xmlrpc_client_start_rpcf(xmlrpc_env * const envP,
xmlrpc_client * const clientP,
const char * const serverUrl,
const char * const methodName,
xmlrpc_response_handler callback,
void * const userData,
const char * const format,
...);
void
xmlrpc_client_set_interrupt(xmlrpc_client * const clientP,
int * const interruptP);
#include <xmlrpc-c/client_global.h>
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _XMLRPC_CLIENT_H_ */

View File

@ -0,0 +1,141 @@
#ifndef CLIENT_GLOBAL_H_INCLUDED
#define CLIENT_GLOBAL_H_INCLUDED
/*=========================================================================
** Initialization and Shutdown
**=========================================================================
** These routines initialize and terminate the XML-RPC client. If you're
** already using libwww on your own, you can pass
** XMLRPC_CLIENT_SKIP_LIBWWW_INIT to avoid initializing it twice.
*/
#define XMLRPC_CLIENT_NO_FLAGS (0)
#define XMLRPC_CLIENT_SKIP_LIBWWW_INIT (1)
extern void
xmlrpc_client_init(int const flags,
const char * const appname,
const char * const appversion);
void
xmlrpc_client_init2(xmlrpc_env * const env,
int const flags,
const char * const appname,
const char * const appversion,
const struct xmlrpc_clientparms * const clientparms,
unsigned int const parm_size);
extern void
xmlrpc_client_cleanup(void);
/*=========================================================================
** xmlrpc_client_call
**=========================================================================
** A synchronous XML-RPC client. Do not attempt to call any of these
** functions from inside an asynchronous callback!
*/
xmlrpc_value *
xmlrpc_client_call(xmlrpc_env * const envP,
const char * const server_url,
const char * const method_name,
const char * const format,
...);
xmlrpc_value *
xmlrpc_client_call_params(xmlrpc_env * const envP,
const char * const serverUrl,
const char * const methodName,
xmlrpc_value * const paramArrayP);
xmlrpc_value *
xmlrpc_client_call_server(xmlrpc_env * const envP,
const xmlrpc_server_info * const server,
const char * const method_name,
const char * const format,
...);
xmlrpc_value *
xmlrpc_client_call_server_params(
xmlrpc_env * const envP,
const xmlrpc_server_info * const serverP,
const char * const method_name,
xmlrpc_value * const paramArrayP);
void
xmlrpc_client_transport_call(
xmlrpc_env * const envP,
void * const reserved, /* for client handle */
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block ** const respXmlPP);
/*=========================================================================
** xmlrpc_client_call_asynch
**=========================================================================
** An asynchronous XML-RPC client.
*/
/* Make an asynchronous XML-RPC call. We make internal copies of all
** arguments except user_data, so you can deallocate them safely as soon
** as you return. Errors will be passed to the callback. You will need
** to run the event loop somehow; see below.
** WARNING: If an error occurs while building the argument, the
** response handler will be called with a NULL param_array. */
void
xmlrpc_client_call_asynch(const char * const server_url,
const char * const method_name,
xmlrpc_response_handler callback,
void * const user_data,
const char * const format,
...);
/* As above, but use an xmlrpc_server_info object. The server object can be
** safely destroyed as soon as this function returns. */
void
xmlrpc_client_call_server_asynch(xmlrpc_server_info * const server,
const char * const method_name,
xmlrpc_response_handler callback,
void * const user_data,
const char * const format,
...);
/* As above, but the parameter list is supplied as an xmlrpc_value
** containing an array.
*/
void
xmlrpc_client_call_asynch_params(const char * const server_url,
const char * const method_name,
xmlrpc_response_handler callback,
void * const user_data,
xmlrpc_value * const paramArrayP);
/* As above, but use an xmlrpc_server_info object. The server object can be
** safely destroyed as soon as this function returns. */
void
xmlrpc_client_call_server_asynch_params(
xmlrpc_server_info * const server,
const char * const method_name,
xmlrpc_response_handler callback,
void * const user_data,
xmlrpc_value * const paramArrayP);
/*=========================================================================
** Event Loop Interface
**=========================================================================
** These functions can be used to run the XML-RPC event loop. If you
** don't like these, you can also run the libwww event loop directly.
*/
/* Finish all outstanding asynchronous calls. Alternatively, the loop
** will exit if someone calls xmlrpc_client_event_loop_end. */
extern void
xmlrpc_client_event_loop_finish_asynch(void);
/* Finish all outstanding asynchronous calls. */
extern void
xmlrpc_client_event_loop_finish_asynch_timeout(unsigned long const milliseconds);
#endif

View File

@ -0,0 +1,121 @@
/*============================================================================
xmlrpc_client_int.h
==============================================================================
This header file defines the interface between client modules inside
xmlrpc-c.
Use this in addition to xmlrpc_client.h, which defines the external
interface.
Copyright information is at the end of the file.
============================================================================*/
#ifndef XMLRPC_CLIENT_INT_H_INCLUDED
#define XMLRPC_CLIENT_INT_H_INCLUDED
#include "xmlrpc-c/util.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _xmlrpc_server_info {
const char * serverUrl;
struct {
bool basic;
bool digest;
bool gssnegotiate;
bool ntlm;
} allowedAuth;
const char * userNamePw;
/* The username/password value for HTTP, i.e. in
"user:password" form
This can be NULL to indicate "none", but only if 'allowedAuth'
doesn't allow any form of authentication.
*/
const char * basicAuthHdrValue;
/* A complete value for an HTTP Authorization: header that
requests HTTP basic authentication. This exists whether
or not 'allowedAuth' allows basic authentication, and is
completely redundant with 'userNamePw'. It exists mainly
for historical reasons, and may also save some computation
when the same xmrpc_server_info is used for multiple
HTTP connections.
This is NULL exactly when 'userNamePw' is NULL.
*/
};
/*=========================================================================
** Transport Implementation functions.
**========================================================================= */
#include "xmlrpc-c/transport.h"
/* The generalized event loop. This uses the above flags. For more details,
** see the wrapper functions below. If you're not using the timeout, the
** 'milliseconds' parameter will be ignored.
** Note that ANY event loop call will return immediately if there are
** no outstanding XML-RPC calls. */
extern void
xmlrpc_client_event_loop_run_general (int flags, xmlrpc_timeout milliseconds);
/* Run the event loop forever. The loop will exit if someone calls
** xmlrpc_client_event_loop_end. */
extern void
xmlrpc_client_event_loop_run (void);
/* Run the event loop forever. The loop will exit if someone calls
** xmlrpc_client_event_loop_end or the timeout expires.
** (Note that ANY event loop call will return immediately if there are
** no outstanding XML-RPC calls.) */
extern void
xmlrpc_client_event_loop_run_timeout (xmlrpc_timeout milliseconds);
/* End the running event loop immediately. This can also be accomplished
** by calling the corresponding function in libwww.
** (Note that ANY event loop call will return immediately if there are
** no outstanding XML-RPC calls.) */
extern void
xmlrpc_client_event_loop_end (void);
/* Return true if there are uncompleted asynchronous calls.
** The exact value of this during a response callback is undefined. */
extern int
xmlrpc_client_asynch_calls_are_unfinished (void);
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,37 @@
#ifndef XMLRPC_C_CONFIG_H_INCLUDED
#define XMLRPC_C_CONFIG_H_INCLUDED
/* This file, part of XML-RPC For C/C++, is meant to
define characteristics of this particular installation
that the other <xmlrpc-c/...> header files need in
order to compile correctly when #included in Xmlrpc-c
user code.
Those header files #include this one.
This file was created by a make rule.
*/
#define XMLRPC_HAVE_WCHAR 1
#ifdef WIN32
/* SOCKET is a type defined by <winsock.h>. Anyone who
uses XMLRPC_SOCKET on a WIN32 system must #include
<winsock.h>
*/
#define XMLRPC_SOCKET SOCKET
#define XMLRPC_HAVE_TIMEVAL 0
#define XMLRPC_HAVE_TIMESPEC 0
#else
#define XMLRPC_SOCKET int
#define XMLRPC_HAVE_TIMEVAL 1
#define XMLRPC_HAVE_TIMESPEC 1
#endif
#if defined(_MSC_VER)
/* Newer MSVC has long long, but MSVC 6 does not */
#define XMLRPC_INT64 __int64
#define XMLRPC_INT32 __int32
#else
#define XMLRPC_INT64 long long
#define XMLRPC_INT32 int
#endif
#endif

View File

@ -0,0 +1,19 @@
#ifndef XMLRPC_INTTYPES_H_INCLUDED
#define XMLRPC_INTTYPES_H_INCLUDED
#ifdef _MSC_VER
typedef unsigned short xmlrpc_uint16_t;
typedef unsigned int xmlrpc_uint32_t;
typedef unsigned __int64 xmlrpc_uint64_t;
#else
#include <inttypes.h>
typedef uint16_t xmlrpc_uint16_t;
typedef uint32_t xmlrpc_uint32_t;
typedef uint64_t xmlrpc_uint64_t;
#endif
#endif

View File

@ -0,0 +1,2 @@
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/server.h>

View File

@ -0,0 +1,24 @@
#ifndef SELECT_INT_H_INCLUDED
#define SELECT_INT_H_INCLUDED
#ifndef WIN32
#include <sys/select.h>
#endif
#include <signal.h>
#include "xmlrpc-c/time_int.h"
#ifdef WIN32
#ifndef sigset_t
typedef int sigset_t;
#endif
#endif
int
xmlrpc_pselect(int const n,
fd_set * const readfdsP,
fd_set * const writefdsP,
fd_set * const exceptfdsP,
const xmlrpc_timespec * const timeoutP,
sigset_t * const sigmaskP);
#endif

View File

@ -0,0 +1,173 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_SERVER_H_INCLUDED
#define XMLRPC_SERVER_H_INCLUDED
#include <xmlrpc-c/base.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct xmlrpc_registry xmlrpc_registry;
typedef void
(*xmlrpc_preinvoke_method)(xmlrpc_env * const envP,
const char * const methodName,
xmlrpc_value * const paramArrayP,
void * const userData);
typedef xmlrpc_value *
(*xmlrpc_method1)(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
void * const serverInfo);
typedef xmlrpc_value *
(*xmlrpc_method2)(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
void * const serverInfo,
void * const callInfo);
typedef xmlrpc_method1 xmlrpc_method; /* backward compatibility */
typedef xmlrpc_value *
(*xmlrpc_default_method)(xmlrpc_env * const envP,
const char * const callInfoP,
const char * const methodName,
xmlrpc_value * const paramArrayP,
void * const serverInfo);
extern unsigned int const xmlrpc_server_version_major;
extern unsigned int const xmlrpc_server_version_minor;
extern unsigned int const xmlrpc_server_version_point;
xmlrpc_registry *
xmlrpc_registry_new(xmlrpc_env * const envP);
void
xmlrpc_registry_free(xmlrpc_registry * const registryP);
void
xmlrpc_registry_disable_introspection(xmlrpc_registry * const registryP);
void
xmlrpc_registry_add_method(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const char * const host,
const char * const methodName,
xmlrpc_method const method,
void * const serverInfo);
void
xmlrpc_registry_add_method_w_doc(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const char * const host,
const char * const methodName,
xmlrpc_method const method,
void * const serverInfo,
const char * const signatureString,
const char * const help);
void
xmlrpc_registry_add_method2(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const char * const methodName,
xmlrpc_method2 method,
const char * const signatureString,
const char * const help,
void * const serverInfo);
struct xmlrpc_method_info3 {
const char * methodName;
xmlrpc_method2 methodFunction;
void * serverInfo;
size_t stackSize;
const char * signatureString;
const char * help;
};
void
xmlrpc_registry_add_method3(
xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const struct xmlrpc_method_info3 * const infoP);
void
xmlrpc_registry_set_default_method(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
xmlrpc_default_method const handler,
void * const userData);
void
xmlrpc_registry_set_preinvoke_method(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
xmlrpc_preinvoke_method const method,
void * const userData);
typedef void xmlrpc_server_shutdown_fn(xmlrpc_env * const envP,
void * const context,
const char * const comment,
void * const callInfo);
void
xmlrpc_registry_set_shutdown(xmlrpc_registry * const registryP,
xmlrpc_server_shutdown_fn * const shutdownFn,
void * const context);
void
xmlrpc_registry_set_dialect(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
xmlrpc_dialect const dialect);
/*----------------------------------------------------------------------------
Lower interface -- services to be used by an HTTP request handler
-----------------------------------------------------------------------------*/
void
xmlrpc_registry_process_call2(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const char * const xmlData,
size_t const xmlLen,
void * const callInfo,
xmlrpc_mem_block ** const outputPP);
xmlrpc_mem_block *
xmlrpc_registry_process_call(xmlrpc_env * const envP,
xmlrpc_registry * const registryP,
const char * const host,
const char * const xmlData,
size_t const xmlLen);
size_t
xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP);
#ifdef __cplusplus
}
#endif
/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE. */
#endif

Some files were not shown because too many files have changed in this diff Show More