author | erik <erik> | 2007-01-24 19:46:19 (UTC) |
---|---|---|
committer | erik <erik> | 2007-01-24 19:46:19 (UTC) |
commit | a017bf21dd89159052f2f7a3fbc043a24956c08c (patch) (unidiff) | |
tree | 008be2b62ee5487dc55b8a7c7f043c94268f8362 | |
parent | a4a7bd22feb060a80e20c81cded43cc24f5cd423 (diff) | |
download | opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.zip opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.tar.gz opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.tar.bz2 |
Every file in this commit has a memory leak of some kind or another. I think
all of them are minor and should not effect properly running code. But if I
were you I would give libstocks and the stockticker plugin in Today a wide
berth. That library is atrocious.
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/libmpeg3.c | 2 | ||||
-rw-r--r-- | libopie2/opieui/oimageeffect.cpp | 5 | ||||
-rw-r--r-- | library/global.cpp | 30 | ||||
-rw-r--r-- | noncore/apps/opie-reader/Bkmks.cpp | 1 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/Excel.cpp | 4 | ||||
-rw-r--r-- | noncore/apps/zsafe/zsafe.cpp | 57 | ||||
-rw-r--r-- | noncore/comm/keypebble/vncauth.c | 6 | ||||
-rw-r--r-- | noncore/net/ftplib/ftplib.c | 4 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/csv.c | 140 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/currency.c | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/lists.h | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/stocks.c | 189 | ||||
-rw-r--r-- | rsync/delta.c | 2 |
13 files changed, 270 insertions, 172 deletions
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c index acaecf7..c8cd3e2 100644 --- a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c +++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c | |||
@@ -1,430 +1,430 @@ | |||
1 | #include "libmpeg3.h" | 1 | #include "libmpeg3.h" |
2 | #include "mpeg3protos.h" | 2 | #include "mpeg3protos.h" |
3 | 3 | ||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <string.h> | 5 | #include <string.h> |
6 | 6 | ||
7 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 7 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
8 | 8 | ||
9 | mpeg3_t* mpeg3_new(char *path) | 9 | mpeg3_t* mpeg3_new(char *path) |
10 | { | 10 | { |
11 | int i; | 11 | int i; |
12 | mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t)); | 12 | mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t)); |
13 | file->cpus = 1; | 13 | file->cpus = 1; |
14 | file->fs = mpeg3_new_fs(path); | 14 | file->fs = mpeg3_new_fs(path); |
15 | file->have_mmx = mpeg3_mmx_test(); | 15 | file->have_mmx = mpeg3_mmx_test(); |
16 | file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); | 16 | file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); |
17 | return file; | 17 | return file; |
18 | } | 18 | } |
19 | 19 | ||
20 | int mpeg3_delete(mpeg3_t *file) | 20 | int mpeg3_delete(mpeg3_t *file) |
21 | { | 21 | { |
22 | int i; | 22 | int i; |
23 | 23 | ||
24 | for(i = 0; i < file->total_vstreams; i++) | 24 | for(i = 0; i < file->total_vstreams; i++) |
25 | mpeg3_delete_vtrack(file, file->vtrack[i]); | 25 | mpeg3_delete_vtrack(file, file->vtrack[i]); |
26 | 26 | ||
27 | for(i = 0; i < file->total_astreams; i++) | 27 | for(i = 0; i < file->total_astreams; i++) |
28 | mpeg3_delete_atrack(file, file->atrack[i]); | 28 | mpeg3_delete_atrack(file, file->atrack[i]); |
29 | 29 | ||
30 | mpeg3_delete_fs(file->fs); | 30 | mpeg3_delete_fs(file->fs); |
31 | mpeg3_delete_demuxer(file->demuxer); | 31 | mpeg3_delete_demuxer(file->demuxer); |
32 | free(file); | 32 | free(file); |
33 | } | 33 | } |
34 | 34 | ||
35 | int mpeg3_check_sig(char *path) | 35 | int mpeg3_check_sig(char *path) |
36 | { | 36 | { |
37 | mpeg3_fs_t *fs; | 37 | mpeg3_fs_t *fs; |
38 | unsigned int bits; | 38 | unsigned int bits; |
39 | char *ext; | 39 | char *ext; |
40 | int result = 0; | 40 | int result = 0; |
41 | 41 | ||
42 | fs = mpeg3_new_fs(path); | 42 | fs = mpeg3_new_fs(path); |
43 | if(mpeg3io_open_file(fs)) | 43 | if(mpeg3io_open_file(fs)) |
44 | { | 44 | { |
45 | /* File not found */ | 45 | /* File not found */ |
46 | return 0; | 46 | return mpeg3_delete_fs(fs); |
47 | } | 47 | } |
48 | 48 | ||
49 | bits = mpeg3io_read_int32(fs); | 49 | bits = mpeg3io_read_int32(fs); |
50 | /* Test header */ | 50 | /* Test header */ |
51 | if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) | 51 | if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) |
52 | { | 52 | { |
53 | result = 1; | 53 | result = 1; |
54 | } | 54 | } |
55 | else | 55 | else |
56 | if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || | 56 | if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || |
57 | (bits == MPEG3_PACK_START_CODE) || | 57 | (bits == MPEG3_PACK_START_CODE) || |
58 | ((bits & 0xfff00000) == 0xfff00000) || | 58 | ((bits & 0xfff00000) == 0xfff00000) || |
59 | (bits == MPEG3_SEQUENCE_START_CODE) || | 59 | (bits == MPEG3_SEQUENCE_START_CODE) || |
60 | (bits == MPEG3_PICTURE_START_CODE) || | 60 | (bits == MPEG3_PICTURE_START_CODE) || |
61 | (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || | 61 | (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || |
62 | ((bits >> 8) == MPEG3_ID3_PREFIX) || | 62 | ((bits >> 8) == MPEG3_ID3_PREFIX) || |
63 | (bits == MPEG3_RIFF_CODE)) | 63 | (bits == MPEG3_RIFF_CODE)) |
64 | { | 64 | { |
65 | result = 1; | 65 | result = 1; |
66 | 66 | ||
67 | ext = strrchr(path, '.'); | 67 | ext = strrchr(path, '.'); |
68 | if(ext) | 68 | if(ext) |
69 | { | 69 | { |
70 | /* Test file extension. */ | 70 | /* Test file extension. */ |
71 | if(strncasecmp(ext, ".mp2", 4) && | 71 | if(strncasecmp(ext, ".mp2", 4) && |
72 | // strncasecmp(ext, ".mp3", 4) && | 72 | // strncasecmp(ext, ".mp3", 4) && |
73 | strncasecmp(ext, ".m1v", 4) && | 73 | strncasecmp(ext, ".m1v", 4) && |
74 | strncasecmp(ext, ".m2v", 4) && | 74 | strncasecmp(ext, ".m2v", 4) && |
75 | strncasecmp(ext, ".m2s", 4) && | 75 | strncasecmp(ext, ".m2s", 4) && |
76 | strncasecmp(ext, ".mpg", 4) && | 76 | strncasecmp(ext, ".mpg", 4) && |
77 | strncasecmp(ext, ".vob", 4) && | 77 | strncasecmp(ext, ".vob", 4) && |
78 | strncasecmp(ext, ".mpeg", 4) && | 78 | strncasecmp(ext, ".mpeg", 4) && |
79 | strncasecmp(ext, ".ac3", 4)) | 79 | strncasecmp(ext, ".ac3", 4)) |
80 | result = 0; | 80 | result = 0; |
81 | } | 81 | } |
82 | } | 82 | } |
83 | 83 | ||
84 | mpeg3io_close_file(fs); | 84 | mpeg3io_close_file(fs); |
85 | mpeg3_delete_fs(fs); | 85 | mpeg3_delete_fs(fs); |
86 | return result; | 86 | return result; |
87 | } | 87 | } |
88 | 88 | ||
89 | mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) | 89 | mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) |
90 | { | 90 | { |
91 | mpeg3_t *file = 0; | 91 | mpeg3_t *file = 0; |
92 | unsigned int bits; | 92 | unsigned int bits; |
93 | int i, done; | 93 | int i, done; |
94 | 94 | ||
95 | /* Initialize the file structure */ | 95 | /* Initialize the file structure */ |
96 | file = mpeg3_new(path); | 96 | file = mpeg3_new(path); |
97 | 97 | ||
98 | /* Need to perform authentication before reading a single byte. */ | 98 | /* Need to perform authentication before reading a single byte. */ |
99 | if(mpeg3io_open_file(file->fs)) | 99 | if(mpeg3io_open_file(file->fs)) |
100 | { | 100 | { |
101 | mpeg3_delete(file); | 101 | mpeg3_delete(file); |
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | /* =============================== Create the title objects ========================= */ | 105 | /* =============================== Create the title objects ========================= */ |
106 | bits = mpeg3io_read_int32(file->fs); | 106 | bits = mpeg3io_read_int32(file->fs); |
107 | 107 | ||
108 | if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */ | 108 | if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */ |
109 | { | 109 | { |
110 | /* Table of contents for another file */ | 110 | /* Table of contents for another file */ |
111 | if(mpeg3_read_toc(file)) | 111 | if(mpeg3_read_toc(file)) |
112 | { | 112 | { |
113 | mpeg3_delete(file); | 113 | mpeg3_delete(file); |
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | mpeg3io_close_file(file->fs); | 116 | mpeg3io_close_file(file->fs); |
117 | } | 117 | } |
118 | else | 118 | else |
119 | if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) | 119 | if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) |
120 | { | 120 | { |
121 | /* Transport stream */ | 121 | /* Transport stream */ |
122 | file->packet_size = MPEG3_TS_PACKET_SIZE; | 122 | file->packet_size = MPEG3_TS_PACKET_SIZE; |
123 | file->is_transport_stream = 1; | 123 | file->is_transport_stream = 1; |
124 | } | 124 | } |
125 | else | 125 | else |
126 | if(bits == MPEG3_PACK_START_CODE) | 126 | if(bits == MPEG3_PACK_START_CODE) |
127 | { | 127 | { |
128 | /* Program stream */ | 128 | /* Program stream */ |
129 | file->packet_size = MPEG3_DVD_PACKET_SIZE; | 129 | file->packet_size = MPEG3_DVD_PACKET_SIZE; |
130 | file->is_program_stream = 1; | 130 | file->is_program_stream = 1; |
131 | } | 131 | } |
132 | else | 132 | else |
133 | if((bits & 0xfff00000) == 0xfff00000 || | 133 | if((bits & 0xfff00000) == 0xfff00000 || |
134 | ((bits >> 8) == MPEG3_ID3_PREFIX) || | 134 | ((bits >> 8) == MPEG3_ID3_PREFIX) || |
135 | (bits == MPEG3_RIFF_CODE)) | 135 | (bits == MPEG3_RIFF_CODE)) |
136 | { | 136 | { |
137 | /* MPEG Audio only */ | 137 | /* MPEG Audio only */ |
138 | file->packet_size = MPEG3_DVD_PACKET_SIZE; | 138 | file->packet_size = MPEG3_DVD_PACKET_SIZE; |
139 | file->has_audio = 1; | 139 | file->has_audio = 1; |
140 | file->is_audio_stream = 1; | 140 | file->is_audio_stream = 1; |
141 | } | 141 | } |
142 | else | 142 | else |
143 | if(bits == MPEG3_SEQUENCE_START_CODE || | 143 | if(bits == MPEG3_SEQUENCE_START_CODE || |
144 | bits == MPEG3_PICTURE_START_CODE) | 144 | bits == MPEG3_PICTURE_START_CODE) |
145 | { | 145 | { |
146 | /* Video only */ | 146 | /* Video only */ |
147 | file->packet_size = MPEG3_DVD_PACKET_SIZE; | 147 | file->packet_size = MPEG3_DVD_PACKET_SIZE; |
148 | file->is_video_stream = 1; | 148 | file->is_video_stream = 1; |
149 | } | 149 | } |
150 | else | 150 | else |
151 | if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) | 151 | if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) |
152 | { | 152 | { |
153 | /* AC3 Audio only */ | 153 | /* AC3 Audio only */ |
154 | file->packet_size = MPEG3_DVD_PACKET_SIZE; | 154 | file->packet_size = MPEG3_DVD_PACKET_SIZE; |
155 | file->has_audio = 1; | 155 | file->has_audio = 1; |
156 | file->is_audio_stream = 1; | 156 | file->is_audio_stream = 1; |
157 | } | 157 | } |
158 | else | 158 | else |
159 | { | 159 | { |
160 | /* file->packet_size = MPEG3_DVD_PACKET_SIZE; */ | 160 | /* file->packet_size = MPEG3_DVD_PACKET_SIZE; */ |
161 | /* file->is_audio_stream = 1; */ | 161 | /* file->is_audio_stream = 1; */ |
162 | mpeg3_delete(file); | 162 | mpeg3_delete(file); |
163 | fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n"); | 163 | fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n"); |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | /* Create title */ | 167 | /* Create title */ |
168 | /* Copy timecodes from an old demuxer */ | 168 | /* Copy timecodes from an old demuxer */ |
169 | if(old_file && mpeg3_get_demuxer(old_file)) | 169 | if(old_file && mpeg3_get_demuxer(old_file)) |
170 | { | 170 | { |
171 | mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file)); | 171 | mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file)); |
172 | } | 172 | } |
173 | else | 173 | else |
174 | /* Start from scratch */ | 174 | /* Start from scratch */ |
175 | if(!file->demuxer->total_titles) | 175 | if(!file->demuxer->total_titles) |
176 | { | 176 | { |
177 | mpeg3demux_create_title(file->demuxer, 0, 0); | 177 | mpeg3demux_create_title(file->demuxer, 0, 0); |
178 | } | 178 | } |
179 | 179 | ||
180 | /* =============================== Get title information ========================= */ | 180 | /* =============================== Get title information ========================= */ |
181 | if(file->is_transport_stream || file->is_program_stream) | 181 | if(file->is_transport_stream || file->is_program_stream) |
182 | { | 182 | { |
183 | /* Create video tracks */ | 183 | /* Create video tracks */ |
184 | /* Video must be created before audio because audio uses the video timecode */ | 184 | /* Video must be created before audio because audio uses the video timecode */ |
185 | /* to get its length. */ | 185 | /* to get its length. */ |
186 | for(i = 0; i < MPEG3_MAX_STREAMS; i++) | 186 | for(i = 0; i < MPEG3_MAX_STREAMS; i++) |
187 | { | 187 | { |
188 | if(file->demuxer->vstream_table[i]) | 188 | if(file->demuxer->vstream_table[i]) |
189 | { | 189 | { |
190 | file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer); | 190 | file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer); |
191 | if(file->vtrack[file->total_vstreams]) file->total_vstreams++; | 191 | if(file->vtrack[file->total_vstreams]) file->total_vstreams++; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
195 | /* Create audio tracks */ | 195 | /* Create audio tracks */ |
196 | for(i = 0; i < MPEG3_MAX_STREAMS; i++) | 196 | for(i = 0; i < MPEG3_MAX_STREAMS; i++) |
197 | { | 197 | { |
198 | if(file->demuxer->astream_table[i]) | 198 | if(file->demuxer->astream_table[i]) |
199 | { | 199 | { |
200 | file->atrack[file->total_astreams] = mpeg3_new_atrack(file, | 200 | file->atrack[file->total_astreams] = mpeg3_new_atrack(file, |
201 | i, | 201 | i, |
202 | file->demuxer->astream_table[i], | 202 | file->demuxer->astream_table[i], |
203 | file->demuxer); | 203 | file->demuxer); |
204 | if(file->atrack[file->total_astreams]) file->total_astreams++; | 204 | if(file->atrack[file->total_astreams]) file->total_astreams++; |
205 | } | 205 | } |
206 | } | 206 | } |
207 | } | 207 | } |
208 | else | 208 | else |
209 | if(file->is_video_stream) | 209 | if(file->is_video_stream) |
210 | { | 210 | { |
211 | /* Create video tracks */ | 211 | /* Create video tracks */ |
212 | file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer); | 212 | file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer); |
213 | if(file->vtrack[0]) file->total_vstreams++; | 213 | if(file->vtrack[0]) file->total_vstreams++; |
214 | } | 214 | } |
215 | else | 215 | else |
216 | if(file->is_audio_stream) | 216 | if(file->is_audio_stream) |
217 | { | 217 | { |
218 | /* Create audio tracks */ | 218 | /* Create audio tracks */ |
219 | file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer); | 219 | file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer); |
220 | if(file->atrack[0]) file->total_astreams++; | 220 | if(file->atrack[0]) file->total_astreams++; |
221 | } | 221 | } |
222 | 222 | ||
223 | if(file->total_vstreams) file->has_video = 1; | 223 | if(file->total_vstreams) file->has_video = 1; |
224 | if(file->total_astreams) file->has_audio = 1; | 224 | if(file->total_astreams) file->has_audio = 1; |
225 | 225 | ||
226 | mpeg3io_close_file(file->fs); | 226 | mpeg3io_close_file(file->fs); |
227 | return file; | 227 | return file; |
228 | } | 228 | } |
229 | 229 | ||
230 | mpeg3_t* mpeg3_open(char *path) | 230 | mpeg3_t* mpeg3_open(char *path) |
231 | { | 231 | { |
232 | return mpeg3_open_copy(path, 0); | 232 | return mpeg3_open_copy(path, 0); |
233 | } | 233 | } |
234 | 234 | ||
235 | int mpeg3_close(mpeg3_t *file) | 235 | int mpeg3_close(mpeg3_t *file) |
236 | { | 236 | { |
237 | /* File is closed in the same procedure it is opened in. */ | 237 | /* File is closed in the same procedure it is opened in. */ |
238 | mpeg3_delete(file); | 238 | mpeg3_delete(file); |
239 | return 0; | 239 | return 0; |
240 | } | 240 | } |
241 | 241 | ||
242 | int mpeg3_set_cpus(mpeg3_t *file, int cpus) | 242 | int mpeg3_set_cpus(mpeg3_t *file, int cpus) |
243 | { | 243 | { |
244 | int i; | 244 | int i; |
245 | file->cpus = cpus; | 245 | file->cpus = cpus; |
246 | for(i = 0; i < file->total_vstreams; i++) | 246 | for(i = 0; i < file->total_vstreams; i++) |
247 | mpeg3video_set_cpus(file->vtrack[i]->video, cpus); | 247 | mpeg3video_set_cpus(file->vtrack[i]->video, cpus); |
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
250 | 250 | ||
251 | int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) | 251 | int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) |
252 | { | 252 | { |
253 | int i; | 253 | int i; |
254 | file->have_mmx = use_mmx; | 254 | file->have_mmx = use_mmx; |
255 | for(i = 0; i < file->total_vstreams; i++) | 255 | for(i = 0; i < file->total_vstreams; i++) |
256 | mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx); | 256 | mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx); |
257 | return 0; | 257 | return 0; |
258 | } | 258 | } |
259 | 259 | ||
260 | int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) | 260 | int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) |
261 | { | 261 | { |
262 | mpeg3_t *file = mpeg3_open(path); | 262 | mpeg3_t *file = mpeg3_open(path); |
263 | mpeg3_demuxer_t *demuxer; | 263 | mpeg3_demuxer_t *demuxer; |
264 | int i; | 264 | int i; |
265 | 265 | ||
266 | if(file) | 266 | if(file) |
267 | { | 267 | { |
268 | fprintf(output, "TOCVERSION 2\n" | 268 | fprintf(output, "TOCVERSION 2\n" |
269 | "PATH: %s\n", path); | 269 | "PATH: %s\n", path); |
270 | demuxer = mpeg3_new_demuxer(file, 0, 0, -1); | 270 | demuxer = mpeg3_new_demuxer(file, 0, 0, -1); |
271 | mpeg3demux_create_title(demuxer, timecode_search, output); | 271 | mpeg3demux_create_title(demuxer, timecode_search, output); |
272 | /* Just print the first title's streams */ | 272 | /* Just print the first title's streams */ |
273 | if(print_streams) mpeg3demux_print_streams(demuxer, output); | 273 | if(print_streams) mpeg3demux_print_streams(demuxer, output); |
274 | 274 | ||
275 | fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes); | 275 | fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes); |
276 | fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size); | 276 | fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size); |
277 | 277 | ||
278 | mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output); | 278 | mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output); |
279 | 279 | ||
280 | mpeg3_delete_demuxer(demuxer); | 280 | mpeg3_delete_demuxer(demuxer); |
281 | mpeg3_close(file); | 281 | mpeg3_close(file); |
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
284 | return 1; | 284 | return 1; |
285 | } | 285 | } |
286 | 286 | ||
287 | int mpeg3_read_toc(mpeg3_t *file) | 287 | int mpeg3_read_toc(mpeg3_t *file) |
288 | { | 288 | { |
289 | char string[MPEG3_STRLEN]; | 289 | char string[MPEG3_STRLEN]; |
290 | int number1; | 290 | int number1; |
291 | 291 | ||
292 | /* Test version number */ | 292 | /* Test version number */ |
293 | file->is_program_stream = 1; | 293 | file->is_program_stream = 1; |
294 | mpeg3io_seek(file->fs, 0); | 294 | mpeg3io_seek(file->fs, 0); |
295 | fscanf(file->fs->fd, "%s %d", string, &number1); | 295 | fscanf(file->fs->fd, "%s %d", string, &number1); |
296 | if(number1 > 2 || number1 < 2) return 1; | 296 | if(number1 > 2 || number1 < 2) return 1; |
297 | 297 | ||
298 | /* Read titles */ | 298 | /* Read titles */ |
299 | mpeg3demux_read_titles(file->demuxer); | 299 | mpeg3demux_read_titles(file->demuxer); |
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | int mpeg3_has_audio(mpeg3_t *file) | 303 | int mpeg3_has_audio(mpeg3_t *file) |
304 | { | 304 | { |
305 | return file->has_audio; | 305 | return file->has_audio; |
306 | } | 306 | } |
307 | 307 | ||
308 | int mpeg3_total_astreams(mpeg3_t *file) | 308 | int mpeg3_total_astreams(mpeg3_t *file) |
309 | { | 309 | { |
310 | return file->total_astreams; | 310 | return file->total_astreams; |
311 | } | 311 | } |
312 | 312 | ||
313 | int mpeg3_audio_channels(mpeg3_t *file, | 313 | int mpeg3_audio_channels(mpeg3_t *file, |
314 | int stream) | 314 | int stream) |
315 | { | 315 | { |
316 | if(file->has_audio) | 316 | if(file->has_audio) |
317 | return file->atrack[stream]->channels; | 317 | return file->atrack[stream]->channels; |
318 | return -1; | 318 | return -1; |
319 | } | 319 | } |
320 | 320 | ||
321 | int mpeg3_sample_rate(mpeg3_t *file, | 321 | int mpeg3_sample_rate(mpeg3_t *file, |
322 | int stream) | 322 | int stream) |
323 | { | 323 | { |
324 | if(file->has_audio) | 324 | if(file->has_audio) |
325 | return file->atrack[stream]->sample_rate; | 325 | return file->atrack[stream]->sample_rate; |
326 | return -1; | 326 | return -1; |
327 | } | 327 | } |
328 | 328 | ||
329 | long mpeg3_get_sample(mpeg3_t *file, | 329 | long mpeg3_get_sample(mpeg3_t *file, |
330 | int stream) | 330 | int stream) |
331 | { | 331 | { |
332 | if(file->has_audio) | 332 | if(file->has_audio) |
333 | return file->atrack[stream]->current_position; | 333 | return file->atrack[stream]->current_position; |
334 | return -1; | 334 | return -1; |
335 | } | 335 | } |
336 | 336 | ||
337 | int mpeg3_set_sample(mpeg3_t *file, | 337 | int mpeg3_set_sample(mpeg3_t *file, |
338 | long sample, | 338 | long sample, |
339 | int stream) | 339 | int stream) |
340 | { | 340 | { |
341 | if(file->has_audio) | 341 | if(file->has_audio) |
342 | { | 342 | { |
343 | file->atrack[stream]->current_position = sample; | 343 | file->atrack[stream]->current_position = sample; |
344 | mpeg3audio_seek_sample(file->atrack[stream]->audio, sample); | 344 | mpeg3audio_seek_sample(file->atrack[stream]->audio, sample); |
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | return -1; | 347 | return -1; |
348 | } | 348 | } |
349 | 349 | ||
350 | long mpeg3_audio_samples(mpeg3_t *file, | 350 | long mpeg3_audio_samples(mpeg3_t *file, |
351 | int stream) | 351 | int stream) |
352 | { | 352 | { |
353 | if(file->has_audio) | 353 | if(file->has_audio) |
354 | return file->atrack[stream]->total_samples; | 354 | return file->atrack[stream]->total_samples; |
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | 357 | ||
358 | int mpeg3_has_video(mpeg3_t *file) | 358 | int mpeg3_has_video(mpeg3_t *file) |
359 | { | 359 | { |
360 | return file->has_video; | 360 | return file->has_video; |
361 | } | 361 | } |
362 | 362 | ||
363 | int mpeg3_total_vstreams(mpeg3_t *file) | 363 | int mpeg3_total_vstreams(mpeg3_t *file) |
364 | { | 364 | { |
365 | return file->total_vstreams; | 365 | return file->total_vstreams; |
366 | } | 366 | } |
367 | 367 | ||
368 | int mpeg3_video_width(mpeg3_t *file, | 368 | int mpeg3_video_width(mpeg3_t *file, |
369 | int stream) | 369 | int stream) |
370 | { | 370 | { |
371 | if(file->has_video) | 371 | if(file->has_video) |
372 | return file->vtrack[stream]->width; | 372 | return file->vtrack[stream]->width; |
373 | return -1; | 373 | return -1; |
374 | } | 374 | } |
375 | 375 | ||
376 | int mpeg3_video_height(mpeg3_t *file, | 376 | int mpeg3_video_height(mpeg3_t *file, |
377 | int stream) | 377 | int stream) |
378 | { | 378 | { |
379 | if(file->has_video) | 379 | if(file->has_video) |
380 | return file->vtrack[stream]->height; | 380 | return file->vtrack[stream]->height; |
381 | return -1; | 381 | return -1; |
382 | } | 382 | } |
383 | 383 | ||
384 | float mpeg3_frame_rate(mpeg3_t *file, | 384 | float mpeg3_frame_rate(mpeg3_t *file, |
385 | int stream) | 385 | int stream) |
386 | { | 386 | { |
387 | if(file->has_video) | 387 | if(file->has_video) |
388 | return file->vtrack[stream]->frame_rate; | 388 | return file->vtrack[stream]->frame_rate; |
389 | return -1; | 389 | return -1; |
390 | } | 390 | } |
391 | 391 | ||
392 | long mpeg3_video_frames(mpeg3_t *file, | 392 | long mpeg3_video_frames(mpeg3_t *file, |
393 | int stream) | 393 | int stream) |
394 | { | 394 | { |
395 | if(file->has_video) | 395 | if(file->has_video) |
396 | return file->vtrack[stream]->total_frames; | 396 | return file->vtrack[stream]->total_frames; |
397 | return -1; | 397 | return -1; |
398 | } | 398 | } |
399 | 399 | ||
400 | long mpeg3_get_frame(mpeg3_t *file, | 400 | long mpeg3_get_frame(mpeg3_t *file, |
401 | int stream) | 401 | int stream) |
402 | { | 402 | { |
403 | if(file->has_video) | 403 | if(file->has_video) |
404 | return file->vtrack[stream]->current_position; | 404 | return file->vtrack[stream]->current_position; |
405 | return -1; | 405 | return -1; |
406 | } | 406 | } |
407 | 407 | ||
408 | int mpeg3_set_frame(mpeg3_t *file, | 408 | int mpeg3_set_frame(mpeg3_t *file, |
409 | long frame, | 409 | long frame, |
410 | int stream) | 410 | int stream) |
411 | { | 411 | { |
412 | if(file->has_video) | 412 | if(file->has_video) |
413 | { | 413 | { |
414 | file->vtrack[stream]->current_position = frame; | 414 | file->vtrack[stream]->current_position = frame; |
415 | mpeg3video_seek_frame(file->vtrack[stream]->video, frame); | 415 | mpeg3video_seek_frame(file->vtrack[stream]->video, frame); |
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | return -1; | 418 | return -1; |
419 | } | 419 | } |
420 | 420 | ||
421 | int mpeg3_seek_percentage(mpeg3_t *file, double percentage) | 421 | int mpeg3_seek_percentage(mpeg3_t *file, double percentage) |
422 | { | 422 | { |
423 | int i; | 423 | int i; |
424 | for(i = 0; i < file->total_astreams; i++) | 424 | for(i = 0; i < file->total_astreams; i++) |
425 | { | 425 | { |
426 | mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage); | 426 | mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage); |
427 | } | 427 | } |
428 | 428 | ||
429 | for(i = 0; i < file->total_vstreams; i++) | 429 | for(i = 0; i < file->total_vstreams; i++) |
430 | { | 430 | { |
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp index be47eb2..93719bc 100644 --- a/libopie2/opieui/oimageeffect.cpp +++ b/libopie2/opieui/oimageeffect.cpp | |||
@@ -1670,770 +1670,773 @@ QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size) | |||
1670 | int *berr2 = berr1 + img.width(); | 1670 | int *berr2 = berr1 + img.width(); |
1671 | 1671 | ||
1672 | for ( int j = 0; j < img.height(); j++ ) | 1672 | for ( int j = 0; j < img.height(); j++ ) |
1673 | { | 1673 | { |
1674 | uint *ip = (uint * )img.scanLine( j ); | 1674 | uint *ip = (uint * )img.scanLine( j ); |
1675 | uchar *dp = dImage.scanLine( j ); | 1675 | uchar *dp = dImage.scanLine( j ); |
1676 | 1676 | ||
1677 | for ( i = 0; i < img.width(); i++ ) | 1677 | for ( i = 0; i < img.width(); i++ ) |
1678 | { | 1678 | { |
1679 | rerr1[i] = rerr2[i] + qRed( *ip ); | 1679 | rerr1[i] = rerr2[i] + qRed( *ip ); |
1680 | rerr2[i] = 0; | 1680 | rerr2[i] = 0; |
1681 | gerr1[i] = gerr2[i] + qGreen( *ip ); | 1681 | gerr1[i] = gerr2[i] + qGreen( *ip ); |
1682 | gerr2[i] = 0; | 1682 | gerr2[i] = 0; |
1683 | berr1[i] = berr2[i] + qBlue( *ip ); | 1683 | berr1[i] = berr2[i] + qBlue( *ip ); |
1684 | berr2[i] = 0; | 1684 | berr2[i] = 0; |
1685 | ip++; | 1685 | ip++; |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); | 1688 | *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); |
1689 | 1689 | ||
1690 | for ( i = 1; i < img.width()-1; i++ ) | 1690 | for ( i = 1; i < img.width()-1; i++ ) |
1691 | { | 1691 | { |
1692 | int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); | 1692 | int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); |
1693 | *dp = indx; | 1693 | *dp = indx; |
1694 | 1694 | ||
1695 | int rerr = rerr1[i]; | 1695 | int rerr = rerr1[i]; |
1696 | rerr -= palette[indx].red(); | 1696 | rerr -= palette[indx].red(); |
1697 | int gerr = gerr1[i]; | 1697 | int gerr = gerr1[i]; |
1698 | gerr -= palette[indx].green(); | 1698 | gerr -= palette[indx].green(); |
1699 | int berr = berr1[i]; | 1699 | int berr = berr1[i]; |
1700 | berr -= palette[indx].blue(); | 1700 | berr -= palette[indx].blue(); |
1701 | 1701 | ||
1702 | // diffuse red error | 1702 | // diffuse red error |
1703 | rerr1[ i+1 ] += ( rerr * 7 ) >> 4; | 1703 | rerr1[ i+1 ] += ( rerr * 7 ) >> 4; |
1704 | rerr2[ i-1 ] += ( rerr * 3 ) >> 4; | 1704 | rerr2[ i-1 ] += ( rerr * 3 ) >> 4; |
1705 | rerr2[ i ] += ( rerr * 5 ) >> 4; | 1705 | rerr2[ i ] += ( rerr * 5 ) >> 4; |
1706 | rerr2[ i+1 ] += ( rerr ) >> 4; | 1706 | rerr2[ i+1 ] += ( rerr ) >> 4; |
1707 | 1707 | ||
1708 | // diffuse green error | 1708 | // diffuse green error |
1709 | gerr1[ i+1 ] += ( gerr * 7 ) >> 4; | 1709 | gerr1[ i+1 ] += ( gerr * 7 ) >> 4; |
1710 | gerr2[ i-1 ] += ( gerr * 3 ) >> 4; | 1710 | gerr2[ i-1 ] += ( gerr * 3 ) >> 4; |
1711 | gerr2[ i ] += ( gerr * 5 ) >> 4; | 1711 | gerr2[ i ] += ( gerr * 5 ) >> 4; |
1712 | gerr2[ i+1 ] += ( gerr ) >> 4; | 1712 | gerr2[ i+1 ] += ( gerr ) >> 4; |
1713 | 1713 | ||
1714 | // diffuse red error | 1714 | // diffuse red error |
1715 | berr1[ i+1 ] += ( berr * 7 ) >> 4; | 1715 | berr1[ i+1 ] += ( berr * 7 ) >> 4; |
1716 | berr2[ i-1 ] += ( berr * 3 ) >> 4; | 1716 | berr2[ i-1 ] += ( berr * 3 ) >> 4; |
1717 | berr2[ i ] += ( berr * 5 ) >> 4; | 1717 | berr2[ i ] += ( berr * 5 ) >> 4; |
1718 | berr2[ i+1 ] += ( berr ) >> 4; | 1718 | berr2[ i+1 ] += ( berr ) >> 4; |
1719 | 1719 | ||
1720 | dp++; | 1720 | dp++; |
1721 | } | 1721 | } |
1722 | 1722 | ||
1723 | *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); | 1723 | *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); |
1724 | } | 1724 | } |
1725 | 1725 | ||
1726 | delete [] rerr1; | 1726 | delete [] rerr1; |
1727 | delete [] gerr1; | 1727 | delete [] gerr1; |
1728 | delete [] berr1; | 1728 | delete [] berr1; |
1729 | 1729 | ||
1730 | img = dImage; | 1730 | img = dImage; |
1731 | return img; | 1731 | return img; |
1732 | } | 1732 | } |
1733 | 1733 | ||
1734 | int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) | 1734 | int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) |
1735 | { | 1735 | { |
1736 | if (palette == 0) | 1736 | if (palette == 0) |
1737 | return 0; | 1737 | return 0; |
1738 | 1738 | ||
1739 | int dr = palette[0].red() - r; | 1739 | int dr = palette[0].red() - r; |
1740 | int dg = palette[0].green() - g; | 1740 | int dg = palette[0].green() - g; |
1741 | int db = palette[0].blue() - b; | 1741 | int db = palette[0].blue() - b; |
1742 | 1742 | ||
1743 | int minDist = dr*dr + dg*dg + db*db; | 1743 | int minDist = dr*dr + dg*dg + db*db; |
1744 | int nearest = 0; | 1744 | int nearest = 0; |
1745 | 1745 | ||
1746 | for (int i = 1; i < size; i++ ) | 1746 | for (int i = 1; i < size; i++ ) |
1747 | { | 1747 | { |
1748 | dr = palette[i].red() - r; | 1748 | dr = palette[i].red() - r; |
1749 | dg = palette[i].green() - g; | 1749 | dg = palette[i].green() - g; |
1750 | db = palette[i].blue() - b; | 1750 | db = palette[i].blue() - b; |
1751 | 1751 | ||
1752 | int dist = dr*dr + dg*dg + db*db; | 1752 | int dist = dr*dr + dg*dg + db*db; |
1753 | 1753 | ||
1754 | if ( dist < minDist ) | 1754 | if ( dist < minDist ) |
1755 | { | 1755 | { |
1756 | minDist = dist; | 1756 | minDist = dist; |
1757 | nearest = i; | 1757 | nearest = i; |
1758 | } | 1758 | } |
1759 | } | 1759 | } |
1760 | 1760 | ||
1761 | return nearest; | 1761 | return nearest; |
1762 | } | 1762 | } |
1763 | 1763 | ||
1764 | bool OImageEffect::blend( | 1764 | bool OImageEffect::blend( |
1765 | const QImage & upper, | 1765 | const QImage & upper, |
1766 | const QImage & lower, | 1766 | const QImage & lower, |
1767 | QImage & output | 1767 | QImage & output |
1768 | ) | 1768 | ) |
1769 | { | 1769 | { |
1770 | if ( | 1770 | if ( |
1771 | upper.width() > lower.width() || | 1771 | upper.width() > lower.width() || |
1772 | upper.height() > lower.height() || | 1772 | upper.height() > lower.height() || |
1773 | upper.depth() != 32 || | 1773 | upper.depth() != 32 || |
1774 | lower.depth() != 32 | 1774 | lower.depth() != 32 |
1775 | ) | 1775 | ) |
1776 | { | 1776 | { |
1777 | odebug << "OImageEffect::blend : Sizes not correct" << oendl; | 1777 | odebug << "OImageEffect::blend : Sizes not correct" << oendl; |
1778 | return false; | 1778 | return false; |
1779 | } | 1779 | } |
1780 | 1780 | ||
1781 | output = lower.copy(); | 1781 | output = lower.copy(); |
1782 | 1782 | ||
1783 | register uchar *i, *o; | 1783 | register uchar *i, *o; |
1784 | register int a; | 1784 | register int a; |
1785 | register int col; | 1785 | register int col; |
1786 | register int w = upper.width(); | 1786 | register int w = upper.width(); |
1787 | int row(upper.height() - 1); | 1787 | int row(upper.height() - 1); |
1788 | 1788 | ||
1789 | do { | 1789 | do { |
1790 | 1790 | ||
1791 | i = upper.scanLine(row); | 1791 | i = upper.scanLine(row); |
1792 | o = output.scanLine(row); | 1792 | o = output.scanLine(row); |
1793 | 1793 | ||
1794 | col = w << 2; | 1794 | col = w << 2; |
1795 | --col; | 1795 | --col; |
1796 | 1796 | ||
1797 | do { | 1797 | do { |
1798 | 1798 | ||
1799 | while (!(a = i[col]) && (col != 3)) { | 1799 | while (!(a = i[col]) && (col != 3)) { |
1800 | --col; --col; --col; --col; | 1800 | --col; --col; --col; --col; |
1801 | } | 1801 | } |
1802 | 1802 | ||
1803 | --col; | 1803 | --col; |
1804 | o[col] += ((i[col] - o[col]) * a) >> 8; | 1804 | o[col] += ((i[col] - o[col]) * a) >> 8; |
1805 | 1805 | ||
1806 | --col; | 1806 | --col; |
1807 | o[col] += ((i[col] - o[col]) * a) >> 8; | 1807 | o[col] += ((i[col] - o[col]) * a) >> 8; |
1808 | 1808 | ||
1809 | --col; | 1809 | --col; |
1810 | o[col] += ((i[col] - o[col]) * a) >> 8; | 1810 | o[col] += ((i[col] - o[col]) * a) >> 8; |
1811 | 1811 | ||
1812 | } while (col--); | 1812 | } while (col--); |
1813 | 1813 | ||
1814 | } while (row--); | 1814 | } while (row--); |
1815 | 1815 | ||
1816 | return true; | 1816 | return true; |
1817 | } | 1817 | } |
1818 | 1818 | ||
1819 | #if 0 | 1819 | #if 0 |
1820 | // Not yet... | 1820 | // Not yet... |
1821 | bool OImageEffect::blend( | 1821 | bool OImageEffect::blend( |
1822 | const QImage & upper, | 1822 | const QImage & upper, |
1823 | const QImage & lower, | 1823 | const QImage & lower, |
1824 | QImage & output, | 1824 | QImage & output, |
1825 | const QRect & destRect | 1825 | const QRect & destRect |
1826 | ) | 1826 | ) |
1827 | { | 1827 | { |
1828 | output = lower.copy(); | 1828 | output = lower.copy(); |
1829 | return output; | 1829 | return output; |
1830 | } | 1830 | } |
1831 | 1831 | ||
1832 | #endif | 1832 | #endif |
1833 | 1833 | ||
1834 | bool OImageEffect::blend( | 1834 | bool OImageEffect::blend( |
1835 | int &x, int &y, | 1835 | int &x, int &y, |
1836 | const QImage & upper, | 1836 | const QImage & upper, |
1837 | const QImage & lower, | 1837 | const QImage & lower, |
1838 | QImage & output | 1838 | QImage & output |
1839 | ) | 1839 | ) |
1840 | { | 1840 | { |
1841 | int cx=0, cy=0, cw=upper.width(), ch=upper.height(); | 1841 | int cx=0, cy=0, cw=upper.width(), ch=upper.height(); |
1842 | 1842 | ||
1843 | if ( upper.width() + x > lower.width() || | 1843 | if ( upper.width() + x > lower.width() || |
1844 | upper.height() + y > lower.height() || | 1844 | upper.height() + y > lower.height() || |
1845 | x < 0 || y < 0 || | 1845 | x < 0 || y < 0 || |
1846 | upper.depth() != 32 || lower.depth() != 32 ) | 1846 | upper.depth() != 32 || lower.depth() != 32 ) |
1847 | { | 1847 | { |
1848 | if ( x > lower.width() || y > lower.height() ) return false; | 1848 | if ( x > lower.width() || y > lower.height() ) return false; |
1849 | if ( upper.width()<=0 || upper.height() <= 0 ) return false; | 1849 | if ( upper.width()<=0 || upper.height() <= 0 ) return false; |
1850 | if ( lower.width()<=0 || lower.height() <= 0 ) return false; | 1850 | if ( lower.width()<=0 || lower.height() <= 0 ) return false; |
1851 | 1851 | ||
1852 | if (x<0) {cx=-x; cw+=x; x=0; }; | 1852 | if (x<0) {cx=-x; cw+=x; x=0; }; |
1853 | if (cw + x > lower.width()) { cw=lower.width()-x; }; | 1853 | if (cw + x > lower.width()) { cw=lower.width()-x; }; |
1854 | if (y<0) {cy=-y; ch+=y; y=0; }; | 1854 | if (y<0) {cy=-y; ch+=y; y=0; }; |
1855 | if (ch + y > lower.height()) { ch=lower.height()-y; }; | 1855 | if (ch + y > lower.height()) { ch=lower.height()-y; }; |
1856 | 1856 | ||
1857 | if ( cx >= upper.width() || cy >= upper.height() ) return true; | 1857 | if ( cx >= upper.width() || cy >= upper.height() ) return true; |
1858 | if ( cw <= 0 || ch <= 0 ) return true; | 1858 | if ( cw <= 0 || ch <= 0 ) return true; |
1859 | } | 1859 | } |
1860 | 1860 | ||
1861 | output.create(cw,ch,32); | 1861 | output.create(cw,ch,32); |
1862 | // output.setAlphaBuffer(true); // I should do some benchmarks to see if | 1862 | // output.setAlphaBuffer(true); // I should do some benchmarks to see if |
1863 | // this is worth the effort | 1863 | // this is worth the effort |
1864 | 1864 | ||
1865 | register QRgb *i, *o, *b; | 1865 | register QRgb *i, *o, *b; |
1866 | 1866 | ||
1867 | register int a; | 1867 | register int a; |
1868 | register int j,k; | 1868 | register int j,k; |
1869 | for (j=0; j<ch; j++) | 1869 | for (j=0; j<ch; j++) |
1870 | { | 1870 | { |
1871 | b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); | 1871 | b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); |
1872 | i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); | 1872 | i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); |
1873 | o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); | 1873 | o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); |
1874 | 1874 | ||
1875 | k=cw-1; | 1875 | k=cw-1; |
1876 | --b; --i; --o; | 1876 | --b; --i; --o; |
1877 | do | 1877 | do |
1878 | { | 1878 | { |
1879 | while ( !(a=qAlpha(*i)) && k>0 ) | 1879 | while ( !(a=qAlpha(*i)) && k>0 ) |
1880 | { | 1880 | { |
1881 | i--; | 1881 | i--; |
1882 | //*o=0; | 1882 | //*o=0; |
1883 | *o=*b; | 1883 | *o=*b; |
1884 | --o; --b; | 1884 | --o; --b; |
1885 | k--; | 1885 | k--; |
1886 | }; | 1886 | }; |
1887 | // *o=0xFF; | 1887 | // *o=0xFF; |
1888 | *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), | 1888 | *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), |
1889 | qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), | 1889 | qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), |
1890 | qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); | 1890 | qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); |
1891 | --i; --o; --b; | 1891 | --i; --o; --b; |
1892 | } while (k--); | 1892 | } while (k--); |
1893 | } | 1893 | } |
1894 | 1894 | ||
1895 | return true; | 1895 | return true; |
1896 | } | 1896 | } |
1897 | 1897 | ||
1898 | bool OImageEffect::blendOnLower( | 1898 | bool OImageEffect::blendOnLower( |
1899 | int x, int y, | 1899 | int x, int y, |
1900 | const QImage & upper, | 1900 | const QImage & upper, |
1901 | const QImage & lower | 1901 | const QImage & lower |
1902 | ) | 1902 | ) |
1903 | { | 1903 | { |
1904 | int cx=0, cy=0, cw=upper.width(), ch=upper.height(); | 1904 | int cx=0, cy=0, cw=upper.width(), ch=upper.height(); |
1905 | 1905 | ||
1906 | if ( upper.depth() != 32 || lower.depth() != 32 ) return false; | 1906 | if ( upper.depth() != 32 || lower.depth() != 32 ) return false; |
1907 | if ( x + cw > lower.width() || | 1907 | if ( x + cw > lower.width() || |
1908 | y + ch > lower.height() || | 1908 | y + ch > lower.height() || |
1909 | x < 0 || y < 0 ) | 1909 | x < 0 || y < 0 ) |
1910 | { | 1910 | { |
1911 | if ( x > lower.width() || y > lower.height() ) return true; | 1911 | if ( x > lower.width() || y > lower.height() ) return true; |
1912 | if ( upper.width()<=0 || upper.height() <= 0 ) return true; | 1912 | if ( upper.width()<=0 || upper.height() <= 0 ) return true; |
1913 | if ( lower.width()<=0 || lower.height() <= 0 ) return true; | 1913 | if ( lower.width()<=0 || lower.height() <= 0 ) return true; |
1914 | 1914 | ||
1915 | if (x<0) {cx=-x; cw+=x; x=0; }; | 1915 | if (x<0) {cx=-x; cw+=x; x=0; }; |
1916 | if (cw + x > lower.width()) { cw=lower.width()-x; }; | 1916 | if (cw + x > lower.width()) { cw=lower.width()-x; }; |
1917 | if (y<0) {cy=-y; ch+=y; y=0; }; | 1917 | if (y<0) {cy=-y; ch+=y; y=0; }; |
1918 | if (ch + y > lower.height()) { ch=lower.height()-y; }; | 1918 | if (ch + y > lower.height()) { ch=lower.height()-y; }; |
1919 | 1919 | ||
1920 | if ( cx >= upper.width() || cy >= upper.height() ) return true; | 1920 | if ( cx >= upper.width() || cy >= upper.height() ) return true; |
1921 | if ( cw <= 0 || ch <= 0 ) return true; | 1921 | if ( cw <= 0 || ch <= 0 ) return true; |
1922 | } | 1922 | } |
1923 | 1923 | ||
1924 | register uchar *i, *b; | 1924 | register uchar *i, *b; |
1925 | register int a; | 1925 | register int a; |
1926 | register int k; | 1926 | register int k; |
1927 | 1927 | ||
1928 | for (int j=0; j<ch; j++) | 1928 | for (int j=0; j<ch; j++) |
1929 | { | 1929 | { |
1930 | b=&lower.scanLine(y+j) [ (x+cw) << 2 ]; | 1930 | b=&lower.scanLine(y+j) [ (x+cw) << 2 ]; |
1931 | i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ]; | 1931 | i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ]; |
1932 | 1932 | ||
1933 | k=cw-1; | 1933 | k=cw-1; |
1934 | --b; --i; | 1934 | --b; --i; |
1935 | do | 1935 | do |
1936 | { | 1936 | { |
1937 | #ifndef WORDS_BIGENDIAN | 1937 | #ifndef WORDS_BIGENDIAN |
1938 | while ( !(a=*i) && k>0 ) | 1938 | while ( !(a=*i) && k>0 ) |
1939 | #else | 1939 | #else |
1940 | while ( !(a=*(i-3)) && k>0 ) | 1940 | while ( !(a=*(i-3)) && k>0 ) |
1941 | #endif | 1941 | #endif |
1942 | { | 1942 | { |
1943 | i-=4; b-=4; k--; | 1943 | i-=4; b-=4; k--; |
1944 | }; | 1944 | }; |
1945 | 1945 | ||
1946 | #ifndef WORDS_BIGENDIAN | 1946 | #ifndef WORDS_BIGENDIAN |
1947 | --i; --b; | 1947 | --i; --b; |
1948 | *b += ( ((*i - *b) * a) >> 8 ); | 1948 | *b += ( ((*i - *b) * a) >> 8 ); |
1949 | --i; --b; | 1949 | --i; --b; |
1950 | *b += ( ((*i - *b) * a) >> 8 ); | 1950 | *b += ( ((*i - *b) * a) >> 8 ); |
1951 | --i; --b; | 1951 | --i; --b; |
1952 | *b += ( ((*i - *b) * a) >> 8 ); | 1952 | *b += ( ((*i - *b) * a) >> 8 ); |
1953 | --i; --b; | 1953 | --i; --b; |
1954 | #else | 1954 | #else |
1955 | *b += ( ((*i - *b) * a) >> 8 ); | 1955 | *b += ( ((*i - *b) * a) >> 8 ); |
1956 | --i; --b; | 1956 | --i; --b; |
1957 | *b += ( ((*i - *b) * a) >> 8 ); | 1957 | *b += ( ((*i - *b) * a) >> 8 ); |
1958 | --i; --b; | 1958 | --i; --b; |
1959 | *b += ( ((*i - *b) * a) >> 8 ); | 1959 | *b += ( ((*i - *b) * a) >> 8 ); |
1960 | i -= 2; b -= 2; | 1960 | i -= 2; b -= 2; |
1961 | #endif | 1961 | #endif |
1962 | } while (k--); | 1962 | } while (k--); |
1963 | } | 1963 | } |
1964 | 1964 | ||
1965 | return true; | 1965 | return true; |
1966 | } | 1966 | } |
1967 | 1967 | ||
1968 | // For selected icons | 1968 | // For selected icons |
1969 | QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) | 1969 | QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) |
1970 | { | 1970 | { |
1971 | return blend( col, img, 0.5); | 1971 | return blend( col, img, 0.5); |
1972 | } | 1972 | } |
1973 | 1973 | ||
1974 | // | 1974 | // |
1975 | // =================================================================== | 1975 | // =================================================================== |
1976 | // Effects originally ported from ImageMagick for PixiePlus, plus a few | 1976 | // Effects originally ported from ImageMagick for PixiePlus, plus a few |
1977 | // new ones. (mosfet 12/29/01) | 1977 | // new ones. (mosfet 12/29/01) |
1978 | // =================================================================== | 1978 | // =================================================================== |
1979 | // | 1979 | // |
1980 | 1980 | ||
1981 | void OImageEffect::normalize(QImage &img) | 1981 | void OImageEffect::normalize(QImage &img) |
1982 | { | 1982 | { |
1983 | int *histogram, threshold_intensity, intense; | 1983 | int *histogram, threshold_intensity, intense; |
1984 | int x, y, i; | 1984 | int x, y, i; |
1985 | 1985 | ||
1986 | unsigned int gray_value; | 1986 | unsigned int gray_value; |
1987 | unsigned int *normalize_map; | 1987 | unsigned int *normalize_map; |
1988 | unsigned int high, low; | 1988 | unsigned int high, low; |
1989 | 1989 | ||
1990 | // allocate histogram and normalize map | 1990 | // allocate histogram and normalize map |
1991 | histogram = (int *)calloc(MaxRGB+1, sizeof(int)); | 1991 | histogram = (int *)calloc(MaxRGB+1, sizeof(int)); |
1992 | normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int)); | 1992 | normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int)); |
1993 | if(!normalize_map || !histogram){ | 1993 | if(!normalize_map || !histogram){ |
1994 | owarn << "Unable to allocate normalize histogram and map" << oendl; | 1994 | owarn << "Unable to allocate normalize histogram and map" << oendl; |
1995 | free(normalize_map); | 1995 | free(normalize_map); |
1996 | free(histogram); | 1996 | free(histogram); |
1997 | return; | 1997 | return; |
1998 | } | 1998 | } |
1999 | 1999 | ||
2000 | // form histogram | 2000 | // form histogram |
2001 | if(img.depth() > 8){ // DirectClass | 2001 | if(img.depth() > 8){ // DirectClass |
2002 | unsigned int *data; | 2002 | unsigned int *data; |
2003 | for(y=0; y < img.height(); ++y){ | 2003 | for(y=0; y < img.height(); ++y){ |
2004 | data = (unsigned int *)img.scanLine(y); | 2004 | data = (unsigned int *)img.scanLine(y); |
2005 | for(x=0; x < img.width(); ++x){ | 2005 | for(x=0; x < img.width(); ++x){ |
2006 | gray_value = intensityValue(data[x]); | 2006 | gray_value = intensityValue(data[x]); |
2007 | histogram[gray_value]++; | 2007 | histogram[gray_value]++; |
2008 | } | 2008 | } |
2009 | } | 2009 | } |
2010 | } | 2010 | } |
2011 | else{ // PsudeoClass | 2011 | else{ // PsudeoClass |
2012 | unsigned char *data; | 2012 | unsigned char *data; |
2013 | unsigned int *cTable = img.colorTable(); | 2013 | unsigned int *cTable = img.colorTable(); |
2014 | for(y=0; y < img.height(); ++y){ | 2014 | for(y=0; y < img.height(); ++y){ |
2015 | data = (unsigned char *)img.scanLine(y); | 2015 | data = (unsigned char *)img.scanLine(y); |
2016 | for(x=0; x < img.width(); ++x){ | 2016 | for(x=0; x < img.width(); ++x){ |
2017 | gray_value = intensityValue(*(cTable+data[x])); | 2017 | gray_value = intensityValue(*(cTable+data[x])); |
2018 | histogram[gray_value]++; | 2018 | histogram[gray_value]++; |
2019 | } | 2019 | } |
2020 | } | 2020 | } |
2021 | } | 2021 | } |
2022 | 2022 | ||
2023 | // find histogram boundaries by locating the 1 percent levels | 2023 | // find histogram boundaries by locating the 1 percent levels |
2024 | threshold_intensity = (img.width()*img.height())/100; | 2024 | threshold_intensity = (img.width()*img.height())/100; |
2025 | intense = 0; | 2025 | intense = 0; |
2026 | for(low=0; low < MaxRGB; ++low){ | 2026 | for(low=0; low < MaxRGB; ++low){ |
2027 | intense+=histogram[low]; | 2027 | intense+=histogram[low]; |
2028 | if(intense > threshold_intensity) | 2028 | if(intense > threshold_intensity) |
2029 | break; | 2029 | break; |
2030 | } | 2030 | } |
2031 | intense=0; | 2031 | intense=0; |
2032 | for(high=MaxRGB; high != 0; --high){ | 2032 | for(high=MaxRGB; high != 0; --high){ |
2033 | intense+=histogram[high]; | 2033 | intense+=histogram[high]; |
2034 | if(intense > threshold_intensity) | 2034 | if(intense > threshold_intensity) |
2035 | break; | 2035 | break; |
2036 | } | 2036 | } |
2037 | 2037 | ||
2038 | if (low == high){ | 2038 | if (low == high){ |
2039 | // Unreasonable contrast; use zero threshold to determine boundaries. | 2039 | // Unreasonable contrast; use zero threshold to determine boundaries. |
2040 | threshold_intensity=0; | 2040 | threshold_intensity=0; |
2041 | intense=0; | 2041 | intense=0; |
2042 | for(low=0; low < MaxRGB; ++low){ | 2042 | for(low=0; low < MaxRGB; ++low){ |
2043 | intense+=histogram[low]; | 2043 | intense+=histogram[low]; |
2044 | if(intense > threshold_intensity) | 2044 | if(intense > threshold_intensity) |
2045 | break; | 2045 | break; |
2046 | } | 2046 | } |
2047 | intense=0; | 2047 | intense=0; |
2048 | for(high=MaxRGB; high != 0; --high) | 2048 | for(high=MaxRGB; high != 0; --high) |
2049 | { | 2049 | { |
2050 | intense+=histogram[high]; | 2050 | intense+=histogram[high]; |
2051 | if(intense > threshold_intensity) | 2051 | if(intense > threshold_intensity) |
2052 | break; | 2052 | break; |
2053 | } | 2053 | } |
2054 | if(low == high) | 2054 | if(low == high) { |
2055 | free(histogram); | ||
2056 | free(normalize_map); | ||
2055 | return; // zero span bound | 2057 | return; // zero span bound |
2058 | } | ||
2056 | } | 2059 | } |
2057 | 2060 | ||
2058 | // Stretch the histogram to create the normalized image mapping. | 2061 | // Stretch the histogram to create the normalized image mapping. |
2059 | for(i=0; i <= MaxRGB; i++){ | 2062 | for(i=0; i <= MaxRGB; i++){ |
2060 | if (i < (int) low) | 2063 | if (i < (int) low) |
2061 | normalize_map[i]=0; | 2064 | normalize_map[i]=0; |
2062 | else{ | 2065 | else{ |
2063 | if(i > (int) high) | 2066 | if(i > (int) high) |
2064 | normalize_map[i]=MaxRGB; | 2067 | normalize_map[i]=MaxRGB; |
2065 | else | 2068 | else |
2066 | normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low); | 2069 | normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low); |
2067 | } | 2070 | } |
2068 | } | 2071 | } |
2069 | // Normalize | 2072 | // Normalize |
2070 | if(img.depth() > 8){ // DirectClass | 2073 | if(img.depth() > 8){ // DirectClass |
2071 | unsigned int *data; | 2074 | unsigned int *data; |
2072 | for(y=0; y < img.height(); ++y){ | 2075 | for(y=0; y < img.height(); ++y){ |
2073 | data = (unsigned int *)img.scanLine(y); | 2076 | data = (unsigned int *)img.scanLine(y); |
2074 | for(x=0; x < img.width(); ++x){ | 2077 | for(x=0; x < img.width(); ++x){ |
2075 | data[x] = qRgba(normalize_map[qRed(data[x])], | 2078 | data[x] = qRgba(normalize_map[qRed(data[x])], |
2076 | normalize_map[qGreen(data[x])], | 2079 | normalize_map[qGreen(data[x])], |
2077 | normalize_map[qBlue(data[x])], | 2080 | normalize_map[qBlue(data[x])], |
2078 | qAlpha(data[x])); | 2081 | qAlpha(data[x])); |
2079 | } | 2082 | } |
2080 | } | 2083 | } |
2081 | } | 2084 | } |
2082 | else{ // PsudeoClass | 2085 | else{ // PsudeoClass |
2083 | int colors = img.numColors(); | 2086 | int colors = img.numColors(); |
2084 | unsigned int *cTable = img.colorTable(); | 2087 | unsigned int *cTable = img.colorTable(); |
2085 | for(i=0; i < colors; ++i){ | 2088 | for(i=0; i < colors; ++i){ |
2086 | cTable[i] = qRgba(normalize_map[qRed(cTable[i])], | 2089 | cTable[i] = qRgba(normalize_map[qRed(cTable[i])], |
2087 | normalize_map[qGreen(cTable[i])], | 2090 | normalize_map[qGreen(cTable[i])], |
2088 | normalize_map[qBlue(cTable[i])], | 2091 | normalize_map[qBlue(cTable[i])], |
2089 | qAlpha(cTable[i])); | 2092 | qAlpha(cTable[i])); |
2090 | } | 2093 | } |
2091 | } | 2094 | } |
2092 | free(histogram); | 2095 | free(histogram); |
2093 | free(normalize_map); | 2096 | free(normalize_map); |
2094 | } | 2097 | } |
2095 | 2098 | ||
2096 | 2099 | ||
2097 | void OImageEffect::equalize(QImage &img) | 2100 | void OImageEffect::equalize(QImage &img) |
2098 | { | 2101 | { |
2099 | int *histogram, *map, *equalize_map; | 2102 | int *histogram, *map, *equalize_map; |
2100 | int x, y, i, j; | 2103 | int x, y, i, j; |
2101 | 2104 | ||
2102 | unsigned int high, low; | 2105 | unsigned int high, low; |
2103 | 2106 | ||
2104 | // allocate histogram and maps | 2107 | // allocate histogram and maps |
2105 | histogram = (int *)calloc(MaxRGB+1, sizeof(int)); | 2108 | histogram = (int *)calloc(MaxRGB+1, sizeof(int)); |
2106 | map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); | 2109 | map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); |
2107 | equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); | 2110 | equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); |
2108 | 2111 | ||
2109 | if(!histogram || !map || !equalize_map){ | 2112 | if(!histogram || !map || !equalize_map){ |
2110 | owarn << "Unable to allocate equalize histogram and maps" << oendl; | 2113 | owarn << "Unable to allocate equalize histogram and maps" << oendl; |
2111 | free(histogram); | 2114 | free(histogram); |
2112 | free(map); | 2115 | free(map); |
2113 | free(equalize_map); | 2116 | free(equalize_map); |
2114 | return; | 2117 | return; |
2115 | } | 2118 | } |
2116 | // form histogram | 2119 | // form histogram |
2117 | if(img.depth() > 8){ // DirectClass | 2120 | if(img.depth() > 8){ // DirectClass |
2118 | unsigned int *data; | 2121 | unsigned int *data; |
2119 | for(y=0; y < img.height(); ++y){ | 2122 | for(y=0; y < img.height(); ++y){ |
2120 | data = (unsigned int *)img.scanLine(y); | 2123 | data = (unsigned int *)img.scanLine(y); |
2121 | for(x=0; x < img.width(); ++x){ | 2124 | for(x=0; x < img.width(); ++x){ |
2122 | histogram[intensityValue(data[x])]++; | 2125 | histogram[intensityValue(data[x])]++; |
2123 | } | 2126 | } |
2124 | } | 2127 | } |
2125 | } | 2128 | } |
2126 | else{ // PsudeoClass | 2129 | else{ // PsudeoClass |
2127 | unsigned char *data; | 2130 | unsigned char *data; |
2128 | unsigned int *cTable = img.colorTable(); | 2131 | unsigned int *cTable = img.colorTable(); |
2129 | for(y=0; y < img.height(); ++y){ | 2132 | for(y=0; y < img.height(); ++y){ |
2130 | data = (unsigned char *)img.scanLine(y); | 2133 | data = (unsigned char *)img.scanLine(y); |
2131 | for(x=0; x < img.width(); ++x){ | 2134 | for(x=0; x < img.width(); ++x){ |
2132 | histogram[intensityValue(*(cTable+data[x]))]++; | 2135 | histogram[intensityValue(*(cTable+data[x]))]++; |
2133 | } | 2136 | } |
2134 | } | 2137 | } |
2135 | } | 2138 | } |
2136 | 2139 | ||
2137 | // integrate the histogram to get the equalization map. | 2140 | // integrate the histogram to get the equalization map. |
2138 | j=0; | 2141 | j=0; |
2139 | for(i=0; i <= MaxRGB; i++){ | 2142 | for(i=0; i <= MaxRGB; i++){ |
2140 | j+=histogram[i]; | 2143 | j+=histogram[i]; |
2141 | map[i]=j; | 2144 | map[i]=j; |
2142 | } | 2145 | } |
2143 | free(histogram); | 2146 | free(histogram); |
2144 | if(map[MaxRGB] == 0){ | 2147 | if(map[MaxRGB] == 0){ |
2145 | free(equalize_map); | 2148 | free(equalize_map); |
2146 | free(map); | 2149 | free(map); |
2147 | return; | 2150 | return; |
2148 | } | 2151 | } |
2149 | // equalize | 2152 | // equalize |
2150 | low=map[0]; | 2153 | low=map[0]; |
2151 | high=map[MaxRGB]; | 2154 | high=map[MaxRGB]; |
2152 | for(i=0; i <= MaxRGB; i++) | 2155 | for(i=0; i <= MaxRGB; i++) |
2153 | equalize_map[i]=(unsigned int) | 2156 | equalize_map[i]=(unsigned int) |
2154 | ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1)); | 2157 | ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1)); |
2155 | free(map); | 2158 | free(map); |
2156 | // stretch the histogram | 2159 | // stretch the histogram |
2157 | if(img.depth() > 8){ // DirectClass | 2160 | if(img.depth() > 8){ // DirectClass |
2158 | unsigned int *data; | 2161 | unsigned int *data; |
2159 | for(y=0; y < img.height(); ++y){ | 2162 | for(y=0; y < img.height(); ++y){ |
2160 | data = (unsigned int *)img.scanLine(y); | 2163 | data = (unsigned int *)img.scanLine(y); |
2161 | for(x=0; x < img.width(); ++x){ | 2164 | for(x=0; x < img.width(); ++x){ |
2162 | data[x] = qRgba(equalize_map[qRed(data[x])], | 2165 | data[x] = qRgba(equalize_map[qRed(data[x])], |
2163 | equalize_map[qGreen(data[x])], | 2166 | equalize_map[qGreen(data[x])], |
2164 | equalize_map[qBlue(data[x])], | 2167 | equalize_map[qBlue(data[x])], |
2165 | qAlpha(data[x])); | 2168 | qAlpha(data[x])); |
2166 | } | 2169 | } |
2167 | } | 2170 | } |
2168 | } | 2171 | } |
2169 | else{ // PsudeoClass | 2172 | else{ // PsudeoClass |
2170 | int colors = img.numColors(); | 2173 | int colors = img.numColors(); |
2171 | unsigned int *cTable = img.colorTable(); | 2174 | unsigned int *cTable = img.colorTable(); |
2172 | for(i=0; i < colors; ++i){ | 2175 | for(i=0; i < colors; ++i){ |
2173 | cTable[i] = qRgba(equalize_map[qRed(cTable[i])], | 2176 | cTable[i] = qRgba(equalize_map[qRed(cTable[i])], |
2174 | equalize_map[qGreen(cTable[i])], | 2177 | equalize_map[qGreen(cTable[i])], |
2175 | equalize_map[qBlue(cTable[i])], | 2178 | equalize_map[qBlue(cTable[i])], |
2176 | qAlpha(cTable[i])); | 2179 | qAlpha(cTable[i])); |
2177 | } | 2180 | } |
2178 | } | 2181 | } |
2179 | free(equalize_map); | 2182 | free(equalize_map); |
2180 | } | 2183 | } |
2181 | 2184 | ||
2182 | QImage OImageEffect::sample(QImage &src, int w, int h) | 2185 | QImage OImageEffect::sample(QImage &src, int w, int h) |
2183 | { | 2186 | { |
2184 | if(w == src.width() && h == src.height()) | 2187 | if(w == src.width() && h == src.height()) |
2185 | return(src); | 2188 | return(src); |
2186 | 2189 | ||
2187 | double *x_offset, *y_offset; | 2190 | double *x_offset, *y_offset; |
2188 | int j, k, y; | 2191 | int j, k, y; |
2189 | register int x; | 2192 | register int x; |
2190 | QImage dest(w, h, src.depth()); | 2193 | QImage dest(w, h, src.depth()); |
2191 | 2194 | ||
2192 | x_offset = (double *)malloc(w*sizeof(double)); | 2195 | x_offset = (double *)malloc(w*sizeof(double)); |
2193 | y_offset = (double *)malloc(h*sizeof(double)); | 2196 | y_offset = (double *)malloc(h*sizeof(double)); |
2194 | if(!x_offset || !y_offset){ | 2197 | if(!x_offset || !y_offset){ |
2195 | owarn << "Unable to allocate pixels buffer" << oendl; | 2198 | owarn << "Unable to allocate pixels buffer" << oendl; |
2196 | free(x_offset); | 2199 | free(x_offset); |
2197 | free(y_offset); | 2200 | free(y_offset); |
2198 | return(src); | 2201 | return(src); |
2199 | } | 2202 | } |
2200 | 2203 | ||
2201 | // init pixel offsets | 2204 | // init pixel offsets |
2202 | for(x=0; x < w; ++x) | 2205 | for(x=0; x < w; ++x) |
2203 | x_offset[x] = x*src.width()/((double)w); | 2206 | x_offset[x] = x*src.width()/((double)w); |
2204 | for(y=0; y < h; ++y) | 2207 | for(y=0; y < h; ++y) |
2205 | y_offset[y] = y*src.height()/((double)h); | 2208 | y_offset[y] = y*src.height()/((double)h); |
2206 | 2209 | ||
2207 | // sample each row | 2210 | // sample each row |
2208 | if(src.depth() > 8){ // DirectClass source image | 2211 | if(src.depth() > 8){ // DirectClass source image |
2209 | unsigned int *srcData, *destData; | 2212 | unsigned int *srcData, *destData; |
2210 | unsigned int *pixels; | 2213 | unsigned int *pixels; |
2211 | pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int)); | 2214 | pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int)); |
2212 | if(!pixels){ | 2215 | if(!pixels){ |
2213 | owarn << "Unable to allocate pixels buffer" << oendl; | 2216 | owarn << "Unable to allocate pixels buffer" << oendl; |
2214 | free(pixels); | 2217 | free(pixels); |
2215 | free(x_offset); | 2218 | free(x_offset); |
2216 | free(y_offset); | 2219 | free(y_offset); |
2217 | return(src); | 2220 | return(src); |
2218 | } | 2221 | } |
2219 | j = (-1); | 2222 | j = (-1); |
2220 | for(y=0; y < h; ++y){ | 2223 | for(y=0; y < h; ++y){ |
2221 | destData = (unsigned int *)dest.scanLine(y); | 2224 | destData = (unsigned int *)dest.scanLine(y); |
2222 | if(j != y_offset[y]){ | 2225 | if(j != y_offset[y]){ |
2223 | // read a scan line | 2226 | // read a scan line |
2224 | j = (int)(y_offset[y]); | 2227 | j = (int)(y_offset[y]); |
2225 | srcData = (unsigned int *)src.scanLine(j); | 2228 | srcData = (unsigned int *)src.scanLine(j); |
2226 | (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int)); | 2229 | (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int)); |
2227 | } | 2230 | } |
2228 | // sample each column | 2231 | // sample each column |
2229 | for(x=0; x < w; ++x){ | 2232 | for(x=0; x < w; ++x){ |
2230 | k = (int)(x_offset[x]); | 2233 | k = (int)(x_offset[x]); |
2231 | destData[x] = pixels[k]; | 2234 | destData[x] = pixels[k]; |
2232 | } | 2235 | } |
2233 | } | 2236 | } |
2234 | free(pixels); | 2237 | free(pixels); |
2235 | } | 2238 | } |
2236 | else{ // PsudeoClass source image | 2239 | else{ // PsudeoClass source image |
2237 | unsigned char *srcData, *destData; | 2240 | unsigned char *srcData, *destData; |
2238 | unsigned char *pixels; | 2241 | unsigned char *pixels; |
2239 | pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char)); | 2242 | pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char)); |
2240 | if(!pixels){ | 2243 | if(!pixels){ |
2241 | owarn << "Unable to allocate pixels buffer" << oendl; | 2244 | owarn << "Unable to allocate pixels buffer" << oendl; |
2242 | free(pixels); | 2245 | free(pixels); |
2243 | free(x_offset); | 2246 | free(x_offset); |
2244 | free(y_offset); | 2247 | free(y_offset); |
2245 | return(src); | 2248 | return(src); |
2246 | } | 2249 | } |
2247 | // copy colortable | 2250 | // copy colortable |
2248 | dest.setNumColors(src.numColors()); | 2251 | dest.setNumColors(src.numColors()); |
2249 | (void)memcpy(dest.colorTable(), src.colorTable(), | 2252 | (void)memcpy(dest.colorTable(), src.colorTable(), |
2250 | src.numColors()*sizeof(unsigned int)); | 2253 | src.numColors()*sizeof(unsigned int)); |
2251 | 2254 | ||
2252 | // sample image | 2255 | // sample image |
2253 | j = (-1); | 2256 | j = (-1); |
2254 | for(y=0; y < h; ++y){ | 2257 | for(y=0; y < h; ++y){ |
2255 | destData = (unsigned char *)dest.scanLine(y); | 2258 | destData = (unsigned char *)dest.scanLine(y); |
2256 | if(j != y_offset[y]){ | 2259 | if(j != y_offset[y]){ |
2257 | // read a scan line | 2260 | // read a scan line |
2258 | j = (int)(y_offset[y]); | 2261 | j = (int)(y_offset[y]); |
2259 | srcData = (unsigned char *)src.scanLine(j); | 2262 | srcData = (unsigned char *)src.scanLine(j); |
2260 | (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned char)); | 2263 | (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned char)); |
2261 | } | 2264 | } |
2262 | // sample each column | 2265 | // sample each column |
2263 | for(x=0; x < w; ++x){ | 2266 | for(x=0; x < w; ++x){ |
2264 | k = (int)(x_offset[x]); | 2267 | k = (int)(x_offset[x]); |
2265 | destData[x] = pixels[k]; | 2268 | destData[x] = pixels[k]; |
2266 | } | 2269 | } |
2267 | } | 2270 | } |
2268 | free(pixels); | 2271 | free(pixels); |
2269 | } | 2272 | } |
2270 | free(x_offset); | 2273 | free(x_offset); |
2271 | free(y_offset); | 2274 | free(y_offset); |
2272 | return(dest); | 2275 | return(dest); |
2273 | } | 2276 | } |
2274 | 2277 | ||
2275 | void OImageEffect::threshold(QImage &img, unsigned int threshold) | 2278 | void OImageEffect::threshold(QImage &img, unsigned int threshold) |
2276 | { | 2279 | { |
2277 | int i, count; | 2280 | int i, count; |
2278 | unsigned int *data; | 2281 | unsigned int *data; |
2279 | if(img.depth() > 8){ // DirectClass | 2282 | if(img.depth() > 8){ // DirectClass |
2280 | count = img.width()*img.height(); | 2283 | count = img.width()*img.height(); |
2281 | data = (unsigned int *)img.bits(); | 2284 | data = (unsigned int *)img.bits(); |
2282 | } | 2285 | } |
2283 | else{ // PsudeoClass | 2286 | else{ // PsudeoClass |
2284 | count = img.numColors(); | 2287 | count = img.numColors(); |
2285 | data = (unsigned int *)img.colorTable(); | 2288 | data = (unsigned int *)img.colorTable(); |
2286 | } | 2289 | } |
2287 | for(i=0; i < count; ++i) | 2290 | for(i=0; i < count; ++i) |
2288 | data[i] = intensityValue(data[i]) < threshold ? Qt::black.rgb() : Qt::white.rgb(); | 2291 | data[i] = intensityValue(data[i]) < threshold ? Qt::black.rgb() : Qt::white.rgb(); |
2289 | } | 2292 | } |
2290 | 2293 | ||
2291 | QImage OImageEffect::charcoal(QImage &src, double factor) | 2294 | QImage OImageEffect::charcoal(QImage &src, double factor) |
2292 | { | 2295 | { |
2293 | QImage dest(src); | 2296 | QImage dest(src); |
2294 | dest.detach(); | 2297 | dest.detach(); |
2295 | toGray(dest); | 2298 | toGray(dest); |
2296 | dest = edge(dest, factor); | 2299 | dest = edge(dest, factor); |
2297 | dest = blur(dest, factor); | 2300 | dest = blur(dest, factor); |
2298 | normalize(dest); | 2301 | normalize(dest); |
2299 | dest.invertPixels(false); | 2302 | dest.invertPixels(false); |
2300 | return(dest); | 2303 | return(dest); |
2301 | } | 2304 | } |
2302 | 2305 | ||
2303 | void OImageEffect::hull(const int x_offset, const int y_offset, | 2306 | void OImageEffect::hull(const int x_offset, const int y_offset, |
2304 | const int polarity, const int columns, | 2307 | const int polarity, const int columns, |
2305 | const int rows, | 2308 | const int rows, |
2306 | unsigned int *f, unsigned int *g) | 2309 | unsigned int *f, unsigned int *g) |
2307 | { | 2310 | { |
2308 | int x, y; | 2311 | int x, y; |
2309 | 2312 | ||
2310 | unsigned int *p, *q, *r, *s; | 2313 | unsigned int *p, *q, *r, *s; |
2311 | unsigned int v; | 2314 | unsigned int v; |
2312 | if(f == NULL || g == NULL) | 2315 | if(f == NULL || g == NULL) |
2313 | return; | 2316 | return; |
2314 | p=f+(columns+2); | 2317 | p=f+(columns+2); |
2315 | q=g+(columns+2); | 2318 | q=g+(columns+2); |
2316 | r=p+(y_offset*(columns+2)+x_offset); | 2319 | r=p+(y_offset*(columns+2)+x_offset); |
2317 | for (y=0; y < rows; y++){ | 2320 | for (y=0; y < rows; y++){ |
2318 | p++; | 2321 | p++; |
2319 | q++; | 2322 | q++; |
2320 | r++; | 2323 | r++; |
2321 | if(polarity > 0) | 2324 | if(polarity > 0) |
2322 | for (x=0; x < columns; x++){ | 2325 | for (x=0; x < columns; x++){ |
2323 | v=(*p); | 2326 | v=(*p); |
2324 | if (*r > v) | 2327 | if (*r > v) |
2325 | v++; | 2328 | v++; |
2326 | *q=v; | 2329 | *q=v; |
2327 | p++; | 2330 | p++; |
2328 | q++; | 2331 | q++; |
2329 | r++; | 2332 | r++; |
2330 | } | 2333 | } |
2331 | else | 2334 | else |
2332 | for(x=0; x < columns; x++){ | 2335 | for(x=0; x < columns; x++){ |
2333 | v=(*p); | 2336 | v=(*p); |
2334 | if (v > (unsigned int) (*r+1)) | 2337 | if (v > (unsigned int) (*r+1)) |
2335 | v--; | 2338 | v--; |
2336 | *q=v; | 2339 | *q=v; |
2337 | p++; | 2340 | p++; |
2338 | q++; | 2341 | q++; |
2339 | r++; | 2342 | r++; |
2340 | } | 2343 | } |
2341 | p++; | 2344 | p++; |
2342 | q++; | 2345 | q++; |
2343 | r++; | 2346 | r++; |
2344 | } | 2347 | } |
2345 | p=f+(columns+2); | 2348 | p=f+(columns+2); |
2346 | q=g+(columns+2); | 2349 | q=g+(columns+2); |
2347 | r=q+(y_offset*(columns+2)+x_offset); | 2350 | r=q+(y_offset*(columns+2)+x_offset); |
2348 | s=q-(y_offset*(columns+2)+x_offset); | 2351 | s=q-(y_offset*(columns+2)+x_offset); |
2349 | for(y=0; y < rows; y++){ | 2352 | for(y=0; y < rows; y++){ |
2350 | p++; | 2353 | p++; |
2351 | q++; | 2354 | q++; |
2352 | r++; | 2355 | r++; |
2353 | s++; | 2356 | s++; |
2354 | if(polarity > 0) | 2357 | if(polarity > 0) |
2355 | for(x=0; x < (int) columns; x++){ | 2358 | for(x=0; x < (int) columns; x++){ |
2356 | v=(*q); | 2359 | v=(*q); |
2357 | if (((unsigned int) (*s+1) > v) && (*r > v)) | 2360 | if (((unsigned int) (*s+1) > v) && (*r > v)) |
2358 | v++; | 2361 | v++; |
2359 | *p=v; | 2362 | *p=v; |
2360 | p++; | 2363 | p++; |
2361 | q++; | 2364 | q++; |
2362 | r++; | 2365 | r++; |
2363 | s++; | 2366 | s++; |
2364 | } | 2367 | } |
2365 | else | 2368 | else |
2366 | for (x=0; x < columns; x++){ | 2369 | for (x=0; x < columns; x++){ |
2367 | v=(*q); | 2370 | v=(*q); |
2368 | if (((unsigned int) (*s+1) < v) && (*r < v)) | 2371 | if (((unsigned int) (*s+1) < v) && (*r < v)) |
2369 | v--; | 2372 | v--; |
2370 | *p=v; | 2373 | *p=v; |
2371 | p++; | 2374 | p++; |
2372 | q++; | 2375 | q++; |
2373 | r++; | 2376 | r++; |
2374 | s++; | 2377 | s++; |
2375 | } | 2378 | } |
2376 | p++; | 2379 | p++; |
2377 | q++; | 2380 | q++; |
2378 | r++; | 2381 | r++; |
2379 | s++; | 2382 | s++; |
2380 | } | 2383 | } |
2381 | } | 2384 | } |
2382 | 2385 | ||
2383 | QImage OImageEffect::despeckle(QImage &src) | 2386 | QImage OImageEffect::despeckle(QImage &src) |
2384 | { | 2387 | { |
2385 | int i, j, x, y; | 2388 | int i, j, x, y; |
2386 | unsigned int *blue_channel, *red_channel, *green_channel, *buffer, | 2389 | unsigned int *blue_channel, *red_channel, *green_channel, *buffer, |
2387 | *alpha_channel; | 2390 | *alpha_channel; |
2388 | int packets; | 2391 | int packets; |
2389 | static const int | 2392 | static const int |
2390 | X[4]= {0, 1, 1,-1}, | 2393 | X[4]= {0, 1, 1,-1}, |
2391 | Y[4]= {1, 0, 1, 1}; | 2394 | Y[4]= {1, 0, 1, 1}; |
2392 | 2395 | ||
2393 | unsigned int *destData; | 2396 | unsigned int *destData; |
2394 | QImage dest(src.width(), src.height(), 32); | 2397 | QImage dest(src.width(), src.height(), 32); |
2395 | 2398 | ||
2396 | packets = (src.width()+2)*(src.height()+2); | 2399 | packets = (src.width()+2)*(src.height()+2); |
2397 | red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); | 2400 | red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); |
2398 | green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); | 2401 | green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); |
2399 | blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); | 2402 | blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); |
2400 | alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); | 2403 | alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); |
2401 | buffer = (unsigned int *)calloc(packets, sizeof(unsigned int)); | 2404 | buffer = (unsigned int *)calloc(packets, sizeof(unsigned int)); |
2402 | if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || | 2405 | if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || |
2403 | !buffer){ | 2406 | !buffer){ |
2404 | free(red_channel); | 2407 | free(red_channel); |
2405 | free(green_channel); | 2408 | free(green_channel); |
2406 | free(blue_channel); | 2409 | free(blue_channel); |
2407 | free(alpha_channel); | 2410 | free(alpha_channel); |
2408 | free(buffer); | 2411 | free(buffer); |
2409 | return(src); | 2412 | return(src); |
2410 | } | 2413 | } |
2411 | 2414 | ||
2412 | // copy image pixels to color component buffers | 2415 | // copy image pixels to color component buffers |
2413 | j = src.width()+2; | 2416 | j = src.width()+2; |
2414 | if(src.depth() > 8){ // DirectClass source image | 2417 | if(src.depth() > 8){ // DirectClass source image |
2415 | unsigned int *srcData; | 2418 | unsigned int *srcData; |
2416 | for(y=0; y < src.height(); ++y){ | 2419 | for(y=0; y < src.height(); ++y){ |
2417 | srcData = (unsigned int *)src.scanLine(y); | 2420 | srcData = (unsigned int *)src.scanLine(y); |
2418 | ++j; | 2421 | ++j; |
2419 | for(x=0; x < src.width(); ++x){ | 2422 | for(x=0; x < src.width(); ++x){ |
2420 | red_channel[j] = qRed(srcData[x]); | 2423 | red_channel[j] = qRed(srcData[x]); |
2421 | green_channel[j] = qGreen(srcData[x]); | 2424 | green_channel[j] = qGreen(srcData[x]); |
2422 | blue_channel[j] = qBlue(srcData[x]); | 2425 | blue_channel[j] = qBlue(srcData[x]); |
2423 | alpha_channel[j] = qAlpha(srcData[x]); | 2426 | alpha_channel[j] = qAlpha(srcData[x]); |
2424 | ++j; | 2427 | ++j; |
2425 | } | 2428 | } |
2426 | ++j; | 2429 | ++j; |
2427 | } | 2430 | } |
2428 | } | 2431 | } |
2429 | else{ // PsudeoClass source image | 2432 | else{ // PsudeoClass source image |
2430 | unsigned char *srcData; | 2433 | unsigned char *srcData; |
2431 | unsigned int *cTable = src.colorTable(); | 2434 | unsigned int *cTable = src.colorTable(); |
2432 | unsigned int pixel; | 2435 | unsigned int pixel; |
2433 | for(y=0; y < src.height(); ++y){ | 2436 | for(y=0; y < src.height(); ++y){ |
2434 | srcData = (unsigned char *)src.scanLine(y); | 2437 | srcData = (unsigned char *)src.scanLine(y); |
2435 | ++j; | 2438 | ++j; |
2436 | for(x=0; x < src.width(); ++x){ | 2439 | for(x=0; x < src.width(); ++x){ |
2437 | pixel = *(cTable+srcData[x]); | 2440 | pixel = *(cTable+srcData[x]); |
2438 | red_channel[j] = qRed(pixel); | 2441 | red_channel[j] = qRed(pixel); |
2439 | green_channel[j] = qGreen(pixel); | 2442 | green_channel[j] = qGreen(pixel); |
diff --git a/library/global.cpp b/library/global.cpp index 7bdd0b1..1895006 100644 --- a/library/global.cpp +++ b/library/global.cpp | |||
@@ -158,703 +158,707 @@ static QString dictDir() | |||
158 | user. The showInputMethod() function shows the current input method, | 158 | user. The showInputMethod() function shows the current input method, |
159 | and hideInputMethod() hides the input method. | 159 | and hideInputMethod() hides the input method. |
160 | 160 | ||
161 | \section1 Document related | 161 | \section1 Document related |
162 | 162 | ||
163 | The findDocuments() function creates a set of \link doclnk.html | 163 | The findDocuments() function creates a set of \link doclnk.html |
164 | DocLnk\endlink objects in a particular folder. | 164 | DocLnk\endlink objects in a particular folder. |
165 | 165 | ||
166 | \section1 Filesystem related | 166 | \section1 Filesystem related |
167 | 167 | ||
168 | Global provides an applicationFileName() function that returns the | 168 | Global provides an applicationFileName() function that returns the |
169 | full path of an application-specific file. | 169 | full path of an application-specific file. |
170 | 170 | ||
171 | The execute() function runs an application. | 171 | The execute() function runs an application. |
172 | 172 | ||
173 | \section1 Word list related | 173 | \section1 Word list related |
174 | 174 | ||
175 | A list of words relevant to the current locale is maintained by the | 175 | A list of words relevant to the current locale is maintained by the |
176 | system. The list is held in a \link qdawg.html DAWG\endlink | 176 | system. The list is held in a \link qdawg.html DAWG\endlink |
177 | (implemented by the QDawg class). This list is used, for example, by | 177 | (implemented by the QDawg class). This list is used, for example, by |
178 | the pickboard input method. | 178 | the pickboard input method. |
179 | 179 | ||
180 | The global QDawg is returned by fixedDawg(); this cannot be updated. | 180 | The global QDawg is returned by fixedDawg(); this cannot be updated. |
181 | An updatable copy of the global QDawg is returned by addedDawg(). | 181 | An updatable copy of the global QDawg is returned by addedDawg(). |
182 | Applications may have their own word lists stored in \l{QDawg}s | 182 | Applications may have their own word lists stored in \l{QDawg}s |
183 | which are returned by dawg(). Use addWords() to add words to the | 183 | which are returned by dawg(). Use addWords() to add words to the |
184 | updateable copy of the global QDawg or to named application | 184 | updateable copy of the global QDawg or to named application |
185 | \l{QDawg}s. | 185 | \l{QDawg}s. |
186 | 186 | ||
187 | \section1 Quoting | 187 | \section1 Quoting |
188 | 188 | ||
189 | The shellQuote() function quotes a string suitable for passing to a | 189 | The shellQuote() function quotes a string suitable for passing to a |
190 | shell. The stringQuote() function backslash escapes '\' and '"' | 190 | shell. The stringQuote() function backslash escapes '\' and '"' |
191 | characters. | 191 | characters. |
192 | 192 | ||
193 | \section1 Hardware | 193 | \section1 Hardware |
194 | 194 | ||
195 | The implementation of the writeHWClock() function depends on the AlarmServer | 195 | The implementation of the writeHWClock() function depends on the AlarmServer |
196 | implementation. If the AlarmServer is using atd the clock will be synced to | 196 | implementation. If the AlarmServer is using atd the clock will be synced to |
197 | hardware. If opie-alarm is used the hardware clock will be synced before | 197 | hardware. If opie-alarm is used the hardware clock will be synced before |
198 | suspending the device. opie-alarm is used by iPAQ and Zaurii implementation | 198 | suspending the device. opie-alarm is used by iPAQ and Zaurii implementation |
199 | 199 | ||
200 | \ingroup qtopiaemb | 200 | \ingroup qtopiaemb |
201 | */ | 201 | */ |
202 | 202 | ||
203 | /*! | 203 | /*! |
204 | \internal | 204 | \internal |
205 | */ | 205 | */ |
206 | Global::Global() | 206 | Global::Global() |
207 | { | 207 | { |
208 | } | 208 | } |
209 | 209 | ||
210 | /*! | 210 | /*! |
211 | Returns the unchangeable QDawg that contains general | 211 | Returns the unchangeable QDawg that contains general |
212 | words for the current locale. | 212 | words for the current locale. |
213 | 213 | ||
214 | \sa addedDawg() | 214 | \sa addedDawg() |
215 | */ | 215 | */ |
216 | const QDawg& Global::fixedDawg() | 216 | const QDawg& Global::fixedDawg() |
217 | { | 217 | { |
218 | if ( !fixed_dawg ) { | 218 | if ( !fixed_dawg ) { |
219 | if ( !docDirCreated ) | 219 | if ( !docDirCreated ) |
220 | createDocDir(); | 220 | createDocDir(); |
221 | 221 | ||
222 | fixed_dawg = new QDawg; | 222 | fixed_dawg = new QDawg; |
223 | QString dawgfilename = dictDir() + "/dawg"; | 223 | QString dawgfilename = dictDir() + "/dawg"; |
224 | QString words_lang; | 224 | QString words_lang; |
225 | QStringList langs = Global::languageList(); | 225 | QStringList langs = Global::languageList(); |
226 | for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { | 226 | for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { |
227 | QString lang = *it; | 227 | QString lang = *it; |
228 | words_lang = dictDir() + "/words." + lang; | 228 | words_lang = dictDir() + "/words." + lang; |
229 | QString dawgfilename_lang = dawgfilename + "." + lang; | 229 | QString dawgfilename_lang = dawgfilename + "." + lang; |
230 | if ( QFile::exists(dawgfilename_lang) || | 230 | if ( QFile::exists(dawgfilename_lang) || |
231 | QFile::exists(words_lang) ) { | 231 | QFile::exists(words_lang) ) { |
232 | dawgfilename = dawgfilename_lang; | 232 | dawgfilename = dawgfilename_lang; |
233 | break; | 233 | break; |
234 | } | 234 | } |
235 | } | 235 | } |
236 | QFile dawgfile(dawgfilename); | 236 | QFile dawgfile(dawgfilename); |
237 | 237 | ||
238 | if ( !dawgfile.exists() ) { | 238 | if ( !dawgfile.exists() ) { |
239 | QString fn = dictDir() + "/words"; | 239 | QString fn = dictDir() + "/words"; |
240 | if ( QFile::exists(words_lang) ) | 240 | if ( QFile::exists(words_lang) ) |
241 | fn = words_lang; | 241 | fn = words_lang; |
242 | QFile in(fn); | 242 | QFile in(fn); |
243 | if ( in.open(IO_ReadOnly) ) { | 243 | if ( in.open(IO_ReadOnly) ) { |
244 | fixed_dawg->createFromWords(&in); | 244 | fixed_dawg->createFromWords(&in); |
245 | if (dawgfile.open(IO_WriteOnly)) | 245 | if (dawgfile.open(IO_WriteOnly)) |
246 | fixed_dawg->write(&dawgfile); | 246 | fixed_dawg->write(&dawgfile); |
247 | dawgfile.close(); | 247 | dawgfile.close(); |
248 | } | 248 | } |
249 | } else | 249 | } else |
250 | fixed_dawg->readFile(dawgfilename); | 250 | fixed_dawg->readFile(dawgfilename); |
251 | } | 251 | } |
252 | 252 | ||
253 | return *fixed_dawg; | 253 | return *fixed_dawg; |
254 | } | 254 | } |
255 | 255 | ||
256 | /*! | 256 | /*! |
257 | Returns the changeable QDawg that contains general | 257 | Returns the changeable QDawg that contains general |
258 | words for the current locale. | 258 | words for the current locale. |
259 | 259 | ||
260 | \sa fixedDawg() | 260 | \sa fixedDawg() |
261 | */ | 261 | */ |
262 | const QDawg& Global::addedDawg() | 262 | const QDawg& Global::addedDawg() |
263 | { | 263 | { |
264 | return dawg("local"); | 264 | return dawg("local"); |
265 | } | 265 | } |
266 | 266 | ||
267 | /*! | 267 | /*! |
268 | Returns the QDawg with the given \a name. | 268 | Returns the QDawg with the given \a name. |
269 | This is an application-specific word list. | 269 | This is an application-specific word list. |
270 | 270 | ||
271 | \a name should not contain "/". | 271 | \a name should not contain "/". |
272 | */ | 272 | */ |
273 | const QDawg& Global::dawg(const QString& name) | 273 | const QDawg& Global::dawg(const QString& name) |
274 | { | 274 | { |
275 | createDocDir(); | 275 | createDocDir(); |
276 | if ( !named_dawg ) | 276 | if ( !named_dawg ) |
277 | named_dawg = new QDict<QDawg>; | 277 | named_dawg = new QDict<QDawg>; |
278 | QDawg* r = named_dawg->find(name); | 278 | QDawg* r = named_dawg->find(name); |
279 | if ( !r ) { | 279 | if ( !r ) { |
280 | r = new QDawg; | 280 | r = new QDawg; |
281 | named_dawg->insert(name,r); | 281 | named_dawg->insert(name,r); |
282 | QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; | 282 | QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; |
283 | QFile dawgfile(dawgfilename); | 283 | QFile dawgfile(dawgfilename); |
284 | if ( dawgfile.open(IO_ReadOnly) ) | 284 | if ( dawgfile.open(IO_ReadOnly) ) |
285 | r->readFile(dawgfilename); | 285 | r->readFile(dawgfilename); |
286 | } | 286 | } |
287 | return *r; | 287 | return *r; |
288 | } | 288 | } |
289 | 289 | ||
290 | /*! | 290 | /*! |
291 | \overload | 291 | \overload |
292 | Adds \a wordlist to the addedDawg(). | 292 | Adds \a wordlist to the addedDawg(). |
293 | 293 | ||
294 | Note that the addition of words persists between program executions | 294 | Note that the addition of words persists between program executions |
295 | (they are saved in the dictionary files), so you should confirm the | 295 | (they are saved in the dictionary files), so you should confirm the |
296 | words with the user before adding them. | 296 | words with the user before adding them. |
297 | */ | 297 | */ |
298 | void Global::addWords(const QStringList& wordlist) | 298 | void Global::addWords(const QStringList& wordlist) |
299 | { | 299 | { |
300 | addWords("local",wordlist); | 300 | addWords("local",wordlist); |
301 | } | 301 | } |
302 | 302 | ||
303 | /*! | 303 | /*! |
304 | \overload | 304 | \overload |
305 | Adds \a wordlist to the addedDawg(). | 305 | Adds \a wordlist to the addedDawg(). |
306 | 306 | ||
307 | Note that the addition of words persists between program executions | 307 | Note that the addition of words persists between program executions |
308 | (they are saved in the dictionary files), so you should confirm the | 308 | (they are saved in the dictionary files), so you should confirm the |
309 | words with the user before adding them. | 309 | words with the user before adding them. |
310 | */ | 310 | */ |
311 | void Global::addWords(const QString& dictname, const QStringList& wordlist) | 311 | void Global::addWords(const QString& dictname, const QStringList& wordlist) |
312 | { | 312 | { |
313 | QDawg& d = (QDawg&)dawg(dictname); | 313 | QDawg& d = (QDawg&)dawg(dictname); |
314 | QStringList all = d.allWords() + wordlist; | 314 | QStringList all = d.allWords() + wordlist; |
315 | d.createFromWords(all); | 315 | d.createFromWords(all); |
316 | 316 | ||
317 | QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; | 317 | QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; |
318 | QFile dawgfile(dawgfilename); | 318 | QFile dawgfile(dawgfilename); |
319 | if ( dawgfile.open(IO_WriteOnly) ) { | 319 | if ( dawgfile.open(IO_WriteOnly) ) { |
320 | d.write(&dawgfile); | 320 | d.write(&dawgfile); |
321 | dawgfile.close(); | 321 | dawgfile.close(); |
322 | } | 322 | } |
323 | 323 | ||
324 | // #### Re-read the dawg here if we use mmap(). | 324 | // #### Re-read the dawg here if we use mmap(). |
325 | 325 | ||
326 | // #### Signal other processes to re-read. | 326 | // #### Signal other processes to re-read. |
327 | } | 327 | } |
328 | 328 | ||
329 | 329 | ||
330 | /*! | 330 | /*! |
331 | Returns the full path for the application called \a appname, with the | 331 | Returns the full path for the application called \a appname, with the |
332 | given \a filename. Returns QString::null if there was a problem creating | 332 | given \a filename. Returns QString::null if there was a problem creating |
333 | the directory tree for \a appname. | 333 | the directory tree for \a appname. |
334 | If \a filename contains "/", it is the caller's responsibility to | 334 | If \a filename contains "/", it is the caller's responsibility to |
335 | ensure that those directories exist. | 335 | ensure that those directories exist. |
336 | */ | 336 | */ |
337 | QString Global::applicationFileName(const QString& appname, const QString& filename) | 337 | QString Global::applicationFileName(const QString& appname, const QString& filename) |
338 | { | 338 | { |
339 | QDir d; | 339 | QDir d; |
340 | QString r = getenv("HOME"); | 340 | QString r = getenv("HOME"); |
341 | r += "/Applications/"; | 341 | r += "/Applications/"; |
342 | if ( !QFile::exists( r ) ) | 342 | if ( !QFile::exists( r ) ) |
343 | if ( d.mkdir(r) == false ) | 343 | if ( d.mkdir(r) == false ) |
344 | return QString::null; | 344 | return QString::null; |
345 | r += appname; | 345 | r += appname; |
346 | if ( !QFile::exists( r ) ) | 346 | if ( !QFile::exists( r ) ) |
347 | if ( d.mkdir(r) == false ) | 347 | if ( d.mkdir(r) == false ) |
348 | return QString::null; | 348 | return QString::null; |
349 | r += "/"; r += filename; | 349 | r += "/"; r += filename; |
350 | return r; | 350 | return r; |
351 | } | 351 | } |
352 | 352 | ||
353 | /*! | 353 | /*! |
354 | \internal | 354 | \internal |
355 | */ | 355 | */ |
356 | void Global::createDocDir() | 356 | void Global::createDocDir() |
357 | { | 357 | { |
358 | if ( !docDirCreated ) { | 358 | if ( !docDirCreated ) { |
359 | docDirCreated = TRUE; | 359 | docDirCreated = TRUE; |
360 | mkdir( QPEApplication::documentDir().latin1(), 0755 ); | 360 | mkdir( QPEApplication::documentDir().latin1(), 0755 ); |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
364 | 364 | ||
365 | /*! | 365 | /*! |
366 | Displays a status \a message to the user. This usually appears | 366 | Displays a status \a message to the user. This usually appears |
367 | in the taskbar for a short amount of time, then disappears. | 367 | in the taskbar for a short amount of time, then disappears. |
368 | */ | 368 | */ |
369 | void Global::statusMessage(const QString& message) | 369 | void Global::statusMessage(const QString& message) |
370 | { | 370 | { |
371 | #if !defined(QT_NO_COP) | 371 | #if !defined(QT_NO_COP) |
372 | QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); | 372 | QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); |
373 | e << message; | 373 | e << message; |
374 | #endif | 374 | #endif |
375 | } | 375 | } |
376 | 376 | ||
377 | /*! | 377 | /*! |
378 | \internal | 378 | \internal |
379 | */ | 379 | */ |
380 | void Global::applyStyle() | 380 | void Global::applyStyle() |
381 | { | 381 | { |
382 | #if !defined(QT_NO_COP) | 382 | #if !defined(QT_NO_COP) |
383 | QCopChannel::send( "QPE/System", "applyStyle()" ); | 383 | QCopChannel::send( "QPE/System", "applyStyle()" ); |
384 | #else | 384 | #else |
385 | ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version | 385 | ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version |
386 | #endif | 386 | #endif |
387 | } | 387 | } |
388 | 388 | ||
389 | /*! | 389 | /*! |
390 | \internal | 390 | \internal |
391 | */ | 391 | */ |
392 | QWidget *Global::shutdown( bool ) | 392 | QWidget *Global::shutdown( bool ) |
393 | { | 393 | { |
394 | #if !defined(QT_NO_COP) | 394 | #if !defined(QT_NO_COP) |
395 | QCopChannel::send( "QPE/System", "shutdown()" ); | 395 | QCopChannel::send( "QPE/System", "shutdown()" ); |
396 | #endif | 396 | #endif |
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | /*! | 400 | /*! |
401 | \internal | 401 | \internal |
402 | */ | 402 | */ |
403 | QWidget *Global::restart( bool ) | 403 | QWidget *Global::restart( bool ) |
404 | { | 404 | { |
405 | #if !defined(QT_NO_COP) | 405 | #if !defined(QT_NO_COP) |
406 | QCopChannel::send( "QPE/System", "restart()" ); | 406 | QCopChannel::send( "QPE/System", "restart()" ); |
407 | #endif | 407 | #endif |
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
411 | /*! | 411 | /*! |
412 | Explicitly show the current input method. | 412 | Explicitly show the current input method. |
413 | 413 | ||
414 | Input methods are indicated in the taskbar by a small icon. If the | 414 | Input methods are indicated in the taskbar by a small icon. If the |
415 | input method is activated (shown) then it takes up some proportion | 415 | input method is activated (shown) then it takes up some proportion |
416 | of the bottom of the screen, to allow the user to interact (input | 416 | of the bottom of the screen, to allow the user to interact (input |
417 | characters) with it. | 417 | characters) with it. |
418 | 418 | ||
419 | \sa hideInputMethod() | 419 | \sa hideInputMethod() |
420 | */ | 420 | */ |
421 | void Global::showInputMethod() | 421 | void Global::showInputMethod() |
422 | { | 422 | { |
423 | #if !defined(QT_NO_COP) | 423 | #if !defined(QT_NO_COP) |
424 | QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); | 424 | QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); |
425 | #endif | 425 | #endif |
426 | } | 426 | } |
427 | 427 | ||
428 | /*! | 428 | /*! |
429 | Explicitly hide the current input method. | 429 | Explicitly hide the current input method. |
430 | 430 | ||
431 | The current input method is still indicated in the taskbar, but no | 431 | The current input method is still indicated in the taskbar, but no |
432 | longer takes up screen space, and can no longer be interacted with. | 432 | longer takes up screen space, and can no longer be interacted with. |
433 | 433 | ||
434 | \sa showInputMethod() | 434 | \sa showInputMethod() |
435 | */ | 435 | */ |
436 | void Global::hideInputMethod() | 436 | void Global::hideInputMethod() |
437 | { | 437 | { |
438 | #if !defined(QT_NO_COP) | 438 | #if !defined(QT_NO_COP) |
439 | QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); | 439 | QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); |
440 | #endif | 440 | #endif |
441 | } | 441 | } |
442 | 442 | ||
443 | 443 | ||
444 | /*! | 444 | /*! |
445 | \internal | 445 | \internal |
446 | */ | 446 | */ |
447 | bool Global::isBuiltinCommand( const QString &name ) | 447 | bool Global::isBuiltinCommand( const QString &name ) |
448 | { | 448 | { |
449 | if(!builtin) | 449 | if(!builtin) |
450 | return FALSE; // yes, it can happen | 450 | return FALSE; // yes, it can happen |
451 | for (int i = 0; builtin[i].file; i++) { | 451 | for (int i = 0; builtin[i].file; i++) { |
452 | if ( builtin[i].file == name ) { | 452 | if ( builtin[i].file == name ) { |
453 | return TRUE; | 453 | return TRUE; |
454 | } | 454 | } |
455 | } | 455 | } |
456 | return FALSE; | 456 | return FALSE; |
457 | } | 457 | } |
458 | 458 | ||
459 | Global::Command* Global::builtin=0; | 459 | Global::Command* Global::builtin=0; |
460 | QGuardedPtr<QWidget> *Global::running=0; | 460 | QGuardedPtr<QWidget> *Global::running=0; |
461 | 461 | ||
462 | /*! | 462 | /*! |
463 | \class Global::Command | 463 | \class Global::Command |
464 | \brief The Global::Command class is internal. | 464 | \brief The Global::Command class is internal. |
465 | \internal | 465 | \internal |
466 | */ | 466 | */ |
467 | 467 | ||
468 | /*! | 468 | /*! |
469 | \internal | 469 | \internal |
470 | */ | 470 | */ |
471 | void Global::setBuiltinCommands( Command* list ) | 471 | void Global::setBuiltinCommands( Command* list ) |
472 | { | 472 | { |
473 | if ( running ) | 473 | if ( running ) |
474 | delete [] running; | 474 | delete [] running; |
475 | 475 | ||
476 | builtin = list; | 476 | builtin = list; |
477 | int count = 0; | 477 | int count = 0; |
478 | if (!builtin) | 478 | if (!builtin) |
479 | return; | 479 | return; |
480 | while ( builtin[count].file ) | 480 | while ( builtin[count].file ) |
481 | count++; | 481 | count++; |
482 | 482 | ||
483 | running = new QGuardedPtr<QWidget> [ count ]; | 483 | running = new QGuardedPtr<QWidget> [ count ]; |
484 | } | 484 | } |
485 | 485 | ||
486 | /*! | 486 | /*! |
487 | \internal | 487 | \internal |
488 | */ | 488 | */ |
489 | void Global::setDocument( QWidget* receiver, const QString& document ) | 489 | void Global::setDocument( QWidget* receiver, const QString& document ) |
490 | { | 490 | { |
491 | Emitter emitter(receiver,document); | 491 | Emitter emitter(receiver,document); |
492 | } | 492 | } |
493 | 493 | ||
494 | /*! | 494 | /*! |
495 | \internal | 495 | \internal |
496 | */ | 496 | */ |
497 | bool Global::terminateBuiltin( const QString& n ) | 497 | bool Global::terminateBuiltin( const QString& n ) |
498 | { | 498 | { |
499 | if (!builtin) | 499 | if (!builtin) |
500 | return FALSE; | 500 | return FALSE; |
501 | for (int i = 0; builtin[i].file; i++) { | 501 | for (int i = 0; builtin[i].file; i++) { |
502 | if ( builtin[i].file == n ) { | 502 | if ( builtin[i].file == n ) { |
503 | delete running[i]; | 503 | delete running[i]; |
504 | return TRUE; | 504 | return TRUE; |
505 | } | 505 | } |
506 | } | 506 | } |
507 | return FALSE; | 507 | return FALSE; |
508 | } | 508 | } |
509 | 509 | ||
510 | /*! | 510 | /*! |
511 | \internal | 511 | \internal |
512 | */ | 512 | */ |
513 | void Global::terminate( const AppLnk* app ) | 513 | void Global::terminate( const AppLnk* app ) |
514 | { | 514 | { |
515 | //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this | 515 | //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this |
516 | 516 | ||
517 | #ifndef QT_NO_COP | 517 | #ifndef QT_NO_COP |
518 | QCString channel = "QPE/Application/" + app->exec().utf8(); | 518 | QCString channel = "QPE/Application/" + app->exec().utf8(); |
519 | if ( QCopChannel::isRegistered(channel) ) { | 519 | if ( QCopChannel::isRegistered(channel) ) { |
520 | QCopEnvelope e(channel, "quit()"); | 520 | QCopEnvelope e(channel, "quit()"); |
521 | } | 521 | } |
522 | #endif | 522 | #endif |
523 | } | 523 | } |
524 | 524 | ||
525 | /*! | 525 | /*! |
526 | Low-level function to run command \a c. | 526 | Low-level function to run command \a c. |
527 | 527 | ||
528 | \warning Do not use this function. Use execute instead. | 528 | \warning Do not use this function. Use execute instead. |
529 | 529 | ||
530 | \sa execute() | 530 | \sa execute() |
531 | */ | 531 | */ |
532 | void Global::invoke(const QString &c) | 532 | void Global::invoke(const QString &c) |
533 | { | 533 | { |
534 | // Convert the command line in to a list of arguments | 534 | // Convert the command line in to a list of arguments |
535 | QStringList list = QStringList::split(QRegExp(" *"),c); | 535 | QStringList list = QStringList::split(QRegExp(" *"),c); |
536 | 536 | ||
537 | #if !defined(QT_NO_COP) | 537 | #if !defined(QT_NO_COP) |
538 | QString ap=list[0]; | 538 | QString ap=list[0]; |
539 | // see if the application is already running | 539 | // see if the application is already running |
540 | // XXX should lock file /tmp/qcop-msg-ap | 540 | // XXX should lock file /tmp/qcop-msg-ap |
541 | if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { | 541 | if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { |
542 | // If the channel is already register, the app is already running, so show it. | 542 | // If the channel is already register, the app is already running, so show it. |
543 | { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } | 543 | { |
544 | 544 | QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); | |
545 | //QCopEnvelope e("QPE/System", "notBusy(QString)" ); | 545 | } |
546 | //e << ap; | 546 | |
547 | return; | 547 | //QCopEnvelope e("QPE/System", "notBusy(QString)" ); |
548 | //e << ap; | ||
549 | return; | ||
548 | } | 550 | } |
549 | // XXX should unlock file /tmp/qcop-msg-ap | 551 | // XXX should unlock file /tmp/qcop-msg-ap |
550 | //see if it is being started | 552 | //see if it is being started |
551 | if ( StartingAppList::isStarting( ap ) ) { | 553 | if ( StartingAppList::isStarting( ap ) ) { |
552 | // FIXME take it out for now, since it leads to a much to short showing of wait if | 554 | // FIXME take it out for now, since it leads to a much to short showing of wait if |
553 | // some entry is clicked. | 555 | // some entry is clicked. |
554 | // Real cause is that ::execute is called twice for document tab. But it would need some larger changes | 556 | // Real cause is that ::execute is called twice for document tab. But it would need some larger changes |
555 | // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there | 557 | // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there |
556 | // had the idea that an apploader belongs to the launcher ... | 558 | // had the idea that an apploader belongs to the launcher ... |
557 | //QCopEnvelope e("QPE/System", "notBusy(QString)" ); | 559 | //QCopEnvelope e("QPE/System", "notBusy(QString)" ); |
558 | //e << ap; | 560 | //e << ap; |
559 | return; | 561 | return; |
560 | } | 562 | } |
561 | 563 | ||
562 | #endif | 564 | #endif |
563 | 565 | ||
564 | #ifdef QT_NO_QWS_MULTIPROCESS | 566 | #ifdef QT_NO_QWS_MULTIPROCESS |
565 | QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); | 567 | QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); |
566 | #else | 568 | #else |
567 | 569 | ||
568 | QStrList slist; | 570 | QStrList slist; |
569 | unsigned int j; | 571 | unsigned int j; |
570 | for ( j = 0; j < list.count(); j++ ) | 572 | for ( j = 0; j < list.count(); j++ ) |
571 | slist.append( list[j].utf8() ); | 573 | slist.append( list[j].utf8() ); |
572 | 574 | ||
573 | const char **args = new const char *[slist.count() + 1]; | 575 | const char **args = new const char *[slist.count() + 1]; |
574 | for ( j = 0; j < slist.count(); j++ ) | 576 | for ( j = 0; j < slist.count(); j++ ) |
575 | args[j] = slist.at(j); | 577 | args[j] = slist.at(j); |
578 | |||
576 | args[j] = NULL; | 579 | args[j] = NULL; |
577 | 580 | ||
578 | #if !defined(QT_NO_COP) | 581 | #if !defined(QT_NO_COP) |
579 | // an attempt to show a wait... | 582 | // an attempt to show a wait... |
580 | // more logic should be used, but this will be fine for the moment... | 583 | // more logic should be used, but this will be fine for the moment... |
581 | QCopEnvelope ( "QPE/System", "busy()" ); | 584 | QCopEnvelope ( "QPE/System", "busy()" ); |
582 | #endif | 585 | #endif |
583 | 586 | ||
584 | #ifdef HAVE_QUICKEXEC | 587 | #ifdef HAVE_QUICKEXEC |
585 | #ifdef Q_OS_MACX | 588 | #ifdef Q_OS_MACX |
586 | QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; | 589 | QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; |
587 | #else | 590 | #else |
588 | QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; | 591 | QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; |
589 | #endif | 592 | #endif |
590 | qDebug("libfile = %s", libexe.latin1() ); | 593 | qDebug("libfile = %s", libexe.latin1() ); |
591 | if ( QFile::exists( libexe ) ) { | 594 | if ( QFile::exists( libexe ) ) { |
592 | qDebug("calling quickexec %s", libexe.latin1() ); | 595 | qDebug("calling quickexec %s", libexe.latin1() ); |
593 | quickexecv( libexe.utf8().data(), (const char **)args ); | 596 | quickexecv( libexe.utf8().data(), (const char **)args ); |
594 | } else | 597 | } else |
595 | #endif | 598 | #endif |
596 | { | 599 | { |
597 | bool success = false; | 600 | bool success = false; |
598 | int pfd [2]; | 601 | int pfd [2]; |
599 | if ( ::pipe ( pfd ) < 0 ) | 602 | if ( ::pipe ( pfd ) < 0 ) |
600 | pfd [0] = pfd [1] = -1; | 603 | pfd [0] = pfd [1] = -1; |
601 | 604 | ||
602 | pid_t pid = ::fork ( ); | 605 | pid_t pid = ::fork ( ); |
603 | 606 | ||
604 | if ( pid == 0 ) { // child | 607 | if ( pid == 0 ) { // child |
605 | for ( int fd = 3; fd < 100; fd++ ) { | 608 | for ( int fd = 3; fd < 100; fd++ ) { |
606 | if ( fd != pfd [1] ) | 609 | if ( fd != pfd [1] ) |
607 | ::close ( fd ); | 610 | ::close ( fd ); |
608 | } | 611 | } |
609 | ::setpgid ( ::getpid ( ), ::getppid ( )); | 612 | ::setpgid ( ::getpid ( ), ::getppid ( )); |
610 | 613 | ||
611 | // Closing of fd[1] indicates that the execvp succeeded! | 614 | // Closing of fd[1] indicates that the execvp succeeded! |
612 | if ( pfd [1] >= 0 ) | 615 | if ( pfd [1] >= 0 ) |
613 | ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); | 616 | ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); |
614 | 617 | ||
615 | // Try bindir first, so that foo/bar works too | 618 | // Try bindir first, so that foo/bar works too |
616 | ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); | 619 | ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); |
617 | ::execvp ( args [0], (char * const *) args ); | 620 | ::execvp ( args [0], (char * const *) args ); |
618 | 621 | ||
619 | char resultByte = 1; | 622 | char resultByte = 1; |
620 | if ( pfd [1] >= 0 ) | 623 | if ( pfd [1] >= 0 ) |
621 | ::write ( pfd [1], &resultByte, 1 ); | 624 | ::write ( pfd [1], &resultByte, 1 ); |
622 | ::_exit ( -1 ); | 625 | ::_exit ( -1 ); |
623 | } | 626 | } |
624 | else if ( pid > 0 ) { | 627 | else if ( pid > 0 ) { |
625 | success = true; | 628 | success = true; |
626 | 629 | ||
627 | if ( pfd [1] >= 0 ) | 630 | if ( pfd [1] >= 0 ) |
628 | ::close ( pfd [1] ); | 631 | ::close ( pfd [1] ); |
629 | if ( pfd [0] >= 0 ) { | 632 | if ( pfd [0] >= 0 ) { |
630 | while ( true ) { | 633 | while ( true ) { |
631 | char resultByte; | 634 | char resultByte; |
632 | int n = ::read ( pfd [0], &resultByte, 1 ); | 635 | int n = ::read ( pfd [0], &resultByte, 1 ); |
633 | if ( n == 1 ) { | 636 | if ( n == 1 ) { |
634 | success = false; | 637 | success = false; |
635 | break; | 638 | break; |
636 | } | 639 | } |
637 | if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) | 640 | if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) |
638 | continue; | 641 | continue; |
639 | 642 | ||
640 | break; // success | 643 | break; // success |
641 | } | 644 | } |
642 | ::close ( pfd [0] ); | 645 | ::close ( pfd [0] ); |
643 | } | 646 | } |
644 | } | 647 | } |
645 | if ( success ) | 648 | if ( success ) |
646 | StartingAppList::add( list[0] ); | 649 | StartingAppList::add( list[0] ); |
647 | else | 650 | else |
648 | QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); | 651 | QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); |
649 | } | 652 | } |
653 | delete [] args; | ||
650 | #endif //QT_NO_QWS_MULTIPROCESS | 654 | #endif //QT_NO_QWS_MULTIPROCESS |
651 | } | 655 | } |
652 | 656 | ||
653 | 657 | ||
654 | /*! | 658 | /*! |
655 | Executes the application identfied by \a c, passing \a | 659 | Executes the application identfied by \a c, passing \a |
656 | document if it isn't null. | 660 | document if it isn't null. |
657 | 661 | ||
658 | Note that a better approach might be to send a QCop message to the | 662 | Note that a better approach might be to send a QCop message to the |
659 | application's QPE/Application/\e{appname} channel. | 663 | application's QPE/Application/\e{appname} channel. |
660 | */ | 664 | */ |
661 | void Global::execute( const QString &c, const QString& document ) | 665 | void Global::execute( const QString &c, const QString& document ) |
662 | { | 666 | { |
663 | // ask the server to do the work | 667 | // ask the server to do the work |
664 | #if !defined(QT_NO_COP) | 668 | #if !defined(QT_NO_COP) |
665 | if ( document.isNull() ) { | 669 | if ( document.isNull() ) { |
666 | QCopEnvelope e( "QPE/System", "execute(QString)" ); | 670 | QCopEnvelope e( "QPE/System", "execute(QString)" ); |
667 | e << c; | 671 | e << c; |
668 | } else { | 672 | } else { |
669 | QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); | 673 | QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); |
670 | e << c << document; | 674 | e << c << document; |
671 | } | 675 | } |
672 | #endif | 676 | #endif |
673 | return; | 677 | return; |
674 | } | 678 | } |
675 | 679 | ||
676 | /*! | 680 | /*! |
677 | Returns the string \a s with the characters '\', '"', and '$' quoted | 681 | Returns the string \a s with the characters '\', '"', and '$' quoted |
678 | by a preceeding '\'. | 682 | by a preceeding '\'. |
679 | 683 | ||
680 | \sa stringQuote() | 684 | \sa stringQuote() |
681 | */ | 685 | */ |
682 | QString Global::shellQuote(const QString& s) | 686 | QString Global::shellQuote(const QString& s) |
683 | { | 687 | { |
684 | QString r="\""; | 688 | QString r="\""; |
685 | for (int i=0; i<(int)s.length(); i++) { | 689 | for (int i=0; i<(int)s.length(); i++) { |
686 | char c = s[i].latin1(); | 690 | char c = s[i].latin1(); |
687 | switch (c) { | 691 | switch (c) { |
688 | case '\\': case '"': case '$': | 692 | case '\\': case '"': case '$': |
689 | r+="\\"; | 693 | r+="\\"; |
690 | } | 694 | } |
691 | r += s[i]; | 695 | r += s[i]; |
692 | } | 696 | } |
693 | r += "\""; | 697 | r += "\""; |
694 | return r; | 698 | return r; |
695 | } | 699 | } |
696 | 700 | ||
697 | /*! | 701 | /*! |
698 | Returns the string \a s with the characters '\' and '"' quoted by a | 702 | Returns the string \a s with the characters '\' and '"' quoted by a |
699 | preceeding '\'. | 703 | preceeding '\'. |
700 | 704 | ||
701 | \sa shellQuote() | 705 | \sa shellQuote() |
702 | */ | 706 | */ |
703 | QString Global::stringQuote(const QString& s) | 707 | QString Global::stringQuote(const QString& s) |
704 | { | 708 | { |
705 | QString r="\""; | 709 | QString r="\""; |
706 | for (int i=0; i<(int)s.length(); i++) { | 710 | for (int i=0; i<(int)s.length(); i++) { |
707 | char c = s[i].latin1(); | 711 | char c = s[i].latin1(); |
708 | switch (c) { | 712 | switch (c) { |
709 | case '\\': case '"': | 713 | case '\\': case '"': |
710 | r+="\\"; | 714 | r+="\\"; |
711 | } | 715 | } |
712 | r += s[i]; | 716 | r += s[i]; |
713 | } | 717 | } |
714 | r += "\""; | 718 | r += "\""; |
715 | return r; | 719 | return r; |
716 | } | 720 | } |
717 | 721 | ||
718 | /*! | 722 | /*! |
719 | Finds all documents on the system's document directories which | 723 | Finds all documents on the system's document directories which |
720 | match the filter \a mimefilter, and appends the resulting DocLnk | 724 | match the filter \a mimefilter, and appends the resulting DocLnk |
721 | objects to \a folder. | 725 | objects to \a folder. |
722 | */ | 726 | */ |
723 | void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) | 727 | void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) |
724 | { | 728 | { |
725 | QString homedocs = QString(getenv("HOME")) + "/Documents"; | 729 | QString homedocs = QString(getenv("HOME")) + "/Documents"; |
726 | DocLnkSet d(homedocs,mimefilter); | 730 | DocLnkSet d(homedocs,mimefilter); |
727 | folder->appendFrom(d); | 731 | folder->appendFrom(d); |
728 | /** let's do intellegint way of searching these files | 732 | /** let's do intellegint way of searching these files |
729 | * a) the user don't want to check mediums global | 733 | * a) the user don't want to check mediums global |
730 | * b) the user wants to check but use the global options for it | 734 | * b) the user wants to check but use the global options for it |
731 | * c) the user wants to check it but not this medium | 735 | * c) the user wants to check it but not this medium |
732 | * d) the user wants to check and this medium as well | 736 | * d) the user wants to check and this medium as well |
733 | * | 737 | * |
734 | * In all cases we need to apply a different mimefilter to | 738 | * In all cases we need to apply a different mimefilter to |
735 | * the medium. | 739 | * the medium. |
736 | * a) mimefilter.isEmpty() we need to apply the responding filter | 740 | * a) mimefilter.isEmpty() we need to apply the responding filter |
737 | * either the global or the one on the medium | 741 | * either the global or the one on the medium |
738 | * | 742 | * |
739 | * b) mimefilter is set to an application we need to find out if the | 743 | * b) mimefilter is set to an application we need to find out if the |
740 | * mimetypes are included in the mime mask of the medium | 744 | * mimetypes are included in the mime mask of the medium |
741 | */ | 745 | */ |
742 | StorageInfo storage; | 746 | StorageInfo storage; |
743 | const QList<FileSystem> &fs = storage.fileSystems(); | 747 | const QList<FileSystem> &fs = storage.fileSystems(); |
744 | QListIterator<FileSystem> it ( fs ); | 748 | QListIterator<FileSystem> it ( fs ); |
745 | for ( ; it.current(); ++it ) { | 749 | for ( ; it.current(); ++it ) { |
746 | if ( (*it)->isRemovable() ) { // let's find out if we should search on it | 750 | if ( (*it)->isRemovable() ) { // let's find out if we should search on it |
747 | // this is a candidate look at the cf and see if we should search on it | 751 | // this is a candidate look at the cf and see if we should search on it |
748 | QString path = (*it)->path(); | 752 | QString path = (*it)->path(); |
749 | Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); | 753 | Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); |
750 | conf.setGroup("main"); | 754 | conf.setGroup("main"); |
751 | if (!conf.readBoolEntry("check",true)) { | 755 | if (!conf.readBoolEntry("check",true)) { |
752 | continue; | 756 | continue; |
753 | } | 757 | } |
754 | conf.setGroup("subdirs"); | 758 | conf.setGroup("subdirs"); |
755 | if (conf.readBoolEntry("wholemedia",true)) { | 759 | if (conf.readBoolEntry("wholemedia",true)) { |
756 | DocLnkSet ide( path,mimefilter); | 760 | DocLnkSet ide( path,mimefilter); |
757 | folder->appendFrom(ide); | 761 | folder->appendFrom(ide); |
758 | } else { | 762 | } else { |
759 | QStringList subDirs = conf.readListEntry("subdirs",':'); | 763 | QStringList subDirs = conf.readListEntry("subdirs",':'); |
760 | if (subDirs.isEmpty()) { | 764 | if (subDirs.isEmpty()) { |
761 | subDirs.append("Documents"); | 765 | subDirs.append("Documents"); |
762 | } | 766 | } |
763 | for (unsigned c = 0; c < subDirs.count();++c) { | 767 | for (unsigned c = 0; c < subDirs.count();++c) { |
764 | DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); | 768 | DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); |
765 | folder->appendFrom(ide); | 769 | folder->appendFrom(ide); |
766 | } | 770 | } |
767 | } | 771 | } |
768 | } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { | 772 | } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { |
769 | QString path = (*it)->path() + "/Documents"; | 773 | QString path = (*it)->path() + "/Documents"; |
770 | DocLnkSet ide( path, mimefilter ); | 774 | DocLnkSet ide( path, mimefilter ); |
771 | folder->appendFrom(ide); | 775 | folder->appendFrom(ide); |
772 | } | 776 | } |
773 | } | 777 | } |
774 | } | 778 | } |
775 | 779 | ||
776 | QStringList Global::languageList() | 780 | QStringList Global::languageList() |
777 | { | 781 | { |
778 | QString lang = getenv("LANG"); | 782 | QString lang = getenv("LANG"); |
779 | QStringList langs; | 783 | QStringList langs; |
780 | langs.append(lang); | 784 | langs.append(lang); |
781 | int i = lang.find("."); | 785 | int i = lang.find("."); |
782 | if ( i > 0 ) | 786 | if ( i > 0 ) |
783 | lang = lang.left( i ); | 787 | lang = lang.left( i ); |
784 | i = lang.find( "_" ); | 788 | i = lang.find( "_" ); |
785 | if ( i > 0 ) | 789 | if ( i > 0 ) |
786 | langs.append(lang.left(i)); | 790 | langs.append(lang.left(i)); |
787 | return langs; | 791 | return langs; |
788 | } | 792 | } |
789 | 793 | ||
790 | QStringList Global::helpPath() | 794 | QStringList Global::helpPath() |
791 | { | 795 | { |
792 | QString qpeDir = QPEApplication::qpeDir(); | 796 | QString qpeDir = QPEApplication::qpeDir(); |
793 | QStringList path; | 797 | QStringList path; |
794 | QStringList langs = Global::languageList(); | 798 | QStringList langs = Global::languageList(); |
795 | for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { | 799 | for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { |
796 | QString lang = *it; | 800 | QString lang = *it; |
797 | if ( !lang.isEmpty() ) | 801 | if ( !lang.isEmpty() ) |
798 | path += qpeDir + "/help/" + lang + "/html"; | 802 | path += qpeDir + "/help/" + lang + "/html"; |
799 | } | 803 | } |
800 | path += qpeDir + "/pics"; | 804 | path += qpeDir + "/pics"; |
801 | path += qpeDir + "/help/html"; | 805 | path += qpeDir + "/help/html"; |
802 | /* we even put english into the en dir so try it as fallback as well for opie */ | 806 | /* we even put english into the en dir so try it as fallback as well for opie */ |
803 | path += qpeDir + "/help/en/html"; | 807 | path += qpeDir + "/help/en/html"; |
804 | path += qpeDir + "/docs"; | 808 | path += qpeDir + "/docs"; |
805 | 809 | ||
806 | 810 | ||
807 | return path; | 811 | return path; |
808 | } | 812 | } |
809 | 813 | ||
810 | /*! | 814 | /*! |
811 | \internal | 815 | \internal |
812 | Truncate file to size specified | 816 | Truncate file to size specified |
813 | \a f must be an open file | 817 | \a f must be an open file |
814 | \a size must be a positive value | 818 | \a size must be a positive value |
815 | */ | 819 | */ |
816 | bool Global::truncateFile(QFile &f, int size){ | 820 | bool Global::truncateFile(QFile &f, int size){ |
817 | if (!f.isOpen()) | 821 | if (!f.isOpen()) |
818 | return FALSE; | 822 | return FALSE; |
819 | 823 | ||
820 | return ::ftruncate(f.handle(), size) != -1; | 824 | return ::ftruncate(f.handle(), size) != -1; |
821 | } | 825 | } |
822 | 826 | ||
823 | 827 | ||
824 | 828 | ||
825 | 829 | ||
826 | // #if defined(Q_OS_UNIX) && defined(Q_WS_QWS) | 830 | // #if defined(Q_OS_UNIX) && defined(Q_WS_QWS) |
827 | // extern int qws_display_id; | 831 | // extern int qws_display_id; |
828 | // #endif | 832 | // #endif |
829 | 833 | ||
830 | /*! | 834 | /*! |
831 | /internal | 835 | /internal |
832 | Returns the default system path for storing temporary files. | 836 | Returns the default system path for storing temporary files. |
833 | Note: This does not it ensure that the provided directory exists | 837 | Note: This does not it ensure that the provided directory exists |
834 | */ | 838 | */ |
835 | QString Global::tempDir() | 839 | QString Global::tempDir() |
836 | { | 840 | { |
837 | QString result; | 841 | QString result; |
838 | #ifdef Q_OS_UNIX | 842 | #ifdef Q_OS_UNIX |
839 | #ifdef Q_WS_QWS | 843 | #ifdef Q_WS_QWS |
840 | result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id)); | 844 | result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id)); |
841 | #else | 845 | #else |
842 | result="/tmp/"; | 846 | result="/tmp/"; |
843 | #endif | 847 | #endif |
844 | #else | 848 | #else |
845 | if (getenv("TEMP")) | 849 | if (getenv("TEMP")) |
846 | result = getenv("TEMP"); | 850 | result = getenv("TEMP"); |
847 | else | 851 | else |
848 | result = getenv("TMP"); | 852 | result = getenv("TMP"); |
849 | 853 | ||
850 | if (result[(int)result.length() - 1] != QDir::separator()) | 854 | if (result[(int)result.length() - 1] != QDir::separator()) |
851 | result.append(QDir::separator()); | 855 | result.append(QDir::separator()); |
852 | #endif | 856 | #endif |
853 | 857 | ||
854 | return result; | 858 | return result; |
855 | } | 859 | } |
856 | 860 | ||
857 | //#endif | 861 | //#endif |
858 | 862 | ||
859 | 863 | ||
860 | #include "global.moc" | 864 | #include "global.moc" |
diff --git a/noncore/apps/opie-reader/Bkmks.cpp b/noncore/apps/opie-reader/Bkmks.cpp index 00141a3..45aa045 100644 --- a/noncore/apps/opie-reader/Bkmks.cpp +++ b/noncore/apps/opie-reader/Bkmks.cpp | |||
@@ -1,416 +1,417 @@ | |||
1 | #include <qmessagebox.h> | 1 | #include <qmessagebox.h> |
2 | 2 | ||
3 | #include "Bkmks.h" | 3 | #include "Bkmks.h" |
4 | 4 | ||
5 | #include "StyleConsts.h" | 5 | #include "StyleConsts.h" |
6 | #include "Markups.h" | 6 | #include "Markups.h" |
7 | #include "my_list.h" | 7 | #include "my_list.h" |
8 | #include "version.h" | 8 | #include "version.h" |
9 | #include "names.h" | 9 | #include "names.h" |
10 | 10 | ||
11 | const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); | 11 | const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); |
12 | 12 | ||
13 | Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : | 13 | Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : |
14 | m_name(0), | 14 | m_name(0), |
15 | m_namelen(0), | 15 | m_namelen(0), |
16 | m_anno(0), | 16 | m_anno(0), |
17 | m_annolen(0), | 17 | m_annolen(0), |
18 | m_position(0) | 18 | m_position(0) |
19 | { | 19 | { |
20 | init(_nm, _nmlen, _anno, _annolen, _p); | 20 | init(_nm, _nmlen, _anno, _annolen, _p); |
21 | } | 21 | } |
22 | 22 | ||
23 | Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) | 23 | Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) |
24 | { | 24 | { |
25 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p); | 25 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p); |
26 | } | 26 | } |
27 | 27 | ||
28 | Bkmk::Bkmk(const Bkmk& rhs) : | 28 | Bkmk::Bkmk(const Bkmk& rhs) : |
29 | m_name(0), | 29 | m_name(0), |
30 | m_namelen(0), | 30 | m_namelen(0), |
31 | m_anno(0), | 31 | m_anno(0), |
32 | m_annolen(0), | 32 | m_annolen(0), |
33 | m_position(0) | 33 | m_position(0) |
34 | { | 34 | { |
35 | init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(), | 35 | init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(), |
36 | sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value()); | 36 | sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value()); |
37 | } | 37 | } |
38 | 38 | ||
39 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) | 39 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) |
40 | { | 40 | { |
41 | if (_anno == NULL) | 41 | if (_anno == NULL) |
42 | { | 42 | { |
43 | tchar t = 0; | 43 | tchar t = 0; |
44 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); | 44 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); |
45 | } | 45 | } |
46 | else | 46 | else |
47 | { | 47 | { |
48 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); | 48 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) | 52 | Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) |
53 | { | 53 | { |
54 | if (_anno == NULL) | 54 | if (_anno == NULL) |
55 | { | 55 | { |
56 | tchar t = 0; | 56 | tchar t = 0; |
57 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); | 57 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); |
58 | } | 58 | } |
59 | else | 59 | else |
60 | { | 60 | { |
61 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); | 61 | init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); |
62 | } | 62 | } |
63 | m_position2 = _p2; | 63 | m_position2 = _p2; |
64 | m_red = m_green = m_blue = 127; | 64 | m_red = m_green = m_blue = 127; |
65 | } | 65 | } |
66 | 66 | ||
67 | void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) | 67 | void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) |
68 | { | 68 | { |
69 | m_namelen = _nmlen; | 69 | m_namelen = _nmlen; |
70 | if (m_namelen > 0) | 70 | if (m_namelen > 0) |
71 | { | 71 | { |
72 | m_name = new unsigned char[m_namelen]; | 72 | m_name = new unsigned char[m_namelen]; |
73 | memcpy(m_name, _nm, m_namelen); | 73 | memcpy(m_name, _nm, m_namelen); |
74 | } | 74 | } |
75 | else | 75 | else |
76 | { | 76 | { |
77 | m_name = NULL; | 77 | m_name = NULL; |
78 | } | 78 | } |
79 | 79 | ||
80 | m_annolen = _annolen; | 80 | m_annolen = _annolen; |
81 | if (m_annolen > 0) | 81 | if (m_annolen > 0) |
82 | { | 82 | { |
83 | m_anno = new unsigned char[m_annolen]; | 83 | m_anno = new unsigned char[m_annolen]; |
84 | memcpy(m_anno, _anno, m_annolen); | 84 | memcpy(m_anno, _anno, m_annolen); |
85 | } | 85 | } |
86 | else | 86 | else |
87 | { | 87 | { |
88 | m_anno = NULL; | 88 | m_anno = NULL; |
89 | } | 89 | } |
90 | m_position = _p; | 90 | m_position = _p; |
91 | m_position2 = _p; | 91 | m_position2 = _p; |
92 | m_red = m_green = m_blue = 255; | 92 | m_red = m_green = m_blue = 255; |
93 | m_level = 0; | 93 | m_level = 0; |
94 | } | 94 | } |
95 | 95 | ||
96 | Bkmk::~Bkmk() | 96 | Bkmk::~Bkmk() |
97 | { | 97 | { |
98 | if (m_name != NULL) delete [] m_name; | 98 | if (m_name != NULL) delete [] m_name; |
99 | m_name = NULL; | 99 | m_name = NULL; |
100 | if (m_anno != NULL) delete [] m_anno; | 100 | if (m_anno != NULL) delete [] m_anno; |
101 | m_anno = NULL; | 101 | m_anno = NULL; |
102 | } | 102 | } |
103 | 103 | ||
104 | Bkmk& Bkmk::operator=(const Bkmk& rhs) | 104 | Bkmk& Bkmk::operator=(const Bkmk& rhs) |
105 | { | 105 | { |
106 | if (m_name != NULL) | 106 | if (m_name != NULL) |
107 | { | 107 | { |
108 | delete [] m_name; | 108 | delete [] m_name; |
109 | m_name = NULL; | 109 | m_name = NULL; |
110 | } | 110 | } |
111 | if (m_anno != NULL) | 111 | if (m_anno != NULL) |
112 | { | 112 | { |
113 | delete [] m_anno; | 113 | delete [] m_anno; |
114 | m_anno = NULL; | 114 | m_anno = NULL; |
115 | } | 115 | } |
116 | if (rhs.m_name != NULL) | 116 | if (rhs.m_name != NULL) |
117 | { | 117 | { |
118 | m_namelen = rhs.m_namelen; | 118 | m_namelen = rhs.m_namelen; |
119 | m_name = new unsigned char[m_namelen]; | 119 | m_name = new unsigned char[m_namelen]; |
120 | memcpy(m_name, rhs.m_name, m_namelen); | 120 | memcpy(m_name, rhs.m_name, m_namelen); |
121 | } | 121 | } |
122 | else | 122 | else |
123 | m_name = NULL; | 123 | m_name = NULL; |
124 | if (rhs.m_anno != NULL) | 124 | if (rhs.m_anno != NULL) |
125 | { | 125 | { |
126 | m_annolen = rhs.m_annolen; | 126 | m_annolen = rhs.m_annolen; |
127 | m_anno = new unsigned char[m_annolen]; | 127 | m_anno = new unsigned char[m_annolen]; |
128 | memcpy(m_anno, rhs.m_anno, m_annolen); | 128 | memcpy(m_anno, rhs.m_anno, m_annolen); |
129 | } | 129 | } |
130 | else | 130 | else |
131 | m_anno = NULL; | 131 | m_anno = NULL; |
132 | m_position = rhs.m_position; | 132 | m_position = rhs.m_position; |
133 | m_position2 = rhs.m_position2; | 133 | m_position2 = rhs.m_position2; |
134 | m_red = rhs.m_red; | 134 | m_red = rhs.m_red; |
135 | m_green = rhs.m_green; | 135 | m_green = rhs.m_green; |
136 | m_blue = rhs.m_blue; | 136 | m_blue = rhs.m_blue; |
137 | m_level = rhs.m_level; | 137 | m_level = rhs.m_level; |
138 | return *this; | 138 | return *this; |
139 | } | 139 | } |
140 | 140 | ||
141 | bool Bkmk::operator==(const Bkmk& rhs) | 141 | bool Bkmk::operator==(const Bkmk& rhs) |
142 | { | 142 | { |
143 | return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0); | 143 | return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0); |
144 | } | 144 | } |
145 | 145 | ||
146 | void Bkmk::setAnno(unsigned char* t, unsigned short len) | 146 | void Bkmk::setAnno(unsigned char* t, unsigned short len) |
147 | { | 147 | { |
148 | if (m_anno != NULL) | 148 | if (m_anno != NULL) |
149 | { | 149 | { |
150 | delete [] m_anno; | 150 | delete [] m_anno; |
151 | m_anno = NULL; | 151 | m_anno = NULL; |
152 | } | 152 | } |
153 | if (t != NULL) | 153 | if (t != NULL) |
154 | { | 154 | { |
155 | m_annolen = len; | 155 | m_annolen = len; |
156 | m_anno = new unsigned char[m_annolen]; | 156 | m_anno = new unsigned char[m_annolen]; |
157 | memcpy(m_anno, t, m_annolen); | 157 | memcpy(m_anno, t, m_annolen); |
158 | } | 158 | } |
159 | else | 159 | else |
160 | { | 160 | { |
161 | m_annolen = sizeof(tchar); | 161 | m_annolen = sizeof(tchar); |
162 | m_anno = new unsigned char[m_annolen]; | 162 | m_anno = new unsigned char[m_annolen]; |
163 | *((tchar*)m_anno) = 0; | 163 | *((tchar*)m_anno) = 0; |
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
167 | void Bkmk::setAnno(tchar* t) | 167 | void Bkmk::setAnno(tchar* t) |
168 | { | 168 | { |
169 | if (m_anno != NULL) | 169 | if (m_anno != NULL) |
170 | { | 170 | { |
171 | delete [] m_anno; | 171 | delete [] m_anno; |
172 | m_anno = NULL; | 172 | m_anno = NULL; |
173 | } | 173 | } |
174 | if (t != NULL) | 174 | if (t != NULL) |
175 | { | 175 | { |
176 | unsigned short len = ustrlen(t)+1; | 176 | unsigned short len = ustrlen(t)+1; |
177 | m_annolen = sizeof(tchar)*len; | 177 | m_annolen = sizeof(tchar)*len; |
178 | m_anno = new unsigned char[m_annolen]; | 178 | m_anno = new unsigned char[m_annolen]; |
179 | memcpy(m_anno, t, m_annolen); | 179 | memcpy(m_anno, t, m_annolen); |
180 | } | 180 | } |
181 | else | 181 | else |
182 | { | 182 | { |
183 | m_annolen = sizeof(tchar); | 183 | m_annolen = sizeof(tchar); |
184 | m_anno = new unsigned char[m_annolen]; | 184 | m_anno = new unsigned char[m_annolen]; |
185 | *((tchar*)m_anno) = 0; | 185 | *((tchar*)m_anno) = 0; |
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) | 189 | BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) |
190 | : | 190 | : |
191 | wt(w), isUpgraded(false), m_extras(_x) | 191 | wt(w), isUpgraded(false), m_extras(_x) |
192 | { | 192 | { |
193 | if (w) | 193 | if (w) |
194 | { | 194 | { |
195 | f = fopen(fnm, "wb"); | 195 | f = fopen(fnm, "wb"); |
196 | } | 196 | } |
197 | else | 197 | else |
198 | { | 198 | { |
199 | f = fopen(fnm, "rb"); | 199 | f = fopen(fnm, "rb"); |
200 | } | 200 | } |
201 | } | 201 | } |
202 | 202 | ||
203 | BkmkFile::~BkmkFile() | 203 | BkmkFile::~BkmkFile() |
204 | { | 204 | { |
205 | if (f != NULL) fclose(f); | 205 | if (f != NULL) fclose(f); |
206 | } | 206 | } |
207 | 207 | ||
208 | void BkmkFile::write(const Bkmk& b) | 208 | void BkmkFile::write(const Bkmk& b) |
209 | { | 209 | { |
210 | if (f != NULL) | 210 | if (f != NULL) |
211 | { | 211 | { |
212 | fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f); | 212 | fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f); |
213 | fwrite(b.m_name,1,b.m_namelen,f); | 213 | fwrite(b.m_name,1,b.m_namelen,f); |
214 | fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f); | 214 | fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f); |
215 | fwrite(b.m_anno,1,b.m_annolen,f); | 215 | fwrite(b.m_anno,1,b.m_annolen,f); |
216 | fwrite(&b.m_position,sizeof(b.m_position),1,f); | 216 | fwrite(&b.m_position,sizeof(b.m_position),1,f); |
217 | if (m_extras) | 217 | if (m_extras) |
218 | { | 218 | { |
219 | fwrite(&b.m_position2,sizeof(b.m_position2),1,f); | 219 | fwrite(&b.m_position2,sizeof(b.m_position2),1,f); |
220 | fwrite(&b.m_red,sizeof(b.m_red),1,f); | 220 | fwrite(&b.m_red,sizeof(b.m_red),1,f); |
221 | fwrite(&b.m_green,sizeof(b.m_green),1,f); | 221 | fwrite(&b.m_green,sizeof(b.m_green),1,f); |
222 | fwrite(&b.m_blue,sizeof(b.m_blue),1,f); | 222 | fwrite(&b.m_blue,sizeof(b.m_blue),1,f); |
223 | fwrite(&b.m_level,sizeof(b.m_level),1,f); | 223 | fwrite(&b.m_level,sizeof(b.m_level),1,f); |
224 | } | 224 | } |
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | void BkmkFile::write(CList<Bkmk>& bl) | 228 | void BkmkFile::write(CList<Bkmk>& bl) |
229 | { | 229 | { |
230 | if (f != NULL) | 230 | if (f != NULL) |
231 | { | 231 | { |
232 | fwrite(&magic, sizeof(magic), 1, f); | 232 | fwrite(&magic, sizeof(magic), 1, f); |
233 | for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++) | 233 | for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++) |
234 | { | 234 | { |
235 | write(*i); | 235 | write(*i); |
236 | } | 236 | } |
237 | } | 237 | } |
238 | } | 238 | } |
239 | 239 | ||
240 | CList<Bkmk>* BkmkFile::readall() | 240 | CList<Bkmk>* BkmkFile::readall() |
241 | { | 241 | { |
242 | CList<Bkmk>* bl = NULL; | 242 | CList<Bkmk>* bl = NULL; |
243 | if (f != NULL) | 243 | if (f != NULL) |
244 | { | 244 | { |
245 | unsigned long newmagic; | 245 | unsigned long newmagic; |
246 | fread(&newmagic, sizeof(newmagic), 1, f); | 246 | fread(&newmagic, sizeof(newmagic), 1, f); |
247 | if ((newmagic & 0xffffff00) != (magic & 0xffffff00)) | 247 | if ((newmagic & 0xffffff00) != (magic & 0xffffff00)) |
248 | { | 248 | { |
249 | if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0) | 249 | if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0) |
250 | { | 250 | { |
251 | fseek(f,0,SEEK_SET); | 251 | fseek(f,0,SEEK_SET); |
252 | bl = readall00(&read05); | 252 | bl = readall00(&read05); |
253 | } | 253 | } |
254 | else | 254 | else |
255 | { | 255 | { |
256 | fseek(f,0,SEEK_SET); | 256 | fseek(f,0,SEEK_SET); |
257 | bl = readall00(&read03); | 257 | bl = readall00(&read03); |
258 | } | 258 | } |
259 | isUpgraded = true; | 259 | isUpgraded = true; |
260 | } | 260 | } |
261 | else | 261 | else |
262 | { | 262 | { |
263 | switch(newmagic & 0xff) | 263 | switch(newmagic & 0xff) |
264 | { | 264 | { |
265 | case 7: | 265 | case 7: |
266 | isUpgraded = false; | 266 | isUpgraded = false; |
267 | bl = readall00(read07); | 267 | bl = readall00(read07); |
268 | // qDebug("Correct version!"); | 268 | // qDebug("Correct version!"); |
269 | break; | 269 | break; |
270 | case 6: | 270 | case 6: |
271 | isUpgraded = true; | 271 | isUpgraded = true; |
272 | bl = readall00(read06); | 272 | bl = readall00(read06); |
273 | // qDebug("Correct version!"); | 273 | // qDebug("Correct version!"); |
274 | break; | 274 | break; |
275 | case 5: | 275 | case 5: |
276 | isUpgraded = true; | 276 | isUpgraded = true; |
277 | bl = readall00(read05); | 277 | bl = readall00(read05); |
278 | // qDebug("Known version!"); | 278 | // qDebug("Known version!"); |
279 | break; | 279 | break; |
280 | default: | 280 | default: |
281 | // qDebug("Unknown version!"); | 281 | // qDebug("Unknown version!"); |
282 | isUpgraded = true; | 282 | isUpgraded = true; |
283 | bl = readall00(read05); | 283 | bl = readall00(read05); |
284 | } | 284 | } |
285 | } | 285 | } |
286 | } | 286 | } |
287 | return bl; | 287 | return bl; |
288 | } | 288 | } |
289 | 289 | ||
290 | CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) | 290 | CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) |
291 | { | 291 | { |
292 | CList<Bkmk>* bl = new CList<Bkmk>; | 292 | CList<Bkmk>* bl = new CList<Bkmk>; |
293 | while (1) | 293 | while (1) |
294 | { | 294 | { |
295 | Bkmk* b = (*readfn)(this, f); | 295 | Bkmk* b = (*readfn)(this, f); |
296 | if (b == NULL) break; | 296 | if (b == NULL) break; |
297 | bl->push_back(*b); | 297 | bl->push_back(*b); |
298 | delete b; | 298 | delete b; |
299 | } | 299 | } |
300 | return bl; | 300 | return bl; |
301 | } | 301 | } |
302 | 302 | ||
303 | Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) | 303 | Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) |
304 | { | 304 | { |
305 | Bkmk* b = NULL; | 305 | Bkmk* b = NULL; |
306 | if (f != NULL) | 306 | if (f != NULL) |
307 | { | 307 | { |
308 | unsigned short ln; | 308 | unsigned short ln; |
309 | if (fread(&ln,sizeof(ln),1,f) == 1) | 309 | if (fread(&ln,sizeof(ln),1,f) == 1) |
310 | { | 310 | { |
311 | tchar* name = new tchar[ln+1]; | 311 | tchar* name = new tchar[ln+1]; |
312 | fread(name,sizeof(tchar),ln,f); | 312 | fread(name,sizeof(tchar),ln,f); |
313 | name[ln] = 0; | 313 | name[ln] = 0; |
314 | 314 | ||
315 | ln = 0; | 315 | ln = 0; |
316 | tchar* anno = new tchar[ln+1]; | 316 | tchar* anno = new tchar[ln+1]; |
317 | anno[ln] = 0; | 317 | anno[ln] = 0; |
318 | 318 | ||
319 | unsigned int pos; | 319 | unsigned int pos; |
320 | fread(&pos,sizeof(pos),1,f); | 320 | fread(&pos,sizeof(pos),1,f); |
321 | b = new Bkmk(name,anno,pos); | 321 | b = new Bkmk(name,anno,pos); |
322 | delete [] anno; | 322 | delete [] anno; |
323 | } | 323 | } |
324 | } | 324 | } |
325 | return b; | 325 | return b; |
326 | } | 326 | } |
327 | 327 | ||
328 | Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) | 328 | Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) |
329 | { | 329 | { |
330 | Bkmk* b = NULL; | 330 | Bkmk* b = NULL; |
331 | if (f != NULL) | 331 | if (f != NULL) |
332 | { | 332 | { |
333 | unsigned short ln; | 333 | unsigned short ln; |
334 | if (fread(&ln,sizeof(ln),1,f) == 1) | 334 | if (fread(&ln,sizeof(ln),1,f) == 1) |
335 | { | 335 | { |
336 | tchar* nm = new tchar[ln+1]; | 336 | tchar* nm = new tchar[ln+1]; |
337 | fread(nm,sizeof(tchar),ln,f); | 337 | fread(nm,sizeof(tchar),ln,f); |
338 | nm[ln] = 0; | 338 | nm[ln] = 0; |
339 | fread(&ln,sizeof(ln),1,f); | 339 | fread(&ln,sizeof(ln),1,f); |
340 | tchar* anno = new tchar[ln+1]; | 340 | tchar* anno = new tchar[ln+1]; |
341 | if (ln > 0) fread(anno,sizeof(tchar),ln,f); | 341 | if (ln > 0) fread(anno,sizeof(tchar),ln,f); |
342 | anno[ln] = 0; | 342 | anno[ln] = 0; |
343 | unsigned int pos; | 343 | unsigned int pos; |
344 | fread(&pos,sizeof(pos),1,f); | 344 | fread(&pos,sizeof(pos),1,f); |
345 | b = new Bkmk(nm,anno,pos); | 345 | b = new Bkmk(nm,anno,pos); |
346 | delete [] anno; | ||
346 | } | 347 | } |
347 | } | 348 | } |
348 | return b; | 349 | return b; |
349 | } | 350 | } |
350 | 351 | ||
351 | Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) | 352 | Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) |
352 | { | 353 | { |
353 | Bkmk* b = NULL; | 354 | Bkmk* b = NULL; |
354 | if (f != NULL) | 355 | if (f != NULL) |
355 | { | 356 | { |
356 | unsigned short ln; | 357 | unsigned short ln; |
357 | if (fread(&ln,sizeof(ln),1,f) == 1) | 358 | if (fread(&ln,sizeof(ln),1,f) == 1) |
358 | { | 359 | { |
359 | b = new Bkmk; | 360 | b = new Bkmk; |
360 | b->m_namelen = ln; | 361 | b->m_namelen = ln; |
361 | b->m_name = new unsigned char[b->m_namelen]; | 362 | b->m_name = new unsigned char[b->m_namelen]; |
362 | fread(b->m_name,1,b->m_namelen,f); | 363 | fread(b->m_name,1,b->m_namelen,f); |
363 | 364 | ||
364 | fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); | 365 | fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); |
365 | if (b->m_annolen > 0) | 366 | if (b->m_annolen > 0) |
366 | { | 367 | { |
367 | b->m_anno = new unsigned char[b->m_annolen]; | 368 | b->m_anno = new unsigned char[b->m_annolen]; |
368 | fread(b->m_anno,1,b->m_annolen,f); | 369 | fread(b->m_anno,1,b->m_annolen,f); |
369 | } | 370 | } |
370 | fread(&(b->m_position),sizeof(b->m_position),1,f); | 371 | fread(&(b->m_position),sizeof(b->m_position),1,f); |
371 | b->m_position2 = b->m_position+b->m_namelen-1; | 372 | b->m_position2 = b->m_position+b->m_namelen-1; |
372 | b->m_red = b->m_green = b->m_blue = 127; | 373 | b->m_red = b->m_green = b->m_blue = 127; |
373 | b->m_level = 0; | 374 | b->m_level = 0; |
374 | } | 375 | } |
375 | } | 376 | } |
376 | return b; | 377 | return b; |
377 | } | 378 | } |
378 | 379 | ||
379 | Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) | 380 | Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) |
380 | { | 381 | { |
381 | Bkmk* b = NULL; | 382 | Bkmk* b = NULL; |
382 | if (f != NULL) | 383 | if (f != NULL) |
383 | { | 384 | { |
384 | unsigned short ln; | 385 | unsigned short ln; |
385 | if (fread(&ln,sizeof(ln),1,f) == 1) | 386 | if (fread(&ln,sizeof(ln),1,f) == 1) |
386 | { | 387 | { |
387 | b = new Bkmk; | 388 | b = new Bkmk; |
388 | b->m_namelen = ln; | 389 | b->m_namelen = ln; |
389 | b->m_name = new unsigned char[b->m_namelen]; | 390 | b->m_name = new unsigned char[b->m_namelen]; |
390 | fread(b->m_name,1,b->m_namelen,f); | 391 | fread(b->m_name,1,b->m_namelen,f); |
391 | 392 | ||
392 | fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); | 393 | fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); |
393 | if (b->m_annolen > 0) | 394 | if (b->m_annolen > 0) |
394 | { | 395 | { |
395 | b->m_anno = new unsigned char[b->m_annolen]; | 396 | b->m_anno = new unsigned char[b->m_annolen]; |
396 | fread(b->m_anno,1,b->m_annolen,f); | 397 | fread(b->m_anno,1,b->m_annolen,f); |
397 | } | 398 | } |
398 | fread(&(b->m_position),sizeof(b->m_position),1,f); | 399 | fread(&(b->m_position),sizeof(b->m_position),1,f); |
399 | if (_this->m_extras) | 400 | if (_this->m_extras) |
400 | { | 401 | { |
401 | fread(&(b->m_position2),sizeof(b->m_position2),1,f); | 402 | fread(&(b->m_position2),sizeof(b->m_position2),1,f); |
402 | fread(&(b->m_red),sizeof(b->m_red),1,f); | 403 | fread(&(b->m_red),sizeof(b->m_red),1,f); |
403 | fread(&(b->m_green),sizeof(b->m_green),1,f); | 404 | fread(&(b->m_green),sizeof(b->m_green),1,f); |
404 | fread(&(b->m_blue),sizeof(b->m_blue),1,f); | 405 | fread(&(b->m_blue),sizeof(b->m_blue),1,f); |
405 | fread(&(b->m_level),sizeof(b->m_level),1,f); | 406 | fread(&(b->m_level),sizeof(b->m_level),1,f); |
406 | } | 407 | } |
407 | else | 408 | else |
408 | { | 409 | { |
409 | b->m_position2 = b->m_position; | 410 | b->m_position2 = b->m_position; |
410 | b->m_red = b->m_green = b->m_blue = 255; | 411 | b->m_red = b->m_green = b->m_blue = 255; |
411 | b->m_level = 0; | 412 | b->m_level = 0; |
412 | } | 413 | } |
413 | } | 414 | } |
414 | } | 415 | } |
415 | return b; | 416 | return b; |
416 | } | 417 | } |
diff --git a/noncore/apps/opie-sheet/Excel.cpp b/noncore/apps/opie-sheet/Excel.cpp index 51fe707..27080e9 100644 --- a/noncore/apps/opie-sheet/Excel.cpp +++ b/noncore/apps/opie-sheet/Excel.cpp | |||
@@ -1,764 +1,766 @@ | |||
1 | /* | 1 | /* |
2 | =. This file is part of the Opie Project | 2 | =. This file is part of the Opie Project |
3 | .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> | 3 | .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> |
4 | .>+-= | 4 | .>+-= |
5 | _;:, .> :=|. This program is free software; you can | 5 | _;:, .> :=|. This program is free software; you can |
6 | .> <`_, > . <= redistribute it and/or modify it under | 6 | .> <`_, > . <= redistribute it and/or modify it under |
7 | :`=1 )Y*s>-.-- : the terms of the GNU General Public | 7 | :`=1 )Y*s>-.-- : the terms of the GNU General Public |
8 | .="- .-=="i, .._ License as published by the Free Software | 8 | .="- .-=="i, .._ License as published by the Free Software |
9 | - . .-<_> .<> Foundation; either version 2 of the License, | 9 | - . .-<_> .<> Foundation; either version 2 of the License, |
10 | ._= =} : or (at your option) any later version. | 10 | ._= =} : or (at your option) any later version. |
11 | .%`+i> _;_. | 11 | .%`+i> _;_. |
12 | .i_,=:_. -<s. This program is distributed in the hope that | 12 | .i_,=:_. -<s. This program is distributed in the hope that |
13 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 13 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
14 | : .. .:, . . . without even the implied warranty of | 14 | : .. .:, . . . without even the implied warranty of |
15 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 15 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
16 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 16 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
17 | ..}^=.= = ; Library General Public License for more | 17 | ..}^=.= = ; Library General Public License for more |
18 | ++= -. .` .: details. | 18 | ++= -. .` .: details. |
19 | : = ...= . :.=- | 19 | : = ...= . :.=- |
20 | -. .:....=;==+<; You should have received a copy of the GNU | 20 | -. .:....=;==+<; You should have received a copy of the GNU |
21 | -_. . . )=. = Library General Public License along with | 21 | -_. . . )=. = Library General Public License along with |
22 | -- :-=` this library; see the file COPYING.LIB. | 22 | -- :-=` this library; see the file COPYING.LIB. |
23 | If not, write to the Free Software Foundation, | 23 | If not, write to the Free Software Foundation, |
24 | Inc., 59 Temple Place - Suite 330, | 24 | Inc., 59 Temple Place - Suite 330, |
25 | Boston, MA 02111-1307, USA. | 25 | Boston, MA 02111-1307, USA. |
26 | 26 | ||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include "Excel.h" | 29 | #include "Excel.h" |
30 | 30 | ||
31 | /* STD */ | 31 | /* STD */ |
32 | #include <stdio.h> | 32 | #include <stdio.h> |
33 | #include <stdlib.h> | 33 | #include <stdlib.h> |
34 | #include <math.h> | 34 | #include <math.h> |
35 | #include <time.h> | 35 | #include <time.h> |
36 | #include <sys/types.h> | 36 | #include <sys/types.h> |
37 | #include <strings.h> | 37 | #include <strings.h> |
38 | 38 | ||
39 | static xfrecord formatter[] = { | 39 | static xfrecord formatter[] = { |
40 | { 0xe , DATEFORMAT, "%m/%d/%y"}, | 40 | { 0xe , DATEFORMAT, "%m/%d/%y"}, |
41 | { 0xf , DATEFORMAT, "%d-%b-%y"}, | 41 | { 0xf , DATEFORMAT, "%d-%b-%y"}, |
42 | { 0x10, DATEFORMAT, "%d-%b"}, | 42 | { 0x10, DATEFORMAT, "%d-%b"}, |
43 | { 0x11, DATEFORMAT, "%b-%y"}, | 43 | { 0x11, DATEFORMAT, "%b-%y"}, |
44 | { 0x12, DATEFORMAT, "%I:%M %p"}, | 44 | { 0x12, DATEFORMAT, "%I:%M %p"}, |
45 | { 0x13, DATEFORMAT, "%I:%M:%S %p"}, | 45 | { 0x13, DATEFORMAT, "%I:%M:%S %p"}, |
46 | { 0x14, DATEFORMAT, "%H:%M"}, | 46 | { 0x14, DATEFORMAT, "%H:%M"}, |
47 | { 0x15, DATEFORMAT, "%H:%M:%S"}, | 47 | { 0x15, DATEFORMAT, "%H:%M:%S"}, |
48 | { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"}, | 48 | { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"}, |
49 | { 0x2d, DATEFORMAT, "%M:%S"}, | 49 | { 0x2d, DATEFORMAT, "%M:%S"}, |
50 | { 0x2e, DATEFORMAT, "%H:%M:%S"}, | 50 | { 0x2e, DATEFORMAT, "%H:%M:%S"}, |
51 | { 0x2f, DATEFORMAT, "%M:%S"}, | 51 | { 0x2f, DATEFORMAT, "%M:%S"}, |
52 | { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"}, | 52 | { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"}, |
53 | { 0x1 , NUMBERFORMAT, "%.0f"}, | 53 | { 0x1 , NUMBERFORMAT, "%.0f"}, |
54 | { 0x2 , NUMBERFORMAT, "%.2f"}, | 54 | { 0x2 , NUMBERFORMAT, "%.2f"}, |
55 | { 0x3 , NUMBERFORMAT, "#,##%.0f"}, | 55 | { 0x3 , NUMBERFORMAT, "#,##%.0f"}, |
56 | { 0x4 , NUMBERFORMAT, "#,##%.2f"}, | 56 | { 0x4 , NUMBERFORMAT, "#,##%.2f"}, |
57 | { 0x5 , NUMBERFORMAT, "$#,##%.0f"}, | 57 | { 0x5 , NUMBERFORMAT, "$#,##%.0f"}, |
58 | { 0x6 , NUMBERFORMAT, "$#,##%.0f"}, | 58 | { 0x6 , NUMBERFORMAT, "$#,##%.0f"}, |
59 | { 0x7 , NUMBERFORMAT, "$#,##%.2f"}, | 59 | { 0x7 , NUMBERFORMAT, "$#,##%.2f"}, |
60 | { 0x8 , NUMBERFORMAT, "$#,##%.2f"}, | 60 | { 0x8 , NUMBERFORMAT, "$#,##%.2f"}, |
61 | { 0x9 , NUMBERFORMAT, "%.0f%%"}, | 61 | { 0x9 , NUMBERFORMAT, "%.0f%%"}, |
62 | { 0xa , NUMBERFORMAT, "%.2f%%"}, | 62 | { 0xa , NUMBERFORMAT, "%.2f%%"}, |
63 | { 0xb , NUMBERFORMAT, "%e"}, | 63 | { 0xb , NUMBERFORMAT, "%e"}, |
64 | { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | 64 | { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, |
65 | { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | 65 | { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, |
66 | { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | 66 | { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, |
67 | { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | 67 | { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, |
68 | { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | 68 | { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, |
69 | { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"}, | 69 | { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"}, |
70 | { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | 70 | { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, |
71 | { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"}, | 71 | { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"}, |
72 | { 0x30, NUMBERFORMAT, "##0.0E0"}, | 72 | { 0x30, NUMBERFORMAT, "##0.0E0"}, |
73 | { 0, 0, ""} | 73 | { 0, 0, ""} |
74 | }; | 74 | }; |
75 | 75 | ||
76 | 76 | ||
77 | 77 | ||
78 | int ExcelBook::Integer2Byte(int b1, int b2) | 78 | int ExcelBook::Integer2Byte(int b1, int b2) |
79 | { | 79 | { |
80 | int i1 = b1 & 0xff; | 80 | int i1 = b1 & 0xff; |
81 | int i2 = b2 & 0xff; | 81 | int i2 = b2 & 0xff; |
82 | int val = i2 << 8 | i1; | 82 | int val = i2 << 8 | i1; |
83 | return val; | 83 | return val; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) | 86 | int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) |
87 | { | 87 | { |
88 | int i1 = Integer2Byte(b1, b2); | 88 | int i1 = Integer2Byte(b1, b2); |
89 | int i2 = Integer2Byte(b3, b4); | 89 | int i2 = Integer2Byte(b3, b4); |
90 | int val = i2 << 16 | i1; | 90 | int val = i2 << 16 | i1; |
91 | return val; | 91 | return val; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | int ExcelBook::Integer2ByteFile(FILE *f) | 94 | int ExcelBook::Integer2ByteFile(FILE *f) |
95 | { | 95 | { |
96 | int i1, i2; | 96 | int i1, i2; |
97 | i1 = fgetc(f); | 97 | i1 = fgetc(f); |
98 | i2 = fgetc(f); | 98 | i2 = fgetc(f); |
99 | return Integer2Byte(i1,i2); | 99 | return Integer2Byte(i1,i2); |
100 | }; | 100 | }; |
101 | 101 | ||
102 | float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) | 102 | float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) |
103 | { | 103 | { |
104 | int i; | 104 | int i; |
105 | float f; | 105 | float f; |
106 | unsigned char *ieee; | 106 | unsigned char *ieee; |
107 | ieee = (unsigned char *) &f; | 107 | ieee = (unsigned char *) &f; |
108 | for (i = 0; i < 4; i++) ieee[i] = 0; | 108 | for (i = 0; i < 4; i++) ieee[i] = 0; |
109 | ieee[0] = ((int)b4) & 0xff; | 109 | ieee[0] = ((int)b4) & 0xff; |
110 | ieee[1] = ((int)b3) & 0xff; | 110 | ieee[1] = ((int)b3) & 0xff; |
111 | ieee[2] = ((int)b2) & 0xff; | 111 | ieee[2] = ((int)b2) & 0xff; |
112 | ieee[3] = ((int)b1) & 0xff; | 112 | ieee[3] = ((int)b1) & 0xff; |
113 | return f; | 113 | return f; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) | 116 | double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) |
117 | { | 117 | { |
118 | long int rk; | 118 | long int rk; |
119 | double value; | 119 | double value; |
120 | 120 | ||
121 | rk=Integer4Byte(b1,b2,b3,b4); | 121 | rk=Integer4Byte(b1,b2,b3,b4); |
122 | //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4); | 122 | //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4); |
123 | if ( (rk & 0x02) != 0) | 123 | if ( (rk & 0x02) != 0) |
124 | { | 124 | { |
125 | long int intval = rk >> 2; //drops the 2 bits | 125 | long int intval = rk >> 2; //drops the 2 bits |
126 | printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2); | 126 | printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2); |
127 | value = (double) intval; | 127 | value = (double) intval; |
128 | printf("Double4Byte: VALUEINT=%f\r\n",value); | 128 | printf("Double4Byte: VALUEINT=%f\r\n",value); |
129 | if ( (rk & 0x01) != 0) | 129 | if ( (rk & 0x01) != 0) |
130 | { | 130 | { |
131 | value /= 100.0; | 131 | value /= 100.0; |
132 | }; | 132 | }; |
133 | return value; | 133 | return value; |
134 | } | 134 | } |
135 | else | 135 | else |
136 | { | 136 | { |
137 | 137 | ||
138 | union { double d; unsigned long int b[2]; } dbl_byte; | 138 | union { double d; unsigned long int b[2]; } dbl_byte; |
139 | unsigned long int valbits = (rk & 0xfffffffc); | 139 | unsigned long int valbits = (rk & 0xfffffffc); |
140 | #if defined(__arm__) && !defined(__vfp__) | 140 | #if defined(__arm__) && !defined(__vfp__) |
141 | dbl_byte.b[0]=valbits; | 141 | dbl_byte.b[0]=valbits; |
142 | dbl_byte.b[1]=0; | 142 | dbl_byte.b[1]=0; |
143 | #else | 143 | #else |
144 | dbl_byte.b[0]=0; | 144 | dbl_byte.b[0]=0; |
145 | dbl_byte.b[1]=valbits; | 145 | dbl_byte.b[1]=valbits; |
146 | #endif | 146 | #endif |
147 | printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]); | 147 | printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]); |
148 | value=dbl_byte.d; | 148 | value=dbl_byte.d; |
149 | printf("Double4Byte: VALUE=%f\r\n",value); | 149 | printf("Double4Byte: VALUE=%f\r\n",value); |
150 | 150 | ||
151 | if ( (rk & 0x01) != 0) | 151 | if ( (rk & 0x01) != 0) |
152 | { | 152 | { |
153 | value /= 100.0; | 153 | value /= 100.0; |
154 | }; | 154 | }; |
155 | return value; | 155 | return value; |
156 | }; | 156 | }; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | void ExcelBook::DetectEndian(void) | 159 | void ExcelBook::DetectEndian(void) |
160 | { | 160 | { |
161 | int end; | 161 | int end; |
162 | long i = 0x44332211; | 162 | long i = 0x44332211; |
163 | unsigned char* a = (unsigned char*) &i; | 163 | unsigned char* a = (unsigned char*) &i; |
164 | end = (*a != 0x11); | 164 | end = (*a != 0x11); |
165 | if (end == 1) | 165 | if (end == 1) |
166 | { | 166 | { |
167 | endian = BIG_ENDIAN; | 167 | endian = BIG_ENDIAN; |
168 | printf("BIGENDIAN!\r\n"); | 168 | printf("BIGENDIAN!\r\n"); |
169 | } | 169 | } |
170 | else | 170 | else |
171 | { | 171 | { |
172 | endian = LITTLE_ENDIAN; | 172 | endian = LITTLE_ENDIAN; |
173 | printf("LITTLEENDIAN!\r\n"); | 173 | printf("LITTLEENDIAN!\r\n"); |
174 | } | 174 | } |
175 | }; | 175 | }; |
176 | 176 | ||
177 | double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) | 177 | double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) |
178 | { | 178 | { |
179 | int i; | 179 | int i; |
180 | double d; | 180 | double d; |
181 | unsigned char *ieee; | 181 | unsigned char *ieee; |
182 | ieee = (unsigned char *)&d; | 182 | ieee = (unsigned char *)&d; |
183 | for (i = 0; i < 8; i++) ieee[i] = 0; | 183 | for (i = 0; i < 8; i++) ieee[i] = 0; |
184 | if (endian == BIG_ENDIAN) | 184 | if (endian == BIG_ENDIAN) |
185 | { | 185 | { |
186 | ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff; | 186 | ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff; |
187 | ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff; | 187 | ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff; |
188 | ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff; | 188 | ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff; |
189 | ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff; | 189 | ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff; |
190 | } | 190 | } |
191 | else | 191 | else |
192 | { | 192 | { |
193 | ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff; | 193 | ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff; |
194 | ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff; | 194 | ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff; |
195 | ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff; | 195 | ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff; |
196 | ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff; | 196 | ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff; |
197 | } | 197 | } |
198 | return d; | 198 | return d; |
199 | }; | 199 | }; |
200 | 200 | ||
201 | bool ExcelBook::OpenFile(char *Filename) | 201 | bool ExcelBook::OpenFile(char *Filename) |
202 | { | 202 | { |
203 | printf("Opening excel file!\r\n"); | 203 | printf("Opening excel file!\r\n"); |
204 | File= fopen(Filename, "r"); | 204 | File= fopen(Filename, "r"); |
205 | Position=0; // first byte index in file | 205 | Position=0; // first byte index in file |
206 | XFRecords.resize(0); | 206 | XFRecords.resize(0); |
207 | SharedStrings.resize(0); | 207 | SharedStrings.resize(0); |
208 | Names.resize(0); | 208 | Names.resize(0); |
209 | Sheets.resize(0); | 209 | Sheets.resize(0); |
210 | if(File==NULL) return false; | 210 | if(File==NULL) return false; |
211 | printf("Opened excel file!\r\n"); | 211 | printf("Opened excel file!\r\n"); |
212 | return true; | 212 | return true; |
213 | }; | 213 | }; |
214 | 214 | ||
215 | bool ExcelBook::CloseFile(void) | 215 | bool ExcelBook::CloseFile(void) |
216 | { | 216 | { |
217 | int w1; | 217 | int w1; |
218 | for(w1=0;w1<(int)XFRecords.count();w1++) | 218 | for(w1=0;w1<(int)XFRecords.count();w1++) |
219 | { | 219 | { |
220 | if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;}; | 220 | if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;}; |
221 | }; | 221 | }; |
222 | for(w1=0;w1<(int)SharedStrings.count();w1++) | 222 | for(w1=0;w1<(int)SharedStrings.count();w1++) |
223 | { | 223 | { |
224 | if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;}; | 224 | if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;}; |
225 | }; | 225 | }; |
226 | for(w1=0;w1<(int)Names.count();w1++) | 226 | for(w1=0;w1<(int)Names.count();w1++) |
227 | { | 227 | { |
228 | if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;}; | 228 | if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;}; |
229 | }; | 229 | }; |
230 | for(w1=0;w1<(int)Sheets.count();w1++) | 230 | for(w1=0;w1<(int)Sheets.count();w1++) |
231 | { | 231 | { |
232 | if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;}; | 232 | if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;}; |
233 | }; | 233 | }; |
234 | XFRecords.resize(0); | 234 | XFRecords.resize(0); |
235 | SharedStrings.resize(0); | 235 | SharedStrings.resize(0); |
236 | Names.resize(0); | 236 | Names.resize(0); |
237 | Sheets.resize(0); | 237 | Sheets.resize(0); |
238 | fclose(File); | 238 | fclose(File); |
239 | printf("closed excel file!\r\n"); | 239 | printf("closed excel file!\r\n"); |
240 | if(File==NULL) return true; | 240 | if(File==NULL) return true; |
241 | return false; | 241 | return false; |
242 | }; | 242 | }; |
243 | 243 | ||
244 | void ExcelBook::SeekPosition(int pos) | 244 | void ExcelBook::SeekPosition(int pos) |
245 | { | 245 | { |
246 | if(!feof(File)) | 246 | if(!feof(File)) |
247 | { | 247 | { |
248 | Position=pos; | 248 | Position=pos; |
249 | //printf("SeekPosition:Pos:%d\r\n",Position); | 249 | //printf("SeekPosition:Pos:%d\r\n",Position); |
250 | fseek(File,pos,SEEK_SET); | 250 | fseek(File,pos,SEEK_SET); |
251 | }; | 251 | }; |
252 | }; | 252 | }; |
253 | 253 | ||
254 | void ExcelBook::SeekSkip(int pos) | 254 | void ExcelBook::SeekSkip(int pos) |
255 | { | 255 | { |
256 | if(!feof(File)) | 256 | if(!feof(File)) |
257 | { | 257 | { |
258 | Position=Position+pos; | 258 | Position=Position+pos; |
259 | //printf("SeekSkip:Pos:%d\r\n",Position); | 259 | //printf("SeekSkip:Pos:%d\r\n",Position); |
260 | fseek(File, Position, SEEK_SET); | 260 | fseek(File, Position, SEEK_SET); |
261 | }; | 261 | }; |
262 | }; | 262 | }; |
263 | 263 | ||
264 | int ExcelBook::FileEOF(void) | 264 | int ExcelBook::FileEOF(void) |
265 | { | 265 | { |
266 | if(File!=NULL) return(feof(File)); else return 0; | 266 | if(File!=NULL) return(feof(File)); else return 0; |
267 | //EOF is defined in stdlib as -1 | 267 | //EOF is defined in stdlib as -1 |
268 | }; | 268 | }; |
269 | 269 | ||
270 | int ExcelBook::Get2Bytes(void) | 270 | int ExcelBook::Get2Bytes(void) |
271 | { | 271 | { |
272 | int i1,i2; | 272 | int i1,i2; |
273 | i1=0; i2=0; | 273 | i1=0; i2=0; |
274 | if (!feof(File)) | 274 | if (!feof(File)) |
275 | { | 275 | { |
276 | i1=fgetc(File); | 276 | i1=fgetc(File); |
277 | Position++; | 277 | Position++; |
278 | }; | 278 | }; |
279 | if (!feof(File)) | 279 | if (!feof(File)) |
280 | { | 280 | { |
281 | i2=fgetc(File); | 281 | i2=fgetc(File); |
282 | Position++; | 282 | Position++; |
283 | }; | 283 | }; |
284 | return Integer2Byte(i1,i2); | 284 | return Integer2Byte(i1,i2); |
285 | }; | 285 | }; |
286 | 286 | ||
287 | char* ExcelBook::Read(int pos, int length) | 287 | char* ExcelBook::Read(int pos, int length) |
288 | { | 288 | { |
289 | int i; | 289 | int i; |
290 | char *data; | 290 | char *data; |
291 | data= new char[length]; | 291 | data= new char[length]; |
292 | SeekPosition(pos); | 292 | SeekPosition(pos); |
293 | for(i=0; i<length; i++) | 293 | for(i=0; i<length; i++) |
294 | { | 294 | { |
295 | if(!feof(File)) data[i]=fgetc(File); | 295 | if(!feof(File)) data[i]=fgetc(File); |
296 | }; | 296 | }; |
297 | Position= Position+length; | 297 | Position= Position+length; |
298 | return data; | 298 | return data; |
299 | }; | 299 | }; |
300 | 300 | ||
301 | QString ExcelBook::ReadUnicodeChar(int pos, int length) | 301 | QString ExcelBook::ReadUnicodeChar(int pos, int length) |
302 | { | 302 | { |
303 | int i; | 303 | int i; |
304 | QString data; | 304 | QString data; |
305 | int i1=' ',i2=' ',ii; | 305 | int i1=' ',i2=' ',ii; |
306 | SeekPosition(pos); | 306 | SeekPosition(pos); |
307 | for(i=0; i<length; i++) | 307 | for(i=0; i<length; i++) |
308 | { | 308 | { |
309 | if(!feof(File)) i1=fgetc(File); | 309 | if(!feof(File)) i1=fgetc(File); |
310 | if(!feof(File)) i2=fgetc(File); | 310 | if(!feof(File)) i2=fgetc(File); |
311 | ii=Integer2Byte(i1,i2); | 311 | ii=Integer2Byte(i1,i2); |
312 | data.append(ii); | 312 | data.append(ii); |
313 | Position+=2; | 313 | Position+=2; |
314 | }; | 314 | }; |
315 | return data; | 315 | return data; |
316 | }; | 316 | }; |
317 | 317 | ||
318 | QString* ExcelBook::GetString(int num) | 318 | QString* ExcelBook::GetString(int num) |
319 | { | 319 | { |
320 | if(num>=0 && num<(int)SharedStrings.count()) | 320 | if(num>=0 && num<(int)SharedStrings.count()) |
321 | { | 321 | { |
322 | return SharedStrings[num]; | 322 | return SharedStrings[num]; |
323 | }; | 323 | }; |
324 | return new QString(""); | 324 | return new QString(""); |
325 | }; | 325 | }; |
326 | 326 | ||
327 | int ExcelBook::SeekBOF(void) | 327 | int ExcelBook::SeekBOF(void) |
328 | { | 328 | { |
329 | int opcode,version,streamtype,length,ret=0; | 329 | int opcode,version,streamtype,length,ret=0; |
330 | char *data; | 330 | char *data; |
331 | while(!feof(File)) | 331 | while(!feof(File)) |
332 | { | 332 | { |
333 | opcode=Get2Bytes(); | 333 | opcode=Get2Bytes(); |
334 | if(opcode==XL_BOF) | 334 | if(opcode==XL_BOF) |
335 | { | 335 | { |
336 | length=Get2Bytes(); | 336 | length=Get2Bytes(); |
337 | data=Read(Position,length); | 337 | data=Read(Position,length); |
338 | version=Integer2Byte(data[0], data[1]); | 338 | version=Integer2Byte(data[0], data[1]); |
339 | streamtype=Integer2Byte(data[2], data[3]); | 339 | streamtype=Integer2Byte(data[2], data[3]); |
340 | printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version); | 340 | printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version); |
341 | delete [] data; data=NULL; | 341 | delete [] data; data=NULL; |
342 | if (version==BIFF8) ret=8; | 342 | if (version==BIFF8) ret=8; |
343 | else if(version==BIFF7) ret=7; | 343 | else if(version==BIFF7) ret=7; |
344 | printf("SEEKBOF:versionBIFF%d\r\n",ret); | 344 | printf("SEEKBOF:versionBIFF%d\r\n",ret); |
345 | if(streamtype==WBKGLOBAL) return ret *2; | 345 | if(streamtype==WBKGLOBAL) return ret *2; |
346 | else if(streamtype==WRKSHEET) return ret *1; | 346 | else if(streamtype==WRKSHEET) return ret *1; |
347 | return 1; | 347 | return 1; |
348 | }; | 348 | }; |
349 | }; | 349 | }; |
350 | return 0; | 350 | return 0; |
351 | }; | 351 | }; |
352 | 352 | ||
353 | ExcelBREC* ExcelBook::GetBREC(void) | 353 | ExcelBREC* ExcelBook::GetBREC(void) |
354 | { | 354 | { |
355 | ExcelBREC* rec; | 355 | ExcelBREC* rec; |
356 | rec= new ExcelBREC; | 356 | rec= new ExcelBREC; |
357 | if(FileEOF()) return NULL; | 357 | if(FileEOF()) return NULL; |
358 | rec->data=NULL; | 358 | rec->data=NULL; |
359 | rec->code=Get2Bytes(); | 359 | rec->code=Get2Bytes(); |
360 | rec->length=Get2Bytes(); | 360 | rec->length=Get2Bytes(); |
361 | rec->position=Position; | 361 | rec->position=Position; |
362 | SeekSkip(rec->length); | 362 | SeekSkip(rec->length); |
363 | return rec; | 363 | return rec; |
364 | }; | 364 | }; |
365 | 365 | ||
366 | ExcelBREC* ExcelBook::PeekBREC(void) | 366 | ExcelBREC* ExcelBook::PeekBREC(void) |
367 | { | 367 | { |
368 | int oldpos; | 368 | int oldpos; |
369 | ExcelBREC* NextRec; | 369 | ExcelBREC* NextRec; |
370 | oldpos=Position; | 370 | oldpos=Position; |
371 | NextRec=GetBREC(); | 371 | NextRec=GetBREC(); |
372 | SeekPosition(oldpos); | 372 | SeekPosition(oldpos); |
373 | return NextRec; | 373 | return NextRec; |
374 | }; | 374 | }; |
375 | 375 | ||
376 | char* ExcelBook::GetDataOfBREC(ExcelBREC* record) | 376 | char* ExcelBook::GetDataOfBREC(ExcelBREC* record) |
377 | { | 377 | { |
378 | if(record->data==NULL) | 378 | if(record->data==NULL) |
379 | { | 379 | { |
380 | ConvertCharToArray(record,Read(record->position,record->length),record->length); | 380 | char* readData = Read(record->position,record->length); |
381 | ConvertCharToArray(record,readData,record->length); | ||
382 | delete [] readData; | ||
381 | }; | 383 | }; |
382 | return record->data;//new? | 384 | return record->data;//new? |
383 | }; | 385 | }; |
384 | 386 | ||
385 | void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) | 387 | void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) |
386 | { | 388 | { |
387 | record->data=new char[length]; | 389 | record->data=new char[length]; |
388 | for(int w1=0;w1<=length-1;w1++) | 390 | for(int w1=0;w1<=length-1;w1++) |
389 | record->data[w1]=chars[w1]; | 391 | record->data[w1]=chars[w1]; |
390 | }; | 392 | }; |
391 | 393 | ||
392 | 394 | ||
393 | bool ExcelSheet::InitCells() | 395 | bool ExcelSheet::InitCells() |
394 | { | 396 | { |
395 | int r; | 397 | int r; |
396 | Cells.resize(rows * cols + cols+1); | 398 | Cells.resize(rows * cols + cols+1); |
397 | if(Cells.count()==0) return false; | 399 | if(Cells.count()==0) return false; |
398 | for(r=0;r < Cells.count();r++) | 400 | for(r=0;r < Cells.count();r++) |
399 | { | 401 | { |
400 | Cells[r]=NULL; | 402 | Cells[r]=NULL; |
401 | }; | 403 | }; |
402 | return true; | 404 | return true; |
403 | }; | 405 | }; |
404 | 406 | ||
405 | void ExcelSheet::Set(int row, int col, ExcelCell* cell) | 407 | void ExcelSheet::Set(int row, int col, ExcelCell* cell) |
406 | { | 408 | { |
407 | if(cell!=NULL&&(row*cols+col)<Cells.count()) | 409 | if(cell!=NULL&&(row*cols+col)<Cells.count()) |
408 | { | 410 | { |
409 | Cells[row*cols+col]=cell; | 411 | Cells[row*cols+col]=cell; |
410 | }; | 412 | }; |
411 | }; | 413 | }; |
412 | 414 | ||
413 | ExcelCell* ExcelSheet::Get(int row, int col) | 415 | ExcelCell* ExcelSheet::Get(int row, int col) |
414 | { | 416 | { |
415 | ExcelCell* cell; | 417 | ExcelCell* cell; |
416 | cell=Cells[row*cols+col]; | 418 | cell=Cells[row*cols+col]; |
417 | if(cell==NULL) return NULL; | 419 | if(cell==NULL) return NULL; |
418 | return cell; | 420 | return cell; |
419 | }; | 421 | }; |
420 | 422 | ||
421 | int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) | 423 | int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) |
422 | { | 424 | { |
423 | char* data=NULL; | 425 | char* data=NULL; |
424 | switch (record->code) | 426 | switch (record->code) |
425 | { | 427 | { |
426 | case XL_DIMENSION: | 428 | case XL_DIMENSION: |
427 | data = GetDataOfBREC(record); | 429 | data = GetDataOfBREC(record); |
428 | if (record->length == 10) | 430 | if (record->length == 10) |
429 | { | 431 | { |
430 | sheet->rows = Integer2Byte(data[2], data[3]); | 432 | sheet->rows = Integer2Byte(data[2], data[3]); |
431 | sheet->cols = Integer2Byte(data[6], data[7]); | 433 | sheet->cols = Integer2Byte(data[6], data[7]); |
432 | } | 434 | } |
433 | else | 435 | else |
434 | { | 436 | { |
435 | sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]); | 437 | sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]); |
436 | sheet->cols = Integer2Byte(data[10], data[11]); | 438 | sheet->cols = Integer2Byte(data[10], data[11]); |
437 | } | 439 | } |
438 | sheet->InitCells(); | 440 | sheet->InitCells(); |
439 | break; | 441 | break; |
440 | 442 | ||
441 | case XL_LABELSST: | 443 | case XL_LABELSST: |
442 | HandleLabelSST(sheet, record); | 444 | HandleLabelSST(sheet, record); |
443 | break; | 445 | break; |
444 | 446 | ||
445 | case XL_RK: | 447 | case XL_RK: |
446 | case XL_RK2: | 448 | case XL_RK2: |
447 | HandleRK(sheet, record); | 449 | HandleRK(sheet, record); |
448 | break; | 450 | break; |
449 | 451 | ||
450 | case XL_MULRK: | 452 | case XL_MULRK: |
451 | HandleMulrk(sheet, record); | 453 | HandleMulrk(sheet, record); |
452 | break; | 454 | break; |
453 | 455 | ||
454 | case XL_ROW: | 456 | case XL_ROW: |
455 | break; | 457 | break; |
456 | 458 | ||
457 | case XL_NUMBER: | 459 | case XL_NUMBER: |
458 | HandleNumber(sheet, record); | 460 | HandleNumber(sheet, record); |
459 | break; | 461 | break; |
460 | 462 | ||
461 | case XL_BOOLERR: | 463 | case XL_BOOLERR: |
462 | break; | 464 | break; |
463 | 465 | ||
464 | case XL_CONTINUE: | 466 | case XL_CONTINUE: |
465 | break; | 467 | break; |
466 | 468 | ||
467 | case XL_FORMULA: | 469 | case XL_FORMULA: |
468 | case XL_FORMULA2: | 470 | case XL_FORMULA2: |
469 | HandleFormula(sheet, record); | 471 | HandleFormula(sheet, record); |
470 | break; | 472 | break; |
471 | 473 | ||
472 | case XL_LABEL: | 474 | case XL_LABEL: |
473 | break; | 475 | break; |
474 | 476 | ||
475 | case XL_NAME: | 477 | case XL_NAME: |
476 | HandleName(sheet, record); | 478 | HandleName(sheet, record); |
477 | break; | 479 | break; |
478 | 480 | ||
479 | case XL_BOF: | 481 | case XL_BOF: |
480 | break; | 482 | break; |
481 | case XL_EOF: | 483 | case XL_EOF: |
482 | return 0; | 484 | return 0; |
483 | default: | 485 | default: |
484 | break; | 486 | break; |
485 | }; | 487 | }; |
486 | return 1; | 488 | return 1; |
487 | }; | 489 | }; |
488 | 490 | ||
489 | int ExcelBook::ReadSheet(ExcelSheet* sheet) | 491 | int ExcelBook::ReadSheet(ExcelSheet* sheet) |
490 | { | 492 | { |
491 | ExcelBREC* record; | 493 | ExcelBREC* record; |
492 | int oldpos; | 494 | int oldpos; |
493 | oldpos = Position; | 495 | oldpos = Position; |
494 | SeekPosition(sheet->position); | 496 | SeekPosition(sheet->position); |
495 | record = GetBREC(); | 497 | record = GetBREC(); |
496 | while (record!=NULL) | 498 | while (record!=NULL) |
497 | { | 499 | { |
498 | if (!SheetHandleRecord(sheet, record)) break; | 500 | if (!SheetHandleRecord(sheet, record)) break; |
499 | record=GetBREC(); | 501 | record=GetBREC(); |
500 | }; | 502 | }; |
501 | SeekPosition(oldpos); | 503 | SeekPosition(oldpos); |
502 | return 1; | 504 | return 1; |
503 | }; | 505 | }; |
504 | 506 | ||
505 | ExcelSheet* ExcelBook::GetSheet(void) | 507 | ExcelSheet* ExcelBook::GetSheet(void) |
506 | { | 508 | { |
507 | ExcelSheet* sh=NULL; | 509 | ExcelSheet* sh=NULL; |
508 | int type; | 510 | int type; |
509 | type=SeekBOF(); | 511 | type=SeekBOF(); |
510 | Version=type; | 512 | Version=type; |
511 | sh=new ExcelSheet; | 513 | sh=new ExcelSheet; |
512 | if(type) | 514 | if(type) |
513 | { | 515 | { |
514 | sh->type=type; | 516 | sh->type=type; |
515 | sh->position=Position; | 517 | sh->position=Position; |
516 | sh->name=QString(""); | 518 | sh->name=QString(""); |
517 | }; | 519 | }; |
518 | if(type==8||type==7) | 520 | if(type==8||type==7) |
519 | { | 521 | { |
520 | ReadSheet(sh); | 522 | ReadSheet(sh); |
521 | }; | 523 | }; |
522 | return sh; | 524 | return sh; |
523 | }; | 525 | }; |
524 | 526 | ||
525 | void ExcelBook::ParseSheets(void) | 527 | void ExcelBook::ParseSheets(void) |
526 | { | 528 | { |
527 | int BOFs; | 529 | int BOFs; |
528 | ExcelBREC* r; | 530 | ExcelBREC* r; |
529 | BOFs=1; | 531 | BOFs=1; |
530 | r=GetBREC(); | 532 | r=GetBREC(); |
531 | while(BOFs) | 533 | while(BOFs) |
532 | { | 534 | { |
533 | r=GetBREC(); | 535 | r=GetBREC(); |
534 | switch(r->code) | 536 | switch(r->code) |
535 | { | 537 | { |
536 | case XL_SST: | 538 | case XL_SST: |
537 | HandleSST(r); | 539 | HandleSST(r); |
538 | break; | 540 | break; |
539 | 541 | ||
540 | case XL_TXO: | 542 | case XL_TXO: |
541 | break; | 543 | break; |
542 | case XL_NAME: | 544 | case XL_NAME: |
543 | break; | 545 | break; |
544 | case XL_ROW: | 546 | case XL_ROW: |
545 | break; | 547 | break; |
546 | 548 | ||
547 | case XL_FORMAT: | 549 | case XL_FORMAT: |
548 | HandleFormat(r); | 550 | HandleFormat(r); |
549 | break; | 551 | break; |
550 | 552 | ||
551 | case XL_XF: | 553 | case XL_XF: |
552 | HandleXF(r); | 554 | HandleXF(r); |
553 | break; | 555 | break; |
554 | 556 | ||
555 | case XL_BOUNDSHEET: | 557 | case XL_BOUNDSHEET: |
556 | HandleBoundSheet(r); | 558 | HandleBoundSheet(r); |
557 | break; | 559 | break; |
558 | 560 | ||
559 | case XL_EXTSST: | 561 | case XL_EXTSST: |
560 | break; | 562 | break; |
561 | case XL_CONTINUE: | 563 | case XL_CONTINUE: |
562 | break; | 564 | break; |
563 | 565 | ||
564 | case XL_EOF: | 566 | case XL_EOF: |
565 | BOFs--; | 567 | BOFs--; |
566 | break; | 568 | break; |
567 | 569 | ||
568 | default: | 570 | default: |
569 | break; | 571 | break; |
570 | }; | 572 | }; |
571 | }; | 573 | }; |
572 | }; | 574 | }; |
573 | 575 | ||
574 | void ExcelBook::GetSheets(void) | 576 | void ExcelBook::GetSheets(void) |
575 | { | 577 | { |
576 | ExcelSheet* sheet; | 578 | ExcelSheet* sheet; |
577 | Sheets.resize(0); | 579 | Sheets.resize(0); |
578 | sheet=GetSheet(); | 580 | sheet=GetSheet(); |
579 | while (sheet->Cells.count()!= 0 ) | 581 | while (sheet->Cells.count()!= 0 ) |
580 | { | 582 | { |
581 | Sheets.resize(Sheets.count()+1); | 583 | Sheets.resize(Sheets.count()+1); |
582 | Sheets[Sheets.count()-1]=sheet; | 584 | Sheets[Sheets.count()-1]=sheet; |
583 | sheet->name=*Names[Sheets.count()-1]; | 585 | sheet->name=*Names[Sheets.count()-1]; |
584 | sheet=GetSheet(); | 586 | sheet=GetSheet(); |
585 | }; | 587 | }; |
586 | }; | 588 | }; |
587 | 589 | ||
588 | bool ExcelBook::ParseBook(char *file) | 590 | bool ExcelBook::ParseBook(char *file) |
589 | { | 591 | { |
590 | dateformat=QString(""); | 592 | dateformat=QString(""); |
591 | DetectEndian(); | 593 | DetectEndian(); |
592 | if ( !OpenFile( file ) ) | 594 | if ( !OpenFile( file ) ) |
593 | return false; | 595 | return false; |
594 | SeekBOF(); | 596 | SeekBOF(); |
595 | ParseSheets(); | 597 | ParseSheets(); |
596 | GetSheets(); | 598 | GetSheets(); |
597 | return true; | 599 | return true; |
598 | }; | 600 | }; |
599 | 601 | ||
600 | QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) | 602 | QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) |
601 | { | 603 | { |
602 | int i; | 604 | int i; |
603 | QString outstr=""; | 605 | QString outstr=""; |
604 | for (i = 0; i < chars; i++) | 606 | for (i = 0; i < chars; i++) |
605 | { | 607 | { |
606 | outstr.append(inbytes[i+pos]); | 608 | outstr.append(inbytes[i+pos]); |
607 | }; | 609 | }; |
608 | return outstr; | 610 | return outstr; |
609 | }; | 611 | }; |
610 | 612 | ||
611 | QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) | 613 | QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) |
612 | { | 614 | { |
613 | QString outstr=""; | 615 | QString outstr=""; |
614 | int i; | 616 | int i; |
615 | int rc; | 617 | int rc; |
616 | for (i=0; i<chars*2; i++) | 618 | for (i=0; i<chars*2; i++) |
617 | { | 619 | { |
618 | rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]); | 620 | rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]); |
619 | outstr.append(QChar(rc)); | 621 | outstr.append(QChar(rc)); |
620 | i++; | 622 | i++; |
621 | }; | 623 | }; |
622 | return outstr; | 624 | return outstr; |
623 | }; | 625 | }; |
624 | 626 | ||
625 | 627 | ||
626 | void ExcelBook::HandleBoundSheet(ExcelBREC* rec) | 628 | void ExcelBook::HandleBoundSheet(ExcelBREC* rec) |
627 | { | 629 | { |
628 | char* data; | 630 | char* data; |
629 | int type; | 631 | int type; |
630 | int visibility; | 632 | int visibility; |
631 | int length; | 633 | int length; |
632 | int pos; | 634 | int pos; |
633 | QString name; | 635 | QString name; |
634 | pos = 8; | 636 | pos = 8; |
635 | data = GetDataOfBREC(rec); | 637 | data = GetDataOfBREC(rec); |
636 | type = data[4]; | 638 | type = data[4]; |
637 | visibility = data[5]; | 639 | visibility = data[5]; |
638 | length = data[6]; | 640 | length = data[6]; |
639 | if(data[7]==0) | 641 | if(data[7]==0) |
640 | { | 642 | { |
641 | //ascii | 643 | //ascii |
642 | name=GetASCII(data,pos,length); | 644 | name=GetASCII(data,pos,length); |
643 | } | 645 | } |
644 | else | 646 | else |
645 | { | 647 | { |
646 | name=GetUnicode(data,pos,length); | 648 | name=GetUnicode(data,pos,length); |
647 | }; | 649 | }; |
648 | Names.resize(Names.count()+1); | 650 | Names.resize(Names.count()+1); |
649 | Names[Names.count()-1]=new QString(name); | 651 | Names[Names.count()-1]=new QString(name); |
650 | }; | 652 | }; |
651 | 653 | ||
652 | void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) | 654 | void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) |
653 | { | 655 | { |
654 | char* data; | 656 | char* data; |
655 | QString name; | 657 | QString name; |
656 | int length; | 658 | int length; |
657 | int pos; | 659 | int pos; |
658 | pos = 15; | 660 | pos = 15; |
659 | data = GetDataOfBREC(rec); | 661 | data = GetDataOfBREC(rec); |
660 | length = data[3]; | 662 | length = data[3]; |
661 | name = GetASCII(data,pos,length); | 663 | name = GetASCII(data,pos,length); |
662 | 664 | ||
663 | 665 | ||
664 | }; | 666 | }; |
665 | 667 | ||
666 | ExcelFormat* ExcelBook::GetFormatting(int xf) | 668 | ExcelFormat* ExcelBook::GetFormatting(int xf) |
667 | { | 669 | { |
668 | int i; | 670 | int i; |
669 | ExcelFormat* rec; | 671 | ExcelFormat* rec; |
670 | rec=new ExcelFormat(); | 672 | rec=new ExcelFormat(); |
671 | for (i = 0; formatter[i].code != 0; i++) | 673 | for (i = 0; formatter[i].code != 0; i++) |
672 | { | 674 | { |
673 | if (xf == formatter[i].code) break; | 675 | if (xf == formatter[i].code) break; |
674 | }; | 676 | }; |
675 | if (formatter[i].format ==NULL) return NULL; | 677 | if (formatter[i].format ==NULL) return NULL; |
676 | rec->code = xf; | 678 | rec->code = xf; |
677 | rec->type = formatter[i].type; | 679 | rec->type = formatter[i].type; |
678 | rec->format = formatter[i].format; | 680 | rec->format = formatter[i].format; |
679 | return rec; | 681 | return rec; |
680 | }; | 682 | }; |
681 | 683 | ||
682 | void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) | 684 | void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) |
683 | { | 685 | { |
684 | QString str=QString(""); | 686 | QString str=QString(""); |
685 | char* data; | 687 | char* data; |
686 | int chars, pos, options, i; | 688 | int chars, pos, options, i; |
687 | int richstring, fareaststring, runlength=0; | 689 | int richstring, fareaststring, runlength=0; |
688 | int richruns=0,fareastsize=0; | 690 | int richruns=0,fareastsize=0; |
689 | int totalstrings; | 691 | int totalstrings; |
690 | int uniquestrings; | 692 | int uniquestrings; |
691 | data = GetDataOfBREC(rec); | 693 | data = GetDataOfBREC(rec); |
692 | totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]); | 694 | totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]); |
693 | uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]); | 695 | uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]); |
694 | pos = 8; | 696 | pos = 8; |
695 | for (i = 0; i < uniquestrings; i++) | 697 | for (i = 0; i < uniquestrings; i++) |
696 | { | 698 | { |
697 | richruns=0; fareastsize=0; | 699 | richruns=0; fareastsize=0; |
698 | chars = Integer2Byte(data[pos], data[pos+1]); | 700 | chars = Integer2Byte(data[pos], data[pos+1]); |
699 | pos += 2; | 701 | pos += 2; |
700 | options = data[pos]; | 702 | options = data[pos]; |
701 | pos++; | 703 | pos++; |
702 | fareaststring = ((options & 0x04) != 0); | 704 | fareaststring = ((options & 0x04) != 0); |
703 | richstring = ((options & 0x08) != 0); | 705 | richstring = ((options & 0x08) != 0); |
704 | if(richstring) | 706 | if(richstring) |
705 | { | 707 | { |
706 | richruns= Integer2Byte(data[pos],data[pos+1]); | 708 | richruns= Integer2Byte(data[pos],data[pos+1]); |
707 | pos+=2; | 709 | pos+=2; |
708 | }; | 710 | }; |
709 | if(fareaststring) | 711 | if(fareaststring) |
710 | { | 712 | { |
711 | fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]); | 713 | fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]); |
712 | pos+=4; | 714 | pos+=4; |
713 | }; | 715 | }; |
714 | 716 | ||
715 | if ((options & 0x01) == 0) //8 bit chars | 717 | if ((options & 0x01) == 0) //8 bit chars |
716 | { | 718 | { |
717 | /* ascii */ | 719 | /* ascii */ |
718 | str = GetASCII(bytes,pos,chars); | 720 | str = GetASCII(bytes,pos,chars); |
719 | pos=pos+chars; | 721 | pos=pos+chars; |
720 | if(str[0]=='=') str[0]=' '; | 722 | if(str[0]=='=') str[0]=' '; |
721 | }else //16 bit chars | 723 | }else //16 bit chars |
722 | { | 724 | { |
723 | /* unicode */ | 725 | /* unicode */ |
724 | str = GetUnicode(bytes,pos,chars); | 726 | str = GetUnicode(bytes,pos,chars); |
725 | pos=pos+chars*2; | 727 | pos=pos+chars*2; |
726 | }; | 728 | }; |
727 | // HERE TO PUT richformat handling | 729 | // HERE TO PUT richformat handling |
728 | if (richstring) | 730 | if (richstring) |
729 | { | 731 | { |
730 | pos += 4 * richruns; | 732 | pos += 4 * richruns; |
731 | }; | 733 | }; |
732 | if (fareaststring) | 734 | if (fareaststring) |
733 | { | 735 | { |
734 | pos += fareastsize; | 736 | pos += fareastsize; |
735 | }; | 737 | }; |
736 | //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode()); | 738 | //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode()); |
737 | SharedStrings.resize(SharedStrings.count()+1); | 739 | SharedStrings.resize(SharedStrings.count()+1); |
738 | SharedStrings[SharedStrings.count()-1]=new QString(str); | 740 | SharedStrings[SharedStrings.count()-1]=new QString(str); |
739 | } | 741 | } |
740 | }; | 742 | }; |
741 | 743 | ||
742 | 744 | ||
743 | char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) | 745 | char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) |
744 | { | 746 | { |
745 | int i, pos; | 747 | int i, pos; |
746 | int length; | 748 | int length; |
747 | 749 | ||
748 | char* data; | 750 | char* data; |
749 | char* bytes; | 751 | char* bytes; |
750 | length = rec->length; | 752 | length = rec->length; |
751 | for (i = 0; i < (int) cont->rec.count(); i++) | 753 | for (i = 0; i < (int) cont->rec.count(); i++) |
752 | { | 754 | { |
753 | length += cont->rec[i]->length; | 755 | length += cont->rec[i]->length; |
754 | } | 756 | } |
755 | bytes = GetDataOfBREC(rec); | 757 | bytes = GetDataOfBREC(rec); |
756 | pos = rec->length; | 758 | pos = rec->length; |
757 | for (i = 0; i < (int) cont->rec.count(); i++) | 759 | for (i = 0; i < (int) cont->rec.count(); i++) |
758 | { | 760 | { |
759 | data = GetDataOfBREC(cont->rec[i]); | 761 | data = GetDataOfBREC(cont->rec[i]); |
760 | *bytes += pos; | 762 | *bytes += pos; |
761 | bytes = data; | 763 | bytes = data; |
762 | pos += cont->rec[i]->length; | 764 | pos += cont->rec[i]->length; |
763 | } | 765 | } |
764 | return bytes; | 766 | return bytes; |
diff --git a/noncore/apps/zsafe/zsafe.cpp b/noncore/apps/zsafe/zsafe.cpp index f70f863..9c0c6ce 100644 --- a/noncore/apps/zsafe/zsafe.cpp +++ b/noncore/apps/zsafe/zsafe.cpp | |||
@@ -1387,1228 +1387,1229 @@ void ZSafe::readAllEntries() | |||
1387 | int len=s.length()+1; | 1387 | int len=s.length()+1; |
1388 | char buffer[len]; | 1388 | char buffer[len]; |
1389 | strcpy (buffer, s); | 1389 | strcpy (buffer, s); |
1390 | 1390 | ||
1391 | QString name; | 1391 | QString name; |
1392 | QString user; | 1392 | QString user; |
1393 | QString password; | 1393 | QString password; |
1394 | QString comment; | 1394 | QString comment; |
1395 | 1395 | ||
1396 | // separete the entries | 1396 | // separete the entries |
1397 | char *i = strtok (buffer, "|"); | 1397 | char *i = strtok (buffer, "|"); |
1398 | QString category(&i[1]); | 1398 | QString category(&i[1]); |
1399 | category.truncate(category.length() -1); | 1399 | category.truncate(category.length() -1); |
1400 | 1400 | ||
1401 | int idx=0; | 1401 | int idx=0; |
1402 | while (i = strtok (NULL, "|")) | 1402 | while (i = strtok (NULL, "|")) |
1403 | { | 1403 | { |
1404 | switch (idx) | 1404 | switch (idx) |
1405 | { | 1405 | { |
1406 | case 0: | 1406 | case 0: |
1407 | name = &i[1]; | 1407 | name = &i[1]; |
1408 | name.truncate(name.length() -1); | 1408 | name.truncate(name.length() -1); |
1409 | // name | 1409 | // name |
1410 | break; | 1410 | break; |
1411 | case 1: | 1411 | case 1: |
1412 | // user | 1412 | // user |
1413 | user = &i[1]; | 1413 | user = &i[1]; |
1414 | user.truncate(user.length() -1); | 1414 | user.truncate(user.length() -1); |
1415 | break; | 1415 | break; |
1416 | case 2: | 1416 | case 2: |
1417 | // password | 1417 | // password |
1418 | password = &i[1]; | 1418 | password = &i[1]; |
1419 | password.truncate(password.length() -1); | 1419 | password.truncate(password.length() -1); |
1420 | break; | 1420 | break; |
1421 | case 3: | 1421 | case 3: |
1422 | // comment | 1422 | // comment |
1423 | comment = &i[1]; | 1423 | comment = &i[1]; |
1424 | comment.truncate(comment.length() -1); | 1424 | comment.truncate(comment.length() -1); |
1425 | break; | 1425 | break; |
1426 | } | 1426 | } |
1427 | idx++; | 1427 | idx++; |
1428 | } | 1428 | } |
1429 | 1429 | ||
1430 | Category *cat= categories.find (category); | 1430 | Category *cat= categories.find (category); |
1431 | if (cat) | 1431 | if (cat) |
1432 | { | 1432 | { |
1433 | // use the existend item | 1433 | // use the existend item |
1434 | QListViewItem *catItem = cat->getListItem(); | 1434 | QListViewItem *catItem = cat->getListItem(); |
1435 | if (catItem) | 1435 | if (catItem) |
1436 | { | 1436 | { |
1437 | QListViewItem * item = new ShadedListItem( 0, catItem ); | 1437 | QListViewItem * item = new ShadedListItem( 0, catItem ); |
1438 | item->setText( 0, tr( name ) ); | 1438 | item->setText( 0, tr( name ) ); |
1439 | item->setText( 1, tr( user ) ); | 1439 | item->setText( 1, tr( user ) ); |
1440 | item->setText( 2, tr( password ) ); | 1440 | item->setText( 2, tr( password ) ); |
1441 | item->setText( 3, tr( comment ) ); | 1441 | item->setText( 3, tr( comment ) ); |
1442 | 1442 | ||
1443 | catItem->setOpen( TRUE ); | 1443 | catItem->setOpen( TRUE ); |
1444 | } | 1444 | } |
1445 | } | 1445 | } |
1446 | else | 1446 | else |
1447 | { | 1447 | { |
1448 | QListViewItem *catI = new ShadedListItem( 1, ListView ); | 1448 | QListViewItem *catI = new ShadedListItem( 1, ListView ); |
1449 | // create and insert a new item | 1449 | // create and insert a new item |
1450 | QListViewItem * item = new ShadedListItem( 0, catI ); | 1450 | QListViewItem * item = new ShadedListItem( 0, catI ); |
1451 | item->setText( 0, tr( name ) ); | 1451 | item->setText( 0, tr( name ) ); |
1452 | item->setText( 1, tr( user ) ); | 1452 | item->setText( 1, tr( user ) ); |
1453 | item->setText( 2, tr( password ) ); | 1453 | item->setText( 2, tr( password ) ); |
1454 | item->setText( 3, tr( comment ) ); | 1454 | item->setText( 3, tr( comment ) ); |
1455 | 1455 | ||
1456 | catI->setOpen( TRUE ); | 1456 | catI->setOpen( TRUE ); |
1457 | 1457 | ||
1458 | Category *c1 = new Category(); | 1458 | Category *c1 = new Category(); |
1459 | c1->setCategoryName(category); | 1459 | c1->setCategoryName(category); |
1460 | 1460 | ||
1461 | QString icon; | 1461 | QString icon; |
1462 | QString fullIconPath; | 1462 | QString fullIconPath; |
1463 | QPixmap *pix; | 1463 | QPixmap *pix; |
1464 | // #ifndef Q_WS_WIN | 1464 | // #ifndef Q_WS_WIN |
1465 | icon = conf->readEntry(APP_KEY+category); | 1465 | icon = conf->readEntry(APP_KEY+category); |
1466 | // #endif | 1466 | // #endif |
1467 | bool isIconAv = false; | 1467 | bool isIconAv = false; |
1468 | if (!icon.isEmpty() && !icon.isNull()) | 1468 | if (!icon.isEmpty() && !icon.isNull()) |
1469 | { | 1469 | { |
1470 | // build the full path | 1470 | // build the full path |
1471 | fullIconPath = iconPath + icon; | 1471 | fullIconPath = iconPath + icon; |
1472 | pix = new QPixmap (fullIconPath); | 1472 | pix = new QPixmap (fullIconPath); |
1473 | if (!pix->isNull()) | 1473 | if (!pix->isNull()) |
1474 | { | 1474 | { |
1475 | QImage img = pix->convertToImage(); | 1475 | QImage img = pix->convertToImage(); |
1476 | pix->convertFromImage(img.smoothScale(14,14)); | 1476 | pix->convertFromImage(img.smoothScale(14,14)); |
1477 | c1->setIconName (icon); | 1477 | c1->setIconName (icon); |
1478 | c1->setIcon (*pix); | 1478 | c1->setIcon (*pix); |
1479 | isIconAv = true; | 1479 | isIconAv = true; |
1480 | } | 1480 | } |
1481 | } | 1481 | } |
1482 | if (!isIconAv) | 1482 | if (!isIconAv) |
1483 | { | 1483 | { |
1484 | c1->setIcon (*getPredefinedIcon(category)); | 1484 | c1->setIcon (*getPredefinedIcon(category)); |
1485 | } | 1485 | } |
1486 | c1->setListItem (catI); | 1486 | c1->setListItem (catI); |
1487 | c1->initListItem(); | 1487 | c1->initListItem(); |
1488 | categories.insert (c1->getCategoryName(), c1); | 1488 | categories.insert (c1->getCategoryName(), c1); |
1489 | } | 1489 | } |
1490 | 1490 | ||
1491 | } | 1491 | } |
1492 | f.close(); | 1492 | f.close(); |
1493 | 1493 | ||
1494 | } | 1494 | } |
1495 | #endif // UNUSED | 1495 | #endif // UNUSED |
1496 | 1496 | ||
1497 | void ZSafe::resume(int) | 1497 | void ZSafe::resume(int) |
1498 | { | 1498 | { |
1499 | // hide the main window | 1499 | // hide the main window |
1500 | 1500 | ||
1501 | if ( !showpwd ) | 1501 | if ( !showpwd ) |
1502 | { | 1502 | { |
1503 | infoForm->hide(); | 1503 | infoForm->hide(); |
1504 | // open zsafe again | 1504 | // open zsafe again |
1505 | m_password = ""; | 1505 | m_password = ""; |
1506 | selectedItem = NULL; | 1506 | selectedItem = NULL; |
1507 | 1507 | ||
1508 | // clear the password list | 1508 | // clear the password list |
1509 | QListViewItem *i; | 1509 | QListViewItem *i; |
1510 | // step through all categories | 1510 | // step through all categories |
1511 | for (i = ListView->firstChild(); | 1511 | for (i = ListView->firstChild(); |
1512 | i != NULL; | 1512 | i != NULL; |
1513 | i = i->nextSibling()) | 1513 | i = i->nextSibling()) |
1514 | { | 1514 | { |
1515 | // step through all subitems | 1515 | // step through all subitems |
1516 | QListViewItem *si; | 1516 | QListViewItem *si; |
1517 | for (si = i->firstChild(); | 1517 | for (si = i->firstChild(); |
1518 | si != NULL; ) | 1518 | si != NULL; ) |
1519 | { | 1519 | { |
1520 | QListViewItem *_si = si; | 1520 | QListViewItem *_si = si; |
1521 | si = si->nextSibling(); | 1521 | si = si->nextSibling(); |
1522 | i->takeItem(_si); // remove from view list | 1522 | i->takeItem(_si); // remove from view list |
1523 | if (_si) delete _si; | 1523 | if (_si) delete _si; |
1524 | } | 1524 | } |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | // ask for password and read again | 1527 | // ask for password and read again |
1528 | openDocument(filename); | 1528 | openDocument(filename); |
1529 | } | 1529 | } |
1530 | } | 1530 | } |
1531 | 1531 | ||
1532 | //--------------------------------------------- | 1532 | //--------------------------------------------- |
1533 | 1533 | ||
1534 | 1534 | ||
1535 | bool ZSafe::openDocument(const char* _filename, const char* ) | 1535 | bool ZSafe::openDocument(const char* _filename, const char* ) |
1536 | { | 1536 | { |
1537 | QString name= _filename; | 1537 | QString name= _filename; |
1538 | qWarning("openDocument "+name); | 1538 | qWarning("openDocument "+name); |
1539 | int retval; | 1539 | int retval; |
1540 | char* entry[FIELD_SIZE]; | 1540 | char* entry[FIELD_SIZE]; |
1541 | // #ifndef Q_WS_WIN | 1541 | // #ifndef Q_WS_WIN |
1542 | int validationFlag = conf->readNumEntry(APP_KEY+"valzsafe", 1); | 1542 | int validationFlag = conf->readNumEntry(APP_KEY+"valzsafe", 1); |
1543 | // #else | 1543 | // #else |
1544 | // int validationFlag = 1; | 1544 | // int validationFlag = 1; |
1545 | // #endif | 1545 | // #endif |
1546 | 1546 | ||
1547 | int pwdOk = 0; | 1547 | int pwdOk = 0; |
1548 | int numberOfTries = 3; | 1548 | int numberOfTries = 3; |
1549 | for (int i=0; i < numberOfTries; i++) | 1549 | for (int i=0; i < numberOfTries; i++) |
1550 | { | 1550 | { |
1551 | QFile f(_filename); | 1551 | QFile f(_filename); |
1552 | if (f.exists()) | 1552 | if (f.exists()) |
1553 | { | 1553 | { |
1554 | // ask with a dialog for the password | 1554 | // ask with a dialog for the password |
1555 | if (m_password.isEmpty()) | 1555 | if (m_password.isEmpty()) |
1556 | getDocPassword(tr("Enter Password")); | 1556 | getDocPassword(tr("Enter Password")); |
1557 | if (m_password.isEmpty() && validationFlag == 0) | 1557 | if (m_password.isEmpty() && validationFlag == 0) |
1558 | { | 1558 | { |
1559 | QMessageBox::critical( 0, tr("ZSafe"), | 1559 | QMessageBox::critical( 0, tr("ZSafe"), |
1560 | tr("Wrong password.\n\nZSafe will now exit.") ); | 1560 | tr("Wrong password.\n\nZSafe will now exit.") ); |
1561 | exitZs (1); | 1561 | exitZs (1); |
1562 | } | 1562 | } |
1563 | 1563 | ||
1564 | retval = loadInit(_filename, m_password); | 1564 | retval = loadInit(_filename, m_password); |
1565 | if (retval != PWERR_GOOD) | 1565 | if (retval != PWERR_GOOD) |
1566 | { | 1566 | { |
1567 | return false; | 1567 | return false; |
1568 | } | 1568 | } |
1569 | } | 1569 | } |
1570 | else | 1570 | else |
1571 | { | 1571 | { |
1572 | this->setCaption(tr("ZSafe")); | 1572 | this->setCaption(tr("ZSafe")); |
1573 | filename = ""; | 1573 | filename = ""; |
1574 | switch( QMessageBox::warning( this, tr("ZSafe"), | 1574 | switch( QMessageBox::warning( this, tr("ZSafe"), |
1575 | tr("<P>You must create a new document first. Ok to create?</P>"), | 1575 | tr("<P>You must create a new document first. Ok to create?</P>"), |
1576 | tr("&Yes"), tr("&No."), | 1576 | tr("&Yes"), tr("&No."), |
1577 | 0 | 1577 | 0 |
1578 | ) ) | 1578 | ) ) |
1579 | { | 1579 | { |
1580 | case 1: // No | 1580 | case 1: // No |
1581 | return false; | 1581 | return false; |
1582 | break; | 1582 | break; |
1583 | case 0: // Yes | 1583 | case 0: // Yes |
1584 | newDocument(); | 1584 | newDocument(); |
1585 | return false; | 1585 | return false; |
1586 | break; | 1586 | break; |
1587 | } | 1587 | } |
1588 | 1588 | ||
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | 1591 | ||
1592 | // load the validation entry | 1592 | // load the validation entry |
1593 | if (validationFlag == 0) | 1593 | if (validationFlag == 0) |
1594 | { | 1594 | { |
1595 | pwdOk = 1; | 1595 | pwdOk = 1; |
1596 | break; | 1596 | break; |
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | retval = loadEntry(entry); | 1599 | retval = loadEntry(entry); |
1600 | if (retval == 1 && | 1600 | if (retval == 1 && |
1601 | !strcmp (entry[0], "ZSAFECATEGORY") && | 1601 | !strcmp (entry[0], "ZSAFECATEGORY") && |
1602 | !strcmp (entry[1], "name") && | 1602 | !strcmp (entry[1], "name") && |
1603 | !strcmp (entry[2], "username") && | 1603 | !strcmp (entry[2], "username") && |
1604 | !strcmp (entry[3], "password") && | 1604 | !strcmp (entry[3], "password") && |
1605 | !strcmp (entry[4], "comment") ) | 1605 | !strcmp (entry[4], "comment") ) |
1606 | { | 1606 | { |
1607 | for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); | 1607 | for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); |
1608 | pwdOk = 1; | 1608 | pwdOk = 1; |
1609 | break; | 1609 | break; |
1610 | } | 1610 | } |
1611 | else | 1611 | else |
1612 | // for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); | 1612 | // for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); |
1613 | fclose (fd); | 1613 | fclose (fd); |
1614 | m_password = ""; | 1614 | m_password = ""; |
1615 | 1615 | ||
1616 | if (i < numberOfTries - 1) | 1616 | if (i < numberOfTries - 1) |
1617 | { | 1617 | { |
1618 | switch( QMessageBox::warning( this, tr("ZSafe"), | 1618 | switch( QMessageBox::warning( this, tr("ZSafe"), |
1619 | tr("Wrong password.\nEnter again?"), | 1619 | tr("Wrong password.\nEnter again?"), |
1620 | tr("&Yes"), tr("&No."), | 1620 | tr("&Yes"), tr("&No."), |
1621 | 0 | 1621 | 0 |
1622 | ) ) | 1622 | ) ) |
1623 | { | 1623 | { |
1624 | case 1: // No | 1624 | case 1: // No |
1625 | exitZs (1); | 1625 | exitZs (1); |
1626 | break; | 1626 | break; |
1627 | case 0: // Yes | 1627 | case 0: // Yes |
1628 | continue; | 1628 | continue; |
1629 | } | 1629 | } |
1630 | } | 1630 | } |
1631 | } | 1631 | } |
1632 | if (pwdOk == 0) | 1632 | if (pwdOk == 0) |
1633 | { | 1633 | { |
1634 | // unset the document entry | 1634 | // unset the document entry |
1635 | conf->writeEntry(APP_KEY+"document", "INVALIDPWD"); | 1635 | conf->writeEntry(APP_KEY+"document", "INVALIDPWD"); |
1636 | if (conf) | 1636 | if (conf) |
1637 | delete conf; | 1637 | delete conf; |
1638 | 1638 | ||
1639 | exitZs (1); | 1639 | exitZs (1); |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | 1642 | ||
1643 | retval = loadEntry(entry); | 1643 | retval = loadEntry(entry); |
1644 | 1644 | ||
1645 | int numberOfEntries=0; | 1645 | int numberOfEntries=0; |
1646 | while (retval == 1) { | 1646 | while (retval == 1) { |
1647 | 1647 | ||
1648 | QString category( QString::fromUtf8(entry[0]) ); | 1648 | QString category( QString::fromUtf8(entry[0]) ); |
1649 | QString name( QString::fromUtf8(entry[1]) ); | 1649 | QString name( QString::fromUtf8(entry[1]) ); |
1650 | QString user( QString::fromUtf8(entry[2]) ); | 1650 | QString user( QString::fromUtf8(entry[2]) ); |
1651 | QString password( QString::fromUtf8(entry[3]) ); | 1651 | QString password( QString::fromUtf8(entry[3]) ); |
1652 | QString comment( QString::fromUtf8(entry[4]) ); | 1652 | QString comment( QString::fromUtf8(entry[4]) ); |
1653 | QString field5( QString::fromUtf8(entry[5]) ); | 1653 | QString field5( QString::fromUtf8(entry[5]) ); |
1654 | QString field6( QString::fromUtf8(entry[6]) ); | 1654 | QString field6( QString::fromUtf8(entry[6]) ); |
1655 | // add the subitems to the categories | 1655 | // add the subitems to the categories |
1656 | 1656 | ||
1657 | Category *cat= categories.find (category); | 1657 | Category *cat= categories.find (category); |
1658 | if (cat) | 1658 | if (cat) |
1659 | { | 1659 | { |
1660 | // use the existend item | 1660 | // use the existend item |
1661 | QListViewItem *catItem = cat->getListItem(); | 1661 | QListViewItem *catItem = cat->getListItem(); |
1662 | if (catItem) | 1662 | if (catItem) |
1663 | { | 1663 | { |
1664 | QListViewItem * item = new ShadedListItem( 0, catItem ); | 1664 | QListViewItem * item = new ShadedListItem( 0, catItem ); |
1665 | item->setText( 0, tr( name ) ); | 1665 | item->setText( 0, tr( name ) ); |
1666 | item->setText( 1, tr( user ) ); | 1666 | item->setText( 1, tr( user ) ); |
1667 | item->setText( 2, tr( password ) ); | 1667 | item->setText( 2, tr( password ) ); |
1668 | item->setText( 3, tr( comment ) ); | 1668 | item->setText( 3, tr( comment ) ); |
1669 | item->setText( 4, tr( field5 ) ); | 1669 | item->setText( 4, tr( field5 ) ); |
1670 | item->setText( 5, tr( field6 ) ); | 1670 | item->setText( 5, tr( field6 ) ); |
1671 | 1671 | ||
1672 | if (expandTree) | 1672 | if (expandTree) |
1673 | catItem->setOpen( TRUE ); | 1673 | catItem->setOpen( TRUE ); |
1674 | numberOfEntries++; | 1674 | numberOfEntries++; |
1675 | } | 1675 | } |
1676 | } | 1676 | } |
1677 | else | 1677 | else |
1678 | { | 1678 | { |
1679 | QListViewItem *catI = new ShadedListItem( 1, ListView ); | 1679 | QListViewItem *catI = new ShadedListItem( 1, ListView ); |
1680 | // create and insert a new item | 1680 | // create and insert a new item |
1681 | QListViewItem * item = new ShadedListItem( 0, catI ); | 1681 | QListViewItem * item = new ShadedListItem( 0, catI ); |
1682 | 1682 | ||
1683 | item->setText( 0, tr( name ) ); | 1683 | item->setText( 0, tr( name ) ); |
1684 | item->setText( 1, tr( user ) ); | 1684 | item->setText( 1, tr( user ) ); |
1685 | item->setText( 2, tr( password ) ); | 1685 | item->setText( 2, tr( password ) ); |
1686 | item->setText( 3, tr( comment ) ); | 1686 | item->setText( 3, tr( comment ) ); |
1687 | item->setText( 4, tr( field5 ) ); | 1687 | item->setText( 4, tr( field5 ) ); |
1688 | item->setText( 5, tr( field6 ) ); | 1688 | item->setText( 5, tr( field6 ) ); |
1689 | 1689 | ||
1690 | if (expandTree) | 1690 | if (expandTree) |
1691 | catI->setOpen( TRUE ); | 1691 | catI->setOpen( TRUE ); |
1692 | 1692 | ||
1693 | Category *c1 = new Category(); | 1693 | Category *c1 = new Category(); |
1694 | c1->setCategoryName(category); | 1694 | c1->setCategoryName(category); |
1695 | 1695 | ||
1696 | QString icon; | 1696 | QString icon; |
1697 | QString fullIconPath; | 1697 | QString fullIconPath; |
1698 | QPixmap *pix; | 1698 | QPixmap *pix; |
1699 | // #ifndef Q_WS_WIN | 1699 | // #ifndef Q_WS_WIN |
1700 | icon = conf->readEntry(APP_KEY+category); | 1700 | icon = conf->readEntry(APP_KEY+category); |
1701 | // #endif | 1701 | // #endif |
1702 | bool isIconAv = false; | 1702 | bool isIconAv = false; |
1703 | if (!icon.isEmpty() && !icon.isNull()) | 1703 | if (!icon.isEmpty() && !icon.isNull()) |
1704 | { | 1704 | { |
1705 | // build the full path | 1705 | // build the full path |
1706 | fullIconPath = iconPath + icon; | 1706 | fullIconPath = iconPath + icon; |
1707 | pix = new QPixmap (fullIconPath); | 1707 | pix = new QPixmap (fullIconPath); |
1708 | if (!pix->isNull()) | 1708 | if (!pix->isNull()) |
1709 | { | 1709 | { |
1710 | QImage img = pix->convertToImage(); | 1710 | QImage img = pix->convertToImage(); |
1711 | pix->convertFromImage(img.smoothScale(14,14)); | 1711 | pix->convertFromImage(img.smoothScale(14,14)); |
1712 | c1->setIconName (icon); | 1712 | c1->setIconName (icon); |
1713 | c1->setIcon (*pix); | 1713 | c1->setIcon (*pix); |
1714 | isIconAv = true; | 1714 | isIconAv = true; |
1715 | } | 1715 | } |
1716 | } | 1716 | } |
1717 | if (!isIconAv) | 1717 | if (!isIconAv) |
1718 | { | 1718 | { |
1719 | c1->setIcon (*getPredefinedIcon(category)); | 1719 | c1->setIcon (*getPredefinedIcon(category)); |
1720 | } | 1720 | } |
1721 | 1721 | ||
1722 | c1->setListItem (catI); | 1722 | c1->setListItem (catI); |
1723 | c1->initListItem(); | 1723 | c1->initListItem(); |
1724 | categories.insert (c1->getCategoryName(), c1); | 1724 | categories.insert (c1->getCategoryName(), c1); |
1725 | numberOfEntries++; | 1725 | numberOfEntries++; |
1726 | } | 1726 | } |
1727 | 1727 | ||
1728 | for (int count = 0; count < FIELD_SIZE; count++) { | 1728 | for (int count = 0; count < FIELD_SIZE; count++) { |
1729 | free(entry[count]); | 1729 | free(entry[count]); |
1730 | } | 1730 | } |
1731 | retval = loadEntry(entry); | 1731 | retval = loadEntry(entry); |
1732 | if (retval == 2) { | 1732 | if (retval == 2) { |
1733 | // m_parent->slotStatusHelpMsg("Last entry loaded"); | 1733 | // m_parent->slotStatusHelpMsg("Last entry loaded"); |
1734 | } | 1734 | } |
1735 | } // end while | 1735 | } // end while |
1736 | 1736 | ||
1737 | if (numberOfEntries == 0) | 1737 | if (numberOfEntries == 0) |
1738 | { | 1738 | { |
1739 | 1739 | ||
1740 | switch( QMessageBox::warning( this, tr("ZSafe"), | 1740 | switch( QMessageBox::warning( this, tr("ZSafe"), |
1741 | tr("Empty document or\nwrong password.\nContinue?"), | 1741 | tr("Empty document or\nwrong password.\nContinue?"), |
1742 | tr("&No"), tr("&Yes."), | 1742 | tr("&No"), tr("&Yes."), |
1743 | 0 | 1743 | 0 |
1744 | ) ) { | 1744 | ) ) { |
1745 | case 0: // No | 1745 | case 0: // No |
1746 | retval = loadFinalize(); | 1746 | retval = loadFinalize(); |
1747 | exitZs (1); | 1747 | exitZs (1); |
1748 | break; | 1748 | break; |
1749 | case 1: // Yes | 1749 | case 1: // Yes |
1750 | break; | 1750 | break; |
1751 | } | 1751 | } |
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | retval = loadFinalize(); | 1754 | retval = loadFinalize(); |
1755 | 1755 | ||
1756 | return true; | 1756 | return true; |
1757 | } | 1757 | } |
1758 | 1758 | ||
1759 | int ZSafe::loadInit(const char* _filename, const char *password) | 1759 | int ZSafe::loadInit(const char* _filename, const char *password) |
1760 | { | 1760 | { |
1761 | unsigned int j = 0; | 1761 | unsigned int j = 0; |
1762 | unsigned int keylength=0; | 1762 | unsigned int keylength=0; |
1763 | int count=0, count2=0, count3=0; | 1763 | int count=0, count2=0, count3=0; |
1764 | unsigned char charbuf[8]; | 1764 | unsigned char charbuf[8]; |
1765 | unsigned short ciphertext[4]; | 1765 | unsigned short ciphertext[4]; |
1766 | char key[128]; | 1766 | char key[128]; |
1767 | Krc2* krc2 = new Krc2(); | 1767 | Krc2* krc2 = new Krc2(); |
1768 | 1768 | ||
1769 | fd = fopen (_filename, "rb"); | 1769 | fd = fopen (_filename, "rb"); |
1770 | 1770 | ||
1771 | QFileInfo f (_filename); | 1771 | QFileInfo f (_filename); |
1772 | load_buffer_length = f.size(); | 1772 | load_buffer_length = f.size(); |
1773 | load_buffer_length = ((load_buffer_length / 1024)+1) * 1024 * 2; | 1773 | load_buffer_length = ((load_buffer_length / 1024)+1) * 1024 * 2; |
1774 | 1774 | ||
1775 | if (fd == NULL) | 1775 | if (fd == NULL) { |
1776 | delete krc2; | ||
1776 | return PWERR_OPEN; | 1777 | return PWERR_OPEN; |
1778 | } | ||
1777 | 1779 | ||
1778 | buffer = (char *)malloc(load_buffer_length); | 1780 | buffer = (char *)malloc(load_buffer_length); |
1779 | for (j = 0; password[j] != '\0'; j++) { | 1781 | for (j = 0; password[j] != '\0'; j++) { |
1780 | key[j] = password[j]; | 1782 | key[j] = password[j]; |
1781 | } | 1783 | } |
1782 | keylength = j; | 1784 | keylength = j; |
1783 | krc2->rc2_expandkey (key, keylength, 128); | 1785 | krc2->rc2_expandkey (key, keylength, 128); |
1784 | 1786 | ||
1785 | #ifndef Q_WS_WIN | 1787 | #ifndef Q_WS_WIN |
1786 | size = read(fileno (fd), (unsigned char *) (charbuf + count), 8); | 1788 | size = read(fileno (fd), (unsigned char *) (charbuf + count), 8); |
1787 | #else | 1789 | #else |
1788 | size = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); | 1790 | size = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); |
1789 | #endif | 1791 | #endif |
1790 | 1792 | ||
1791 | if (size < 8) | 1793 | if (size < 8) { |
1794 | delete krc2; | ||
1792 | return PWERR_DATA; | 1795 | return PWERR_DATA; |
1796 | } | ||
1793 | 1797 | ||
1794 | for (count = 0; count < 4; count++) { | 1798 | for (count = 0; count < 4; count++) { |
1795 | count2 = count << 1; | 1799 | count2 = count << 1; |
1796 | iv[count] = charbuf[count2] << 8; | 1800 | iv[count] = charbuf[count2] << 8; |
1797 | iv[count] += charbuf[count2 + 1]; | 1801 | iv[count] += charbuf[count2 + 1]; |
1798 | } | 1802 | } |
1799 | 1803 | ||
1800 | size = 0; | 1804 | size = 0; |
1801 | bufferIndex = 0; | 1805 | bufferIndex = 0; |
1802 | #ifndef Q_WS_WIN | 1806 | #ifndef Q_WS_WIN |
1803 | while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) { | 1807 | while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) { |
1804 | while (count < 8) { | 1808 | while (count < 8) { |
1805 | count2 = read (fileno (fd), (unsigned char *) (charbuf + count), 8); | 1809 | count2 = read (fileno (fd), (unsigned char *) (charbuf + count), 8); |
1806 | #else | 1810 | #else |
1807 | while ((count = fread ((unsigned char *) (charbuf), sizeof(unsigned char), 8, fd)) > 0) { | 1811 | while ((count = fread ((unsigned char *) (charbuf), sizeof(unsigned char), 8, fd)) > 0) { |
1808 | while (count < 8) { | 1812 | while (count < 8) { |
1809 | count2 = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); | 1813 | count2 = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); |
1810 | #endif | 1814 | #endif |
1811 | if (count2 == 0) { | 1815 | if (count2 == 0) { |
1816 | delete krc2; | ||
1812 | return PWERR_DATA; | 1817 | return PWERR_DATA; |
1813 | } | 1818 | } |
1814 | count += count2; | 1819 | count += count2; |
1815 | } /* while (count < 8) */ | 1820 | } /* while (count < 8) */ |
1816 | 1821 | ||
1817 | size += 8; | 1822 | size += 8; |
1818 | for (count2 = 0; count2 < 8; count2 += 2) { | 1823 | for (count2 = 0; count2 < 8; count2 += 2) { |
1819 | count3 = count2 >> 1; | 1824 | count3 = count2 >> 1; |
1820 | ciphertext[count3] = charbuf[count2] << 8; | 1825 | ciphertext[count3] = charbuf[count2] << 8; |
1821 | ciphertext[count3] += charbuf[count2 + 1]; | 1826 | ciphertext[count3] += charbuf[count2 + 1]; |
1822 | 1827 | ||
1823 | plaintext[count3] = ciphertext[count3] ^ iv[count3]; | 1828 | plaintext[count3] = ciphertext[count3] ^ iv[count3]; |
1824 | iv[count3] = plaintext[count3]; | 1829 | iv[count3] = plaintext[count3]; |
1825 | } /* for (count2) */ | 1830 | } /* for (count2) */ |
1826 | 1831 | ||
1827 | krc2->rc2_decrypt (plaintext); | 1832 | krc2->rc2_decrypt (plaintext); |
1828 | memcpy ((unsigned char *) (buffer + bufferIndex), plaintext, 8); | 1833 | memcpy ((unsigned char *) (buffer + bufferIndex), plaintext, 8); |
1829 | bufferIndex += 8; | 1834 | bufferIndex += 8; |
1830 | buffer[bufferIndex + 1] = '\0'; | 1835 | buffer[bufferIndex + 1] = '\0'; |
1831 | } /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */ | 1836 | } /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */ |
1837 | delete krc2; | ||
1832 | size -= buffer[size - 1]; | 1838 | size -= buffer[size - 1]; |
1833 | lastcount = 0; | 1839 | lastcount = 0; |
1834 | 1840 | ||
1835 | /* This will point to the starting index */ | 1841 | /* This will point to the starting index */ |
1836 | bufferIndex = 0; | 1842 | bufferIndex = 0; |
1837 | return PWERR_GOOD; | 1843 | return PWERR_GOOD; |
1838 | } | 1844 | } |
1839 | 1845 | ||
1840 | int ZSafe::loadEntry(char *entry[FIELD_SIZE]) | 1846 | int ZSafe::loadEntry(char *entry[FIELD_SIZE]) |
1841 | { | 1847 | { |
1842 | /* Strip off PKCS 5 padding | 1848 | /* Strip off PKCS 5 padding |
1843 | * Should check to make sure it's good here | 1849 | * Should check to make sure it's good here |
1844 | */ | 1850 | */ |
1845 | int count, count1=0; | 1851 | int count, count1=0; |
1846 | 1852 | ||
1847 | for (count = lastcount; count < size; count++) { | 1853 | for (count = lastcount; count < size; count++) { |
1848 | if ((unsigned char) (buffer[count]) == 255) { | 1854 | if ((unsigned char) (buffer[count]) == 255) { |
1849 | if (buffer[bufferIndex] == '\0') { | 1855 | if (buffer[bufferIndex] == '\0') { |
1850 | bufferIndex++; | 1856 | bufferIndex++; |
1851 | } | 1857 | } |
1852 | entry[count1] = (char *) malloc (count - bufferIndex + 1); | 1858 | entry[count1] = (char *) malloc (count - bufferIndex + 1); |
1853 | memcpy (entry[count1], (unsigned char *) (buffer + bufferIndex), count - bufferIndex); | 1859 | memcpy (entry[count1], (unsigned char *) (buffer + bufferIndex), count - bufferIndex); |
1854 | entry[count1][count - bufferIndex] = '\0'; | 1860 | entry[count1][count - bufferIndex] = '\0'; |
1855 | count++; | 1861 | count++; |
1856 | bufferIndex = count; | 1862 | bufferIndex = count; |
1857 | count1++; | 1863 | count1++; |
1858 | if (count1 == FIELD_SIZE) { | 1864 | if (count1 == FIELD_SIZE) { |
1859 | lastcount = count; | 1865 | lastcount = count; |
1860 | return 1; | 1866 | return 1; |
1861 | } | 1867 | } |
1862 | } /* if ((unsigned char) (buffer[count]) == 255) */ | 1868 | } /* if ((unsigned char) (buffer[count]) == 255) */ |
1863 | } /* for (count = 0; count < size; count++) */ | 1869 | } /* for (count = 0; count < size; count++) */ |
1864 | 1870 | ||
1865 | return 2; | 1871 | return 2; |
1866 | } | 1872 | } |
1867 | 1873 | ||
1868 | int ZSafe::loadFinalize(void) | 1874 | int ZSafe::loadFinalize(void) |
1869 | { | 1875 | { |
1870 | fclose (fd); | 1876 | fclose (fd); |
1871 | if (buffer) free(buffer); | 1877 | if (buffer) free(buffer); |
1872 | return PWERR_GOOD; | 1878 | return PWERR_GOOD; |
1873 | } | 1879 | } |
1874 | 1880 | ||
1875 | bool ZSafe::saveDocument(const char* _filename, | 1881 | bool ZSafe::saveDocument(const char* _filename, |
1876 | bool withPwd, | 1882 | bool withPwd, |
1877 | const char* ) | 1883 | const char* ) |
1878 | { | 1884 | { |
1879 | if (filename.isEmpty()) | 1885 | if (filename.isEmpty()) |
1880 | { | 1886 | { |
1881 | QMessageBox::critical( 0, tr("ZSafe"), | 1887 | QMessageBox::critical( 0, tr("ZSafe"), |
1882 | tr("No document defined.\nYou have to create a new document")); | 1888 | tr("No document defined.\nYou have to create a new document")); |
1883 | return false; | 1889 | return false; |
1884 | } | 1890 | } |
1885 | 1891 | ||
1886 | // if (m_password.isEmpty()) | 1892 | // if (m_password.isEmpty()) |
1887 | // withPwd = true; // the document must be saved with a valid password | 1893 | // withPwd = true; // the document must be saved with a valid password |
1888 | if (withPwd) | 1894 | if (withPwd) |
1889 | { | 1895 | { |
1890 | bool pwdOk = FALSE; | 1896 | bool pwdOk = FALSE; |
1891 | while (!pwdOk) | 1897 | while (!pwdOk) |
1892 | { | 1898 | { |
1893 | getDocPassword(tr("Enter Password")); | 1899 | getDocPassword(tr("Enter Password")); |
1894 | if (m_password.isEmpty()) | 1900 | if (m_password.isEmpty()) |
1895 | { | 1901 | { |
1896 | 1902 | ||
1897 | QMessageBox::critical( 0, tr("ZSafe"), | 1903 | QMessageBox::critical( 0, tr("ZSafe"), |
1898 | tr("Password is empty.\nPlease enter again.")); | 1904 | tr("Password is empty.\nPlease enter again.")); |
1899 | continue; | 1905 | continue; |
1900 | } | 1906 | } |
1901 | 1907 | ||
1902 | QString firstPasswd = m_password; | 1908 | QString firstPasswd = m_password; |
1903 | 1909 | ||
1904 | getDocPassword(tr("Reenter Password")); | 1910 | getDocPassword(tr("Reenter Password")); |
1905 | if (m_password.isEmpty()) | 1911 | if (m_password.isEmpty()) |
1906 | { | 1912 | { |
1907 | QMessageBox::critical( 0, tr("ZSafe"), | 1913 | QMessageBox::critical( 0, tr("ZSafe"), |
1908 | tr("Password is empty.\nPlease enter again.")); | 1914 | tr("Password is empty.\nPlease enter again.")); |
1909 | continue; | 1915 | continue; |
1910 | } | 1916 | } |
1911 | if (firstPasswd != m_password) | 1917 | if (firstPasswd != m_password) |
1912 | { | 1918 | { |
1913 | 1919 | ||
1914 | QMessageBox::critical( 0, tr("ZSafe"), | 1920 | QMessageBox::critical( 0, tr("ZSafe"), |
1915 | tr("Passwords must be identical.\nPlease enter again.")); | 1921 | tr("Passwords must be identical.\nPlease enter again.")); |
1916 | continue; | 1922 | continue; |
1917 | } | 1923 | } |
1918 | pwdOk = TRUE; | 1924 | pwdOk = TRUE; |
1919 | modified = false; | 1925 | modified = false; |
1920 | } | 1926 | } |
1921 | } | 1927 | } |
1922 | else if (modified) | 1928 | else if (modified) |
1923 | { | 1929 | { |
1924 | QString fns(_filename); | 1930 | QString fns(_filename); |
1925 | fns = fns.right (fns.length() - fns.findRev ('/') - 1); | 1931 | fns = fns.right (fns.length() - fns.findRev ('/') - 1); |
1926 | switch( QMessageBox::information( this, tr("ZSafe"), | 1932 | switch( QMessageBox::information( this, tr("ZSafe"), |
1927 | tr("Do you want to save ") + fns + tr("\nbefore continuing?"), | 1933 | tr("Do you want to save ") + fns + tr("\nbefore continuing?"), |
1928 | tr("&Save"), | 1934 | tr("&Save"), |
1929 | tr("&Don't Save"), | 1935 | tr("&Don't Save"), |
1930 | 0 // Enter == button 0 | 1936 | 0 // Enter == button 0 |
1931 | ) ) | 1937 | ) ) |
1932 | { // Escape == button 2 | 1938 | { // Escape == button 2 |
1933 | case 0: // Save clicked, Alt-S or Enter pressed. | 1939 | case 0: // Save clicked, Alt-S or Enter pressed. |
1934 | modified = false; | 1940 | modified = false; |
1935 | break; | 1941 | break; |
1936 | case 1: // Don't Save clicked or Alt-D pressed | 1942 | case 1: // Don't Save clicked or Alt-D pressed |
1937 | modified = false; | 1943 | modified = false; |
1938 | return true; | 1944 | return true; |
1939 | } | 1945 | } |
1940 | } | 1946 | } |
1941 | modified = false; | 1947 | modified = false; |
1942 | 1948 | ||
1943 | if (m_password.isEmpty()) | 1949 | if (m_password.isEmpty()) |
1944 | return false; | 1950 | return false; |
1945 | 1951 | ||
1946 | int retval = saveInit(_filename, m_password); | 1952 | int retval = saveInit(_filename, m_password); |
1947 | // int retval = saveInit(_filename, "test"); | 1953 | // int retval = saveInit(_filename, "test"); |
1948 | if (retval != PWERR_GOOD) { | 1954 | if (retval != PWERR_GOOD) { |
1949 | return false; | 1955 | return false; |
1950 | } | 1956 | } |
1951 | 1957 | ||
1952 | char* entry[FIELD_SIZE]; | 1958 | char* entry[FIELD_SIZE]; |
1953 | 1959 | ||
1954 | // save the validation entry | 1960 | // save the validation entry |
1955 | { | 1961 | { |
1956 | int i=0; | 1962 | int i=0; |
1957 | entry[i] = (char*)malloc(strlen("ZSAFECATEGORY")+1); | 1963 | entry[i] = (char*)malloc(strlen("ZSAFECATEGORY")+1); |
1958 | strcpy(entry[i++], "ZSAFECATEGORY"); | 1964 | strcpy(entry[i++], "ZSAFECATEGORY"); |
1959 | entry[i] = (char*)malloc(strlen("name")+1); | 1965 | entry[i] = (char*)malloc(strlen("name")+1); |
1960 | strcpy(entry[i++], "name"); | 1966 | strcpy(entry[i++], "name"); |
1961 | entry[i] = (char*)malloc(strlen("username")+1); | 1967 | entry[i] = (char*)malloc(strlen("username")+1); |
1962 | strcpy(entry[i++], "username"); | 1968 | strcpy(entry[i++], "username"); |
1963 | entry[i] = (char*)malloc(strlen("password")+1); | 1969 | entry[i] = (char*)malloc(strlen("password")+1); |
1964 | strcpy(entry[i++], "password"); | 1970 | strcpy(entry[i++], "password"); |
1965 | entry[i] = (char*)malloc(strlen("comment")+1); | 1971 | entry[i] = (char*)malloc(strlen("comment")+1); |
1966 | strcpy(entry[i++], "comment"); | 1972 | strcpy(entry[i++], "comment"); |
1967 | 1973 | ||
1968 | entry[i] = (char*)malloc(strlen("field5")+1); | 1974 | entry[i] = (char*)malloc(strlen("field5")+1); |
1969 | strcpy(entry[i++], "field5"); | 1975 | strcpy(entry[i++], "field5"); |
1970 | entry[i] = (char*)malloc(strlen("field6")+1); | 1976 | entry[i] = (char*)malloc(strlen("field6")+1); |
1971 | strcpy(entry[i++], "field6"); | 1977 | strcpy(entry[i++], "field6"); |
1972 | 1978 | ||
1973 | retval = saveEntry(entry); | 1979 | retval = saveEntry(entry); |
1974 | for (int z=0; z<i; z++) free(entry[z]); | 1980 | for (int z=0; z<i; z++) free(entry[z]); |
1975 | if (retval == PWERR_DATA) { | 1981 | if (retval == PWERR_DATA) { |
1976 | #ifndef NO_OPIE | 1982 | #ifndef NO_OPIE |
1977 | owarn << "1: Error writing file, contents not saved" << oendl; | 1983 | owarn << "1: Error writing file, contents not saved" << oendl; |
1978 | #else | 1984 | #else |
1979 | qWarning("1: Error writing file, contents not saved"); | 1985 | qWarning("1: Error writing file, contents not saved"); |
1980 | #endif | 1986 | #endif |
1981 | saveFinalize(); | 1987 | saveFinalize(); |
1982 | return false; | 1988 | return false; |
1983 | } | 1989 | } |
1984 | // #ifndef Q_WS_WIN | 1990 | // #ifndef Q_WS_WIN |
1985 | conf->writeEntry(APP_KEY+"valzsafe", 1); | 1991 | conf->writeEntry(APP_KEY+"valzsafe", 1); |
1986 | // #endif | 1992 | // #endif |
1987 | saveConf(); | 1993 | saveConf(); |
1988 | } | 1994 | } |
1989 | 1995 | ||
1990 | QListViewItem *i; | 1996 | QListViewItem *i; |
1991 | // step through all categories | 1997 | // step through all categories |
1992 | for (i = ListView->firstChild(); | 1998 | for (i = ListView->firstChild(); |
1993 | i != NULL; | 1999 | i != NULL; |
1994 | i = i->nextSibling()) | 2000 | i = i->nextSibling()) |
1995 | { | 2001 | { |
1996 | // step through all subitems | 2002 | // step through all subitems |
1997 | QListViewItem *si; | 2003 | QListViewItem *si; |
1998 | for (si = i->firstChild(); | 2004 | for (si = i->firstChild(); |
1999 | si != NULL; | 2005 | si != NULL; |
2000 | si = si->nextSibling()) | 2006 | si = si->nextSibling()) |
2001 | { | 2007 | { |
2002 | int j=0; | 2008 | int j=0; |
2003 | entry[j] = (char*)malloc(strlen(i->text(0).utf8())+1); | 2009 | entry[j] = (char*)malloc(strlen(i->text(0).utf8())+1); |
2004 | strcpy(entry[j++], i->text(0).utf8()); | 2010 | strcpy(entry[j++], i->text(0).utf8()); |
2005 | entry[j] = (char*)malloc(strlen(si->text(0).utf8())+1); | 2011 | entry[j] = (char*)malloc(strlen(si->text(0).utf8())+1); |
2006 | strcpy(entry[j++], si->text(0).utf8()); | 2012 | strcpy(entry[j++], si->text(0).utf8()); |
2007 | entry[j] = (char*)malloc(strlen(si->text(1).utf8())+1); | 2013 | entry[j] = (char*)malloc(strlen(si->text(1).utf8())+1); |
2008 | strcpy(entry[j++], si->text(1).utf8()); | 2014 | strcpy(entry[j++], si->text(1).utf8()); |
2009 | entry[j] = (char*)malloc(strlen(si->text(2).utf8())+1); | 2015 | entry[j] = (char*)malloc(strlen(si->text(2).utf8())+1); |
2010 | strcpy(entry[j++], si->text(2).utf8()); | 2016 | strcpy(entry[j++], si->text(2).utf8()); |
2011 | entry[j] = (char*)malloc(strlen(si->text(3).utf8())+1); | 2017 | entry[j] = (char*)malloc(strlen(si->text(3).utf8())+1); |
2012 | strcpy(entry[j++], si->text(3).utf8()); | 2018 | strcpy(entry[j++], si->text(3).utf8()); |
2013 | entry[j] = (char*)malloc(strlen(si->text(4).utf8())+1); | 2019 | entry[j] = (char*)malloc(strlen(si->text(4).utf8())+1); |
2014 | strcpy(entry[j++], si->text(4).utf8()); | 2020 | strcpy(entry[j++], si->text(4).utf8()); |
2015 | entry[j] = (char*)malloc(strlen(si->text(5).utf8())+1); | 2021 | entry[j] = (char*)malloc(strlen(si->text(5).utf8())+1); |
2016 | strcpy(entry[j++], si->text(5).utf8()); | 2022 | strcpy(entry[j++], si->text(5).utf8()); |
2017 | 2023 | ||
2018 | retval = saveEntry(entry); | 2024 | retval = saveEntry(entry); |
2019 | for (int z=0; z<j; z++) | 2025 | for (int z=0; z<j; z++) |
2020 | { | 2026 | { |
2021 | free(entry[z]); | 2027 | free(entry[z]); |
2022 | } | 2028 | } |
2023 | if (retval == PWERR_DATA) { | 2029 | if (retval == PWERR_DATA) { |
2024 | #ifndef NO_OPIE | 2030 | #ifndef NO_OPIE |
2025 | owarn << "1: Error writing file, contents not saved" << oendl; | 2031 | owarn << "1: Error writing file, contents not saved" << oendl; |
2026 | #else | 2032 | #else |
2027 | qWarning("1: Error writing file, contents not saved"); | 2033 | qWarning("1: Error writing file, contents not saved"); |
2028 | #endif | 2034 | #endif |
2029 | saveFinalize(); | 2035 | saveFinalize(); |
2030 | return false; | 2036 | return false; |
2031 | } | 2037 | } |
2032 | 2038 | ||
2033 | } | 2039 | } |
2034 | } | 2040 | } |
2035 | 2041 | ||
2036 | if (saveFinalize() == PWERR_DATA) { | 2042 | if (saveFinalize() == PWERR_DATA) { |
2037 | #ifndef NO_OPIE | 2043 | #ifndef NO_OPIE |
2038 | owarn << "2: Error writing file, contents not saved" << oendl; | 2044 | owarn << "2: Error writing file, contents not saved" << oendl; |
2039 | #else | 2045 | #else |
2040 | qWarning("2: Error writing file, contents not saved"); | 2046 | qWarning("2: Error writing file, contents not saved"); |
2041 | #endif | 2047 | #endif |
2042 | return false; | 2048 | return false; |
2043 | } else { | 2049 | } else { |
2044 | #ifndef DESKTOP | 2050 | #ifndef DESKTOP |
2045 | Global::statusMessage (tr("Password file saved.")); | 2051 | Global::statusMessage (tr("Password file saved.")); |
2046 | #endif | 2052 | #endif |
2047 | modified = false; | 2053 | modified = false; |
2048 | return true; | 2054 | return true; |
2049 | } | 2055 | } |
2050 | } | 2056 | } |
2051 | 2057 | ||
2052 | PasswordForm *newPwdDialog; | 2058 | PasswordForm *newPwdDialog; |
2053 | bool newPwdDialogResult = false; | 2059 | bool newPwdDialogResult = false; |
2054 | void ZSafe::setPasswordDialogDone() | 2060 | void ZSafe::setPasswordDialogDone() |
2055 | { | 2061 | { |
2056 | newPwdDialogResult = true; | 2062 | newPwdDialogResult = true; |
2057 | newPwdDialog->close(); | 2063 | newPwdDialog->close(); |
2058 | } | 2064 | } |
2059 | 2065 | ||
2060 | void ZSafe::getDocPassword(QString title) | 2066 | void ZSafe::getDocPassword(QString title) |
2061 | { | 2067 | { |
2062 | // open the 'Password' dialog | 2068 | // open the 'Password' dialog |
2063 | PasswordForm *dialog = new PasswordForm(this, title, TRUE); | 2069 | PasswordForm *dialog = new PasswordForm(this, title, TRUE); |
2064 | newPwdDialog = dialog; | 2070 | newPwdDialog = dialog; |
2065 | newPwdDialogResult = false; | 2071 | newPwdDialogResult = false; |
2066 | 2072 | ||
2067 | // QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon ); | 2073 | // QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon ); |
2068 | // dialog->setIcon( image0); | 2074 | // dialog->setIcon( image0); |
2069 | 2075 | ||
2070 | connect( dialog->PasswordField, SIGNAL( returnPressed() ), | 2076 | connect( dialog->PasswordField, SIGNAL( returnPressed() ), |
2071 | this, SLOT( setPasswordDialogDone() ) ); | 2077 | this, SLOT( setPasswordDialogDone() ) ); |
2072 | 2078 | ||
2073 | // CS: !!! | 2079 | // CS: !!! |
2074 | // int pos = filename.findRev ('/'); | 2080 | // int pos = filename.findRev ('/'); |
2075 | QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); | 2081 | QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); |
2076 | dialog->setCaption(ti); | 2082 | dialog->setCaption(ti); |
2077 | // dialog->setCaption(title); | 2083 | // dialog->setCaption(title); |
2078 | 2084 | ||
2079 | dialog->PasswordField->setFocus(); | 2085 | dialog->PasswordField->setFocus(); |
2080 | QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); | 2086 | QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); |
2081 | 2087 | ||
2082 | QString password; | 2088 | QString password; |
2083 | if (result == QDialog::Accepted || newPwdDialogResult) | 2089 | if (result == QDialog::Accepted || newPwdDialogResult) |
2084 | { | 2090 | { |
2085 | m_password = dialog->PasswordField->text(); | 2091 | m_password = dialog->PasswordField->text(); |
2086 | } | 2092 | } |
2087 | else | 2093 | else |
2088 | { | 2094 | { |
2089 | exitZs (1); | 2095 | exitZs (1); |
2090 | } | 2096 | } |
2091 | } | 2097 | } |
2092 | 2098 | ||
2093 | int ZSafe::saveInit(const char *_filename, const char *password) | 2099 | int ZSafe::saveInit(const char *_filename, const char *password) |
2094 | { | 2100 | { |
2095 | char key[128]; | 2101 | char key[128]; |
2096 | unsigned int j = 0; | 2102 | unsigned int j = 0; |
2097 | unsigned int keylength; | 2103 | unsigned int keylength; |
2098 | // int val; | 2104 | // int val; |
2099 | int count2; | 2105 | int count2; |
2100 | Krc2* krc2 = new Krc2(); | 2106 | Krc2* krc2 = new Krc2(); |
2101 | 2107 | ||
2102 | /* first we should check the permissions of the filename */ | 2108 | QFileInfo f (_filename); |
2103 | /* | 2109 | save_buffer_length = f.size(); |
2104 | if (QFile::exists(_filename)) { | 2110 | save_buffer_length = ((save_buffer_length / 1024)+1) * 1024; |
2105 | val = checkFile(_filename); | ||
2106 | if (val != PWERR_GOOD) | ||
2107 | return val; | ||
2108 | } else | ||
2109 | { | ||
2110 | val = creat (_filename, (S_IRUSR | S_IWUSR)); | ||
2111 | if (val == -1) | ||
2112 | return PWERR_OPEN; | ||
2113 | else | ||
2114 | close(val); | ||
2115 | } | ||
2116 | */ | ||
2117 | QFileInfo f (_filename); | ||
2118 | save_buffer_length = f.size(); | ||
2119 | save_buffer_length = ((save_buffer_length / 1024)+1) * 1024; | ||
2120 | 2111 | ||
2121 | fd = fopen (_filename, "wb"); | 2112 | fd = fopen (_filename, "wb"); |
2122 | if (fd == NULL) | 2113 | if (fd == NULL) { |
2114 | delete krc2; | ||
2123 | return PWERR_OPEN; | 2115 | return PWERR_OPEN; |
2116 | } | ||
2124 | 2117 | ||
2125 | buffer = (char*)malloc(save_buffer_length); | 2118 | buffer = (char*)malloc(save_buffer_length); |
2126 | 2119 | ||
2127 | /* make the key ready */ | 2120 | /* make the key ready */ |
2128 | for (j = 0; password[j] != '\0'; j++) { | 2121 | for (j = 0; password[j] != '\0'; j++) { |
2129 | key[j] = password[j]; | 2122 | key[j] = password[j]; |
2130 | } | 2123 | } |
2131 | keylength = j; | 2124 | keylength = j; |
2132 | krc2->rc2_expandkey (key, keylength, 128); | 2125 | krc2->rc2_expandkey (key, keylength, 128); |
2126 | delete krc2; | ||
2133 | 2127 | ||
2134 | /* First, we make the IV */ | 2128 | /* First, we make the IV */ |
2135 | for (count2 = 0; count2 < 4; count2++) { | 2129 | for (count2 = 0; count2 < 4; count2++) { |
2136 | iv[count2] = rand (); | 2130 | iv[count2] = rand (); |
2137 | putc ((unsigned char) (iv[count2] >> 8), fd); | 2131 | putc ((unsigned char) (iv[count2] >> 8), fd); |
2138 | putc ((unsigned char) (iv[count2] & 0xff), fd); | 2132 | putc ((unsigned char) (iv[count2] & 0xff), fd); |
2139 | } | 2133 | } |
2140 | 2134 | ||
2141 | bufferIndex = 0; | 2135 | bufferIndex = 0; |
2142 | return PWERR_GOOD; | 2136 | return PWERR_GOOD; |
2143 | } | 2137 | } |
2144 | 2138 | ||
2145 | 2139 | ||
2146 | int ZSafe::saveEntry(char *entry[FIELD_SIZE]) | 2140 | int ZSafe::saveEntry(char *entry[FIELD_SIZE]) |
2147 | { | 2141 | { |
2148 | char *text1; | 2142 | char *text1; |
2149 | int count2, count3; | 2143 | int count2, count3; |
2150 | unsigned short ciphertext[4]; | 2144 | unsigned short ciphertext[4]; |
2151 | Krc2* krc2 = new Krc2(); | 2145 | Krc2* krc2 = new Krc2(); |
2152 | 2146 | ||
2153 | buffer = (char*)memset(buffer, '\0', save_buffer_length); | 2147 | buffer = (char*)memset(buffer, '\0', save_buffer_length); |
2154 | 2148 | ||
2155 | for (count2 = 0; count2 < FIELD_SIZE; count2++) { | 2149 | for (count2 = 0; count2 < FIELD_SIZE; count2++) { |
2156 | text1 = entry[count2]; | 2150 | text1 = entry[count2]; |
2157 | if (strlen (text1) == 0) { | 2151 | if (strlen (text1) == 0) { |
2158 | strncat(buffer, " ", strlen(" ")); | 2152 | strncat(buffer, " ", strlen(" ")); |
2159 | } else { | 2153 | } else { |
2160 | strncat(buffer, text1, strlen(text1)); | 2154 | strncat(buffer, text1, strlen(text1)); |
2161 | } | 2155 | } |
2162 | /* Use 255 as the marker. \n is too tough to test for */ | 2156 | /* Use 255 as the marker. \n is too tough to test for */ |
2163 | buffer[strlen (buffer)] = 255; | 2157 | buffer[strlen (buffer)] = 255; |
2164 | } /*for (count2 = 0; count2 < 5; count2++)*/ | 2158 | } /*for (count2 = 0; count2 < 5; count2++)*/ |
2165 | count2 = 0; | 2159 | count2 = 0; |
2166 | /* I'm using CBC mode and encrypting the data straight from top down. | 2160 | /* I'm using CBC mode and encrypting the data straight from top down. |
2167 | * At the bottom, encrypted, I will append an MD5 hash of the file, eventually. | 2161 | * At the bottom, encrypted, I will append an MD5 hash of the file, eventually. |
2168 | * PKCS 5 padding (explained at the code section | 2162 | * PKCS 5 padding (explained at the code section |
2169 | */ | 2163 | */ |
2170 | while (count2 < (int)strlen (buffer)) { | 2164 | while (count2 < (int)strlen (buffer)) { |
2171 | #ifndef WORDS_BIGENDIAN | 2165 | #ifndef WORDS_BIGENDIAN |
2172 | plaintext[bufferIndex] = buffer[count2 + 1] << 8; | 2166 | plaintext[bufferIndex] = buffer[count2 + 1] << 8; |
2173 | plaintext[bufferIndex] += buffer[count2] & 0xff; | 2167 | plaintext[bufferIndex] += buffer[count2] & 0xff; |
2174 | #endif | 2168 | #endif |
2175 | #ifdef WORDS_BIGENDIAN | 2169 | #ifdef WORDS_BIGENDIAN |
2176 | plaintext[bufferIndex] = buffer[count2] << 8; | 2170 | plaintext[bufferIndex] = buffer[count2] << 8; |
2177 | plaintext[bufferIndex] += buffer[count2 + 1] & 0xff; | 2171 | plaintext[bufferIndex] += buffer[count2 + 1] & 0xff; |
2178 | #endif | 2172 | #endif |
2179 | bufferIndex++; | 2173 | bufferIndex++; |
2180 | if (bufferIndex == 4) { | 2174 | if (bufferIndex == 4) { |
2181 | krc2->rc2_encrypt (plaintext); | 2175 | krc2->rc2_encrypt (plaintext); |
2182 | 2176 | ||
2183 | for (count3 = 0; count3 < 4; count3++) { | 2177 | for (count3 = 0; count3 < 4; count3++) { |
2184 | ciphertext[count3] = iv[count3] ^ plaintext[count3]; | 2178 | ciphertext[count3] = iv[count3] ^ plaintext[count3]; |
2185 | 2179 | ||
2186 | /* Now store the ciphertext as the iv */ | 2180 | /* Now store the ciphertext as the iv */ |
2187 | iv[count3] = plaintext[count3]; | 2181 | iv[count3] = plaintext[count3]; |
2188 | 2182 | ||
2189 | /* reset the buffer index */ | 2183 | /* reset the buffer index */ |
2190 | bufferIndex = 0; | 2184 | bufferIndex = 0; |
2191 | if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) return PWERR_DATA; | 2185 | if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) { |
2192 | if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) return PWERR_DATA; | 2186 | delete krc2; |
2187 | return PWERR_DATA; | ||
2188 | } | ||
2189 | if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) { | ||
2190 | delete krc2; | ||
2191 | return PWERR_DATA; | ||
2192 | } | ||
2193 | } /*for (count3 = 0; count3 < 5; count3++)*/ | 2193 | } /*for (count3 = 0; count3 < 5; count3++)*/ |
2194 | } /*if (bufferIndex == 5)*/ | 2194 | } /*if (bufferIndex == 5)*/ |
2195 | /* increment a short, not a byte */ | 2195 | /* increment a short, not a byte */ |
2196 | count2 += 2; | 2196 | count2 += 2; |
2197 | } /*while (count2 < strlen (buffer))*/ | 2197 | } /*while (count2 < strlen (buffer))*/ |
2198 | int ret = PWERR_GOOD; | 2198 | delete krc2; |
2199 | return ret; | 2199 | return PWERR_GOOD; |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | int ZSafe::saveFinalize(void) | 2202 | int ZSafe::saveFinalize(void) |
2203 | { | 2203 | { |
2204 | int count1, retval = PWERR_GOOD; | 2204 | int count1, retval = PWERR_GOOD; |
2205 | unsigned short ciphertext[4]; | 2205 | unsigned short ciphertext[4]; |
2206 | Krc2* krc2 = new Krc2(); | 2206 | Krc2* krc2 = new Krc2(); |
2207 | 2207 | ||
2208 | /* Tack on the PKCS 5 padding | 2208 | /* Tack on the PKCS 5 padding |
2209 | * How it works is we fill up the last n bytes with the value n | 2209 | * How it works is we fill up the last n bytes with the value n |
2210 | * | 2210 | * |
2211 | * So, if we have, say, 13 bytes, 8 of which are used, we have 5 left | 2211 | * So, if we have, say, 13 bytes, 8 of which are used, we have 5 left |
2212 | * over, leaving us 3 short, so we fill it in with 3's. | 2212 | * over, leaving us 3 short, so we fill it in with 3's. |
2213 | * | 2213 | * |
2214 | * If we come out even, we fill it with 8 8s | 2214 | * If we come out even, we fill it with 8 8s |
2215 | * | 2215 | * |
2216 | * um, except that in this instance we are using 4 shorts instead of 8 bytes. | 2216 | * um, except that in this instance we are using 4 shorts instead of 8 bytes. |
2217 | * so, half everything | 2217 | * so, half everything |
2218 | */ | 2218 | */ |
2219 | for (count1 = bufferIndex; count1 < 4; count1++) { | 2219 | for (count1 = bufferIndex; count1 < 4; count1++) { |
2220 | plaintext[count1] = (4 - bufferIndex); | 2220 | plaintext[count1] = (4 - bufferIndex); |
2221 | } | 2221 | } |
2222 | krc2->rc2_encrypt (plaintext); | 2222 | krc2->rc2_encrypt (plaintext); |
2223 | for (count1 = 0; count1 < 4; count1++) { | 2223 | for (count1 = 0; count1 < 4; count1++) { |
2224 | ciphertext[count1] = iv[count1] ^ plaintext[count1]; | 2224 | ciphertext[count1] = iv[count1] ^ plaintext[count1]; |
2225 | if (putc ((unsigned char) (ciphertext[count1] >> 8), fd) == EOF) retval = PWERR_DATA; | 2225 | if (putc ((unsigned char) (ciphertext[count1] >> 8), fd) == EOF) retval = PWERR_DATA; |
2226 | if (putc ((unsigned char) (ciphertext[count1] & 0xff), fd) == EOF) retval = PWERR_DATA; | 2226 | if (putc ((unsigned char) (ciphertext[count1] & 0xff), fd) == EOF) retval = PWERR_DATA; |
2227 | } | 2227 | } |
2228 | 2228 | ||
2229 | fclose (fd); | 2229 | fclose (fd); |
2230 | free(buffer); | 2230 | free(buffer); |
2231 | delete krc2; | ||
2231 | return retval; | 2232 | return retval; |
2232 | } | 2233 | } |
2233 | 2234 | ||
2234 | void ZSafe::quitMe () | 2235 | void ZSafe::quitMe () |
2235 | { | 2236 | { |
2236 | if (modified) | 2237 | if (modified) |
2237 | { | 2238 | { |
2238 | switch( QMessageBox::information( this, tr("ZSafe"), | 2239 | switch( QMessageBox::information( this, tr("ZSafe"), |
2239 | tr("Do you want to save\nbefore exiting?"), | 2240 | tr("Do you want to save\nbefore exiting?"), |
2240 | tr("&Save"), | 2241 | tr("&Save"), |
2241 | tr("S&ave with\nnew\npassword"), | 2242 | tr("S&ave with\nnew\npassword"), |
2242 | tr("&Don't Save"), | 2243 | tr("&Don't Save"), |
2243 | 0 // Enter == button 0 | 2244 | 0 // Enter == button 0 |
2244 | ) ) | 2245 | ) ) |
2245 | { // Escape == button 2 | 2246 | { // Escape == button 2 |
2246 | case 0: // Save clicked, Alt-S or Enter pressed. | 2247 | case 0: // Save clicked, Alt-S or Enter pressed. |
2247 | // save | 2248 | // save |
2248 | modified = false; | 2249 | modified = false; |
2249 | saveDocument(filename, FALSE); | 2250 | saveDocument(filename, FALSE); |
2250 | exitZs (1); | 2251 | exitZs (1); |
2251 | break; | 2252 | break; |
2252 | case 1: // | 2253 | case 1: // |
2253 | // Save with new password | 2254 | // Save with new password |
2254 | modified = false; | 2255 | modified = false; |
2255 | saveDocument(filename, TRUE); | 2256 | saveDocument(filename, TRUE); |
2256 | exitZs (1); | 2257 | exitZs (1); |
2257 | break; | 2258 | break; |
2258 | case 2: // Don't Save clicked or Alt-D pressed | 2259 | case 2: // Don't Save clicked or Alt-D pressed |
2259 | // don't save but exitZs | 2260 | // don't save but exitZs |
2260 | exitZs (1); | 2261 | exitZs (1); |
2261 | break; | 2262 | break; |
2262 | } | 2263 | } |
2263 | } | 2264 | } |
2264 | exitZs (1); | 2265 | exitZs (1); |
2265 | 2266 | ||
2266 | } | 2267 | } |
2267 | 2268 | ||
2268 | void ZSafe::categoryFieldActivated( const QString& category) | 2269 | void ZSafe::categoryFieldActivated( const QString& category) |
2269 | { | 2270 | { |
2270 | if (categoryDialog) | 2271 | if (categoryDialog) |
2271 | setCategoryDialogFields(categoryDialog, category); | 2272 | setCategoryDialogFields(categoryDialog, category); |
2272 | } | 2273 | } |
2273 | 2274 | ||
2274 | void ZSafe::addCategory() | 2275 | void ZSafe::addCategory() |
2275 | { | 2276 | { |
2276 | if (filename.isEmpty()) | 2277 | if (filename.isEmpty()) |
2277 | { | 2278 | { |
2278 | QMessageBox::critical( 0, tr("ZSafe"), | 2279 | QMessageBox::critical( 0, tr("ZSafe"), |
2279 | tr("No document defined.\nYou have to create a new document")); | 2280 | tr("No document defined.\nYou have to create a new document")); |
2280 | return; | 2281 | return; |
2281 | } | 2282 | } |
2282 | else | 2283 | else |
2283 | { | 2284 | { |
2284 | // open the 'Category' dialog | 2285 | // open the 'Category' dialog |
2285 | bool initIcons = false; | 2286 | bool initIcons = false; |
2286 | // open the 'Category' dialog | 2287 | // open the 'Category' dialog |
2287 | CategoryDialog *dialog; | 2288 | CategoryDialog *dialog; |
2288 | if (categoryDialog) | 2289 | if (categoryDialog) |
2289 | { | 2290 | { |
2290 | dialog = categoryDialog; | 2291 | dialog = categoryDialog; |
2291 | } | 2292 | } |
2292 | else | 2293 | else |
2293 | { | 2294 | { |
2294 | categoryDialog = new CategoryDialog(this, tr("Category"), TRUE); | 2295 | categoryDialog = new CategoryDialog(this, tr("Category"), TRUE); |
2295 | dialog = categoryDialog; | 2296 | dialog = categoryDialog; |
2296 | connect( dialog->CategoryField, | 2297 | connect( dialog->CategoryField, |
2297 | SIGNAL( activated(const QString&)), | 2298 | SIGNAL( activated(const QString&)), |
2298 | this, SLOT( categoryFieldActivated(const QString&) ) ); | 2299 | this, SLOT( categoryFieldActivated(const QString&) ) ); |
2299 | initIcons = true; | 2300 | initIcons = true; |
2300 | } | 2301 | } |
2301 | 2302 | ||
2302 | // read all categories from the config file and store | 2303 | // read all categories from the config file and store |
2303 | // into a list | 2304 | // into a list |
2304 | QFile f (cfgFile); | 2305 | QFile f (cfgFile); |
2305 | QStringList list; | 2306 | QStringList list; |
2306 | if ( f.open(IO_ReadOnly) ) { // file opened successfully | 2307 | if ( f.open(IO_ReadOnly) ) { // file opened successfully |
2307 | QTextStream t( &f ); // use a text stream | 2308 | QTextStream t( &f ); // use a text stream |
2308 | QString s; | 2309 | QString s; |
2309 | while ( !t.eof() ) { // until end of file... | 2310 | while ( !t.eof() ) { // until end of file... |
2310 | s = t.readLine(); // line of text excluding '\n' | 2311 | s = t.readLine(); // line of text excluding '\n' |
2311 | list.append(s); | 2312 | list.append(s); |
2312 | } | 2313 | } |
2313 | f.close(); | 2314 | f.close(); |
2314 | } | 2315 | } |
2315 | QStringList::Iterator it = list.begin(); | 2316 | QStringList::Iterator it = list.begin(); |
2316 | QString categ; | 2317 | QString categ; |
2317 | QString firstCategory; | 2318 | QString firstCategory; |
2318 | dialog->CategoryField->clear(); // remove all items | 2319 | dialog->CategoryField->clear(); // remove all items |
2319 | while( it != list.end() ) | 2320 | while( it != list.end() ) |
2320 | { | 2321 | { |
2321 | QString *cat = new QString (*it); | 2322 | QString *cat = new QString (*it); |
2322 | if (cat->contains("-field1", FALSE)) | 2323 | if (cat->contains("-field1", FALSE)) |
2323 | { | 2324 | { |
2324 | int pos = cat->find ("-field1"); | 2325 | int pos = cat->find ("-field1"); |
2325 | cat->truncate(pos); | 2326 | cat->truncate(pos); |
2326 | categ = *cat; | 2327 | categ = *cat; |
2327 | if (!categ.isEmpty()) | 2328 | if (!categ.isEmpty()) |
2328 | { | 2329 | { |
2329 | dialog->CategoryField->insertItem (categ, -1); | 2330 | dialog->CategoryField->insertItem (categ, -1); |
2330 | if (firstCategory.isEmpty()) | 2331 | if (firstCategory.isEmpty()) |
2331 | firstCategory = categ; | 2332 | firstCategory = categ; |
2332 | } | 2333 | } |
2333 | } | 2334 | } |
2334 | ++it; | 2335 | ++it; |
2335 | } | 2336 | } |
2336 | 2337 | ||
2337 | 2338 | ||
2338 | if (firstCategory.isEmpty()) | 2339 | if (firstCategory.isEmpty()) |
2339 | setCategoryDialogFields(dialog); | 2340 | setCategoryDialogFields(dialog); |
2340 | else | 2341 | else |
2341 | setCategoryDialogFields(dialog, firstCategory); | 2342 | setCategoryDialogFields(dialog, firstCategory); |
2342 | 2343 | ||
2343 | // CategoryDialog *dialog = new CategoryDialog(this, "Category", TRUE); | 2344 | // CategoryDialog *dialog = new CategoryDialog(this, "Category", TRUE); |
2344 | 2345 | ||
2345 | if (initIcons) | 2346 | if (initIcons) |
2346 | { | 2347 | { |
2347 | Wait waitDialog(this, tr("Wait dialog")); | 2348 | Wait waitDialog(this, tr("Wait dialog")); |
2348 | waitDialog.waitLabel->setText(tr("Gathering icons...")); | 2349 | waitDialog.waitLabel->setText(tr("Gathering icons...")); |
2349 | waitDialog.show(); | 2350 | waitDialog.show(); |
2350 | qApp->processEvents(); | 2351 | qApp->processEvents(); |
2351 | 2352 | ||
2352 | QDir d(QPEApplication::qpeDir() + "pics/"); | 2353 | QDir d(QPEApplication::qpeDir() + "pics/"); |
2353 | d.setFilter( QDir::Files); | 2354 | d.setFilter( QDir::Files); |
2354 | 2355 | ||
2355 | const QFileInfoList *list = d.entryInfoList(); | 2356 | const QFileInfoList *list = d.entryInfoList(); |
2356 | QFileInfoListIterator it( *list ); // create list iterator | 2357 | QFileInfoListIterator it( *list ); // create list iterator |
2357 | QFileInfo *fi; // pointer for traversing | 2358 | QFileInfo *fi; // pointer for traversing |
2358 | 2359 | ||
2359 | dialog->IconField->insertItem("predefined"); | 2360 | dialog->IconField->insertItem("predefined"); |
2360 | while ( (fi=it.current()) ) { // for each file... | 2361 | while ( (fi=it.current()) ) { // for each file... |
2361 | QString fileName = fi->fileName(); | 2362 | QString fileName = fi->fileName(); |
2362 | if(fileName.right(4) == ".png"){ | 2363 | if(fileName.right(4) == ".png"){ |
2363 | fileName = fileName.mid(0,fileName.length()-4); | 2364 | fileName = fileName.mid(0,fileName.length()-4); |
2364 | QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon)); | 2365 | QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon)); |
2365 | dialog->IconField->insertItem(imageOfFile,fileName); | 2366 | dialog->IconField->insertItem(imageOfFile,fileName); |
2366 | } | 2367 | } |
2367 | ++it; | 2368 | ++it; |
2368 | } | 2369 | } |
2369 | waitDialog.hide(); | 2370 | waitDialog.hide(); |
2370 | } | 2371 | } |
2371 | 2372 | ||
2372 | QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); | 2373 | QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); |
2373 | QString category; | 2374 | QString category; |
2374 | QString icon; | 2375 | QString icon; |
2375 | QString fullIconPath; | 2376 | QString fullIconPath; |
2376 | QPixmap *pix; | 2377 | QPixmap *pix; |
2377 | if (result == QDialog::Accepted) | 2378 | if (result == QDialog::Accepted) |
2378 | { | 2379 | { |
2379 | modified = true; | 2380 | modified = true; |
2380 | category = dialog->CategoryField->currentText(); | 2381 | category = dialog->CategoryField->currentText(); |
2381 | icon = dialog->IconField->currentText()+".png"; | 2382 | icon = dialog->IconField->currentText()+".png"; |
2382 | 2383 | ||
2383 | QListViewItem *li = new ShadedListItem( 1, ListView ); | 2384 | QListViewItem *li = new ShadedListItem( 1, ListView ); |
2384 | Category *c1 = new Category(); | 2385 | Category *c1 = new Category(); |
2385 | c1->setCategoryName(category); | 2386 | c1->setCategoryName(category); |
2386 | 2387 | ||
2387 | // if (!icon.isEmpty() && !icon.isNull()) | 2388 | // if (!icon.isEmpty() && !icon.isNull()) |
2388 | if (icon != "predefined.png") | 2389 | if (icon != "predefined.png") |
2389 | { | 2390 | { |
2390 | // build the full path | 2391 | // build the full path |
2391 | fullIconPath = iconPath + icon; | 2392 | fullIconPath = iconPath + icon; |
2392 | pix = new QPixmap (fullIconPath); | 2393 | pix = new QPixmap (fullIconPath); |
2393 | // pix->resize(14, 14); | 2394 | // pix->resize(14, 14); |
2394 | if (!pix->isNull()) | 2395 | if (!pix->isNull()) |
2395 | { | 2396 | { |
2396 | // save the full pixmap name into the config file | 2397 | // save the full pixmap name into the config file |
2397 | // #ifndef Q_WS_WIN | 2398 | // #ifndef Q_WS_WIN |
2398 | conf->writeEntry(APP_KEY+category, icon); | 2399 | conf->writeEntry(APP_KEY+category, icon); |
2399 | // #endif | 2400 | // #endif |
2400 | saveConf(); | 2401 | saveConf(); |
2401 | QImage img = pix->convertToImage(); | 2402 | QImage img = pix->convertToImage(); |
2402 | pix->convertFromImage(img.smoothScale(14,14)); | 2403 | pix->convertFromImage(img.smoothScale(14,14)); |
2403 | c1->setIcon (*pix); | 2404 | c1->setIcon (*pix); |
2404 | c1->setIconName(icon); | 2405 | c1->setIconName(icon); |
2405 | } | 2406 | } |
2406 | else | 2407 | else |
2407 | { | 2408 | { |
2408 | QPixmap folder( ( const char** ) general_data ); | 2409 | QPixmap folder( ( const char** ) general_data ); |
2409 | c1->setIcon (folder); | 2410 | c1->setIcon (folder); |
2410 | } | 2411 | } |
2411 | } | 2412 | } |
2412 | else | 2413 | else |
2413 | { | 2414 | { |
2414 | c1->setIcon (*getPredefinedIcon(category)); | 2415 | c1->setIcon (*getPredefinedIcon(category)); |
2415 | } | 2416 | } |
2416 | 2417 | ||
2417 | c1->setListItem (li); | 2418 | c1->setListItem (li); |
2418 | c1->initListItem(); | 2419 | c1->initListItem(); |
2419 | categories.insert (c1->getCategoryName(), c1); | 2420 | categories.insert (c1->getCategoryName(), c1); |
2420 | 2421 | ||
2421 | saveCategoryDialogFields(dialog); | 2422 | saveCategoryDialogFields(dialog); |
2422 | } | 2423 | } |
2423 | else | 2424 | else |
2424 | { | 2425 | { |
2425 | // delete dialog; | 2426 | // delete dialog; |
2426 | dialog->hide(); | 2427 | dialog->hide(); |
2427 | return; | 2428 | return; |
2428 | } | 2429 | } |
2429 | 2430 | ||
2430 | } | 2431 | } |
2431 | 2432 | ||
2432 | } | 2433 | } |
2433 | 2434 | ||
2434 | void ZSafe::delCategory() | 2435 | void ZSafe::delCategory() |
2435 | { | 2436 | { |
2436 | if (!selectedItem) | 2437 | if (!selectedItem) |
2437 | return; | 2438 | return; |
2438 | if (isCategory(selectedItem)) | 2439 | if (isCategory(selectedItem)) |
2439 | { | 2440 | { |
2440 | switch( QMessageBox::information( this, tr("ZSafe"), | 2441 | switch( QMessageBox::information( this, tr("ZSafe"), |
2441 | tr("Do you want to delete?"), | 2442 | tr("Do you want to delete?"), |
2442 | tr("&Delete"), tr("D&on't Delete"), | 2443 | tr("&Delete"), tr("D&on't Delete"), |
2443 | 0 // Enter == button 0 | 2444 | 0 // Enter == button 0 |
2444 | ) ) { // Escape == button 2 | 2445 | ) ) { // Escape == button 2 |
2445 | case 0: // Delete clicked, Alt-S or Enter pressed. | 2446 | case 0: // Delete clicked, Alt-S or Enter pressed. |
2446 | // Delete from the category list | 2447 | // Delete from the category list |
2447 | modified = true; | 2448 | modified = true; |
2448 | categories.remove (selectedItem->text(0)); | 2449 | categories.remove (selectedItem->text(0)); |
2449 | // #ifndef Q_WS_WIN | 2450 | // #ifndef Q_WS_WIN |
2450 | conf->removeEntry (selectedItem->text(0)); | 2451 | conf->removeEntry (selectedItem->text(0)); |
2451 | // #endif | 2452 | // #endif |
2452 | saveConf(); | 2453 | saveConf(); |
2453 | 2454 | ||
2454 | // Delete the selected item and all subitems | 2455 | // Delete the selected item and all subitems |
2455 | // step through all subitems | 2456 | // step through all subitems |
2456 | QListViewItem *si; | 2457 | QListViewItem *si; |
2457 | for (si = selectedItem->firstChild(); | 2458 | for (si = selectedItem->firstChild(); |
2458 | si != NULL; ) | 2459 | si != NULL; ) |
2459 | { | 2460 | { |
2460 | QListViewItem *_si = si; | 2461 | QListViewItem *_si = si; |
2461 | si = si->nextSibling(); | 2462 | si = si->nextSibling(); |
2462 | selectedItem->takeItem(_si); // remove from view list | 2463 | selectedItem->takeItem(_si); // remove from view list |
2463 | if (_si) delete _si; | 2464 | if (_si) delete _si; |
2464 | } | 2465 | } |
2465 | ListView->takeItem(selectedItem); | 2466 | ListView->takeItem(selectedItem); |
2466 | delete selectedItem; | 2467 | delete selectedItem; |
2467 | 2468 | ||
2468 | selectedItem = NULL; | 2469 | selectedItem = NULL; |
2469 | break; | 2470 | break; |
2470 | case 1: // Don't delete | 2471 | case 1: // Don't delete |
2471 | break; | 2472 | break; |
2472 | } | 2473 | } |
2473 | 2474 | ||
2474 | } | 2475 | } |
2475 | } | 2476 | } |
2476 | 2477 | ||
2477 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) | 2478 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) |
2478 | { | 2479 | { |
2479 | if (!dialog) | 2480 | if (!dialog) |
2480 | return; | 2481 | return; |
2481 | 2482 | ||
2482 | QString icon; | 2483 | QString icon; |
2483 | if (selectedItem) | 2484 | if (selectedItem) |
2484 | { | 2485 | { |
2485 | dialog->Field1->setText(getFieldLabel (selectedItem, "1", tr("Name"))); | 2486 | dialog->Field1->setText(getFieldLabel (selectedItem, "1", tr("Name"))); |
2486 | dialog->Field2->setText(getFieldLabel (selectedItem, "2", tr("Username"))); | 2487 | dialog->Field2->setText(getFieldLabel (selectedItem, "2", tr("Username"))); |
2487 | dialog->Field3->setText(getFieldLabel (selectedItem, "3", tr("Password"))); | 2488 | dialog->Field3->setText(getFieldLabel (selectedItem, "3", tr("Password"))); |
2488 | dialog->Field4->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); | 2489 | dialog->Field4->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); |
2489 | dialog->Field5->setText(getFieldLabel (selectedItem, "5", tr("Field 4"))); | 2490 | dialog->Field5->setText(getFieldLabel (selectedItem, "5", tr("Field 4"))); |
2490 | dialog->Field6->setText(getFieldLabel (selectedItem, "6", tr("Field 5"))); | 2491 | dialog->Field6->setText(getFieldLabel (selectedItem, "6", tr("Field 5"))); |
2491 | 2492 | ||
2492 | Category *cat= categories.find (selectedItem->text(0)); | 2493 | Category *cat= categories.find (selectedItem->text(0)); |
2493 | if (cat) | 2494 | if (cat) |
2494 | { | 2495 | { |
2495 | icon = cat->getIconName(); | 2496 | icon = cat->getIconName(); |
2496 | } | 2497 | } |
2497 | else | 2498 | else |
2498 | icon = conf->readEntry(APP_KEY+selectedItem->text(0)); | 2499 | icon = conf->readEntry(APP_KEY+selectedItem->text(0)); |
2499 | } | 2500 | } |
2500 | else | 2501 | else |
2501 | { | 2502 | { |
2502 | dialog->Field1->setText(tr("Name")); | 2503 | dialog->Field1->setText(tr("Name")); |
2503 | dialog->Field2->setText(tr("Username")); | 2504 | dialog->Field2->setText(tr("Username")); |
2504 | dialog->Field3->setText(tr("Password")); | 2505 | dialog->Field3->setText(tr("Password")); |
2505 | dialog->Field4->setText(tr("Comment")); | 2506 | dialog->Field4->setText(tr("Comment")); |
2506 | dialog->Field5->setText(tr("Field 4")); | 2507 | dialog->Field5->setText(tr("Field 4")); |
2507 | dialog->Field6->setText(tr("Field 5")); | 2508 | dialog->Field6->setText(tr("Field 5")); |
2508 | } | 2509 | } |
2509 | 2510 | ||
2510 | QDir d(QPEApplication::qpeDir() + "pics/"); | 2511 | QDir d(QPEApplication::qpeDir() + "pics/"); |
2511 | d.setFilter( QDir::Files); | 2512 | d.setFilter( QDir::Files); |
2512 | 2513 | ||
2513 | const QFileInfoList *list = d.entryInfoList(); | 2514 | const QFileInfoList *list = d.entryInfoList(); |
2514 | int i=0; | 2515 | int i=0; |
2515 | QFileInfoListIterator it( *list ); // create list iterator | 2516 | QFileInfoListIterator it( *list ); // create list iterator |
2516 | QFileInfo *fi; // pointer for traversing | 2517 | QFileInfo *fi; // pointer for traversing |
2517 | if (icon.isEmpty() || icon.isNull()) | 2518 | if (icon.isEmpty() || icon.isNull()) |
2518 | { | 2519 | { |
2519 | dialog->IconField->setCurrentItem(0); | 2520 | dialog->IconField->setCurrentItem(0); |
2520 | } | 2521 | } |
2521 | else | 2522 | else |
2522 | { | 2523 | { |
2523 | while ( (fi=it.current()) ) | 2524 | while ( (fi=it.current()) ) |
2524 | { // for each file... | 2525 | { // for each file... |
2525 | QString fileName = fi->fileName(); | 2526 | QString fileName = fi->fileName(); |
2526 | if(fileName.right(4) == ".png") | 2527 | if(fileName.right(4) == ".png") |
2527 | { | 2528 | { |
2528 | fileName = fileName.mid(0,fileName.length()-4); | 2529 | fileName = fileName.mid(0,fileName.length()-4); |
2529 | 2530 | ||
2530 | if(fileName+".png"==icon) | 2531 | if(fileName+".png"==icon) |
2531 | { | 2532 | { |
2532 | dialog->IconField->setCurrentItem(i+1); | 2533 | dialog->IconField->setCurrentItem(i+1); |
2533 | break; | 2534 | break; |
2534 | } | 2535 | } |
2535 | ++i; | 2536 | ++i; |
2536 | } | 2537 | } |
2537 | ++it; | 2538 | ++it; |
2538 | } | 2539 | } |
2539 | } | 2540 | } |
2540 | } | 2541 | } |
2541 | 2542 | ||
2542 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) | 2543 | void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) |
2543 | { | 2544 | { |
2544 | if (!dialog) | 2545 | if (!dialog) |
2545 | return; | 2546 | return; |
2546 | 2547 | ||
2547 | dialog->Field1->setText(getFieldLabel (category, "1", tr("Name"))); | 2548 | dialog->Field1->setText(getFieldLabel (category, "1", tr("Name"))); |
2548 | dialog->Field2->setText(getFieldLabel (category, "2", tr("Username"))); | 2549 | dialog->Field2->setText(getFieldLabel (category, "2", tr("Username"))); |
2549 | dialog->Field3->setText(getFieldLabel (category, "3", tr("Password"))); | 2550 | dialog->Field3->setText(getFieldLabel (category, "3", tr("Password"))); |
2550 | dialog->Field4->setText(getFieldLabel (category, "4", tr("Comment"))); | 2551 | dialog->Field4->setText(getFieldLabel (category, "4", tr("Comment"))); |
2551 | dialog->Field5->setText(getFieldLabel (category, "5", tr("Field 4"))); | 2552 | dialog->Field5->setText(getFieldLabel (category, "5", tr("Field 4"))); |
2552 | dialog->Field6->setText(getFieldLabel (category, "6", tr("Field 5"))); | 2553 | dialog->Field6->setText(getFieldLabel (category, "6", tr("Field 5"))); |
2553 | 2554 | ||
2554 | QString icon; | 2555 | QString icon; |
2555 | Category *cat= categories.find (category); | 2556 | Category *cat= categories.find (category); |
2556 | if (cat) | 2557 | if (cat) |
2557 | { | 2558 | { |
2558 | icon = cat->getIconName(); | 2559 | icon = cat->getIconName(); |
2559 | } | 2560 | } |
2560 | else | 2561 | else |
2561 | icon = conf->readEntry(APP_KEY+category); | 2562 | icon = conf->readEntry(APP_KEY+category); |
2562 | 2563 | ||
2563 | QDir d(QPEApplication::qpeDir() + "pics/"); | 2564 | QDir d(QPEApplication::qpeDir() + "pics/"); |
2564 | d.setFilter( QDir::Files); | 2565 | d.setFilter( QDir::Files); |
2565 | 2566 | ||
2566 | const QFileInfoList *list = d.entryInfoList(); | 2567 | const QFileInfoList *list = d.entryInfoList(); |
2567 | int i=0; | 2568 | int i=0; |
2568 | QFileInfoListIterator it( *list ); // create list iterator | 2569 | QFileInfoListIterator it( *list ); // create list iterator |
2569 | QFileInfo *fi; // pointer for traversing | 2570 | QFileInfo *fi; // pointer for traversing |
2570 | if (icon.isEmpty() || icon.isNull()) | 2571 | if (icon.isEmpty() || icon.isNull()) |
2571 | { | 2572 | { |
2572 | dialog->IconField->setCurrentItem(0); | 2573 | dialog->IconField->setCurrentItem(0); |
2573 | } | 2574 | } |
2574 | else | 2575 | else |
2575 | { | 2576 | { |
2576 | while ( (fi=it.current()) ) | 2577 | while ( (fi=it.current()) ) |
2577 | { // for each file... | 2578 | { // for each file... |
2578 | QString fileName = fi->fileName(); | 2579 | QString fileName = fi->fileName(); |
2579 | if(fileName.right(4) == ".png") | 2580 | if(fileName.right(4) == ".png") |
2580 | { | 2581 | { |
2581 | fileName = fileName.mid(0,fileName.length()-4); | 2582 | fileName = fileName.mid(0,fileName.length()-4); |
2582 | 2583 | ||
2583 | if(fileName+".png"==icon) | 2584 | if(fileName+".png"==icon) |
2584 | { | 2585 | { |
2585 | dialog->IconField->setCurrentItem(i+1); | 2586 | dialog->IconField->setCurrentItem(i+1); |
2586 | break; | 2587 | break; |
2587 | } | 2588 | } |
2588 | ++i; | 2589 | ++i; |
2589 | } | 2590 | } |
2590 | ++it; | 2591 | ++it; |
2591 | } | 2592 | } |
2592 | } | 2593 | } |
2593 | } | 2594 | } |
2594 | 2595 | ||
2595 | void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) | 2596 | void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) |
2596 | { | 2597 | { |
2597 | QString app_key = APP_KEY; | 2598 | QString app_key = APP_KEY; |
2598 | conf->setGroup( "fieldDefs" ); | 2599 | conf->setGroup( "fieldDefs" ); |
2599 | QString category = dialog->CategoryField->currentText(); | 2600 | QString category = dialog->CategoryField->currentText(); |
2600 | // #ifndef Q_WS_WIN | 2601 | // #ifndef Q_WS_WIN |
2601 | conf->writeEntry(app_key+category+"-field1", dialog->Field1->text()); | 2602 | conf->writeEntry(app_key+category+"-field1", dialog->Field1->text()); |
2602 | conf->writeEntry(app_key+category+"-field2", dialog->Field2->text()); | 2603 | conf->writeEntry(app_key+category+"-field2", dialog->Field2->text()); |
2603 | conf->writeEntry(app_key+category+"-field3", dialog->Field3->text()); | 2604 | conf->writeEntry(app_key+category+"-field3", dialog->Field3->text()); |
2604 | conf->writeEntry(app_key+category+"-field4", dialog->Field4->text()); | 2605 | conf->writeEntry(app_key+category+"-field4", dialog->Field4->text()); |
2605 | conf->writeEntry(app_key+category+"-field5", dialog->Field5->text()); | 2606 | conf->writeEntry(app_key+category+"-field5", dialog->Field5->text()); |
2606 | conf->writeEntry(app_key+category+"-field6", dialog->Field6->text()); | 2607 | conf->writeEntry(app_key+category+"-field6", dialog->Field6->text()); |
2607 | // #endif | 2608 | // #endif |
2608 | saveConf(); | 2609 | saveConf(); |
2609 | conf->setGroup ("zsafe"); | 2610 | conf->setGroup ("zsafe"); |
2610 | } | 2611 | } |
2611 | 2612 | ||
2612 | void ZSafe::editCategory() | 2613 | void ZSafe::editCategory() |
2613 | { | 2614 | { |
2614 | if (!selectedItem) | 2615 | if (!selectedItem) |
diff --git a/noncore/comm/keypebble/vncauth.c b/noncore/comm/keypebble/vncauth.c index 277d145..7de837a 100644 --- a/noncore/comm/keypebble/vncauth.c +++ b/noncore/comm/keypebble/vncauth.c | |||
@@ -1,160 +1,164 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory | 2 | * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory |
3 | * | 3 | * |
4 | * This is free software; you can redistribute it and/or modify | 4 | * This is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or | 6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
8 | * | 8 | * |
9 | * This software is distributed in the hope that it will be useful, | 9 | * This software is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
17 | * USA. | 17 | * USA. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * vncauth.c - Functions for VNC password management and authentication. | 21 | * vncauth.c - Functions for VNC password management and authentication. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <stdio.h> | 24 | #include <stdio.h> |
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <sys/types.h> | 27 | #include <sys/types.h> |
28 | #include <sys/stat.h> | 28 | #include <sys/stat.h> |
29 | #include <time.h> | 29 | #include <time.h> |
30 | #include "vncauth.h" | 30 | #include "vncauth.h" |
31 | #include "d3des.h" | 31 | #include "d3des.h" |
32 | 32 | ||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * We use a fixed key to store passwords, since we assume that our local | 35 | * We use a fixed key to store passwords, since we assume that our local |
36 | * file system is secure but nonetheless don't want to store passwords | 36 | * file system is secure but nonetheless don't want to store passwords |
37 | * as plaintext. | 37 | * as plaintext. |
38 | */ | 38 | */ |
39 | 39 | ||
40 | unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; | 40 | unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; |
41 | 41 | ||
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Encrypt a password and store it in a file. Returns 0 if successful, | 44 | * Encrypt a password and store it in a file. Returns 0 if successful, |
45 | * 1 if the file could not be written. | 45 | * 1 if the file could not be written. |
46 | */ | 46 | */ |
47 | 47 | ||
48 | int | 48 | int |
49 | vncEncryptAndStorePasswd(char *passwd, char *fname) | 49 | vncEncryptAndStorePasswd(char *passwd, char *fname) |
50 | { | 50 | { |
51 | FILE *fp; | 51 | FILE *fp; |
52 | uint i; | 52 | uint i; |
53 | unsigned char encryptedPasswd[8]; | 53 | unsigned char encryptedPasswd[8]; |
54 | 54 | ||
55 | if ((fp = fopen(fname,"w")) == NULL) return 1; | 55 | if ((fp = fopen(fname,"w")) == NULL) return 1; |
56 | 56 | ||
57 | chmod(fname, S_IRUSR|S_IWUSR); | 57 | chmod(fname, S_IRUSR|S_IWUSR); |
58 | 58 | ||
59 | /* pad password with nulls */ | 59 | /* pad password with nulls */ |
60 | 60 | ||
61 | for (i = 0; i < 8; i++) { | 61 | for (i = 0; i < 8; i++) { |
62 | if (i < strlen(passwd)) { | 62 | if (i < strlen(passwd)) { |
63 | encryptedPasswd[i] = passwd[i]; | 63 | encryptedPasswd[i] = passwd[i]; |
64 | } else { | 64 | } else { |
65 | encryptedPasswd[i] = 0; | 65 | encryptedPasswd[i] = 0; |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | /* Do encryption in-place - this way we overwrite our copy of the plaintext | 69 | /* Do encryption in-place - this way we overwrite our copy of the plaintext |
70 | password */ | 70 | password */ |
71 | 71 | ||
72 | deskey(fixedkey, EN0); | 72 | deskey(fixedkey, EN0); |
73 | des(encryptedPasswd, encryptedPasswd); | 73 | des(encryptedPasswd, encryptedPasswd); |
74 | 74 | ||
75 | for (i = 0; i < 8; i++) { | 75 | for (i = 0; i < 8; i++) { |
76 | putc(encryptedPasswd[i], fp); | 76 | putc(encryptedPasswd[i], fp); |
77 | } | 77 | } |
78 | 78 | ||
79 | fclose(fp); | 79 | fclose(fp); |
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Decrypt a password from a file. Returns a pointer to a newly allocated | 85 | * Decrypt a password from a file. Returns a pointer to a newly allocated |
86 | * string containing the password or a null pointer if the password could | 86 | * string containing the password or a null pointer if the password could |
87 | * not be retrieved for some reason. | 87 | * not be retrieved for some reason. |
88 | */ | 88 | */ |
89 | 89 | ||
90 | char * | 90 | char * |
91 | vncDecryptPasswdFromFile(char *fname) | 91 | vncDecryptPasswdFromFile(char *fname) |
92 | { | 92 | { |
93 | FILE *fp; | 93 | FILE *fp; |
94 | int i, ch; | 94 | int i, ch; |
95 | unsigned char *passwd = (unsigned char *)malloc(9); | 95 | unsigned char *passwd = (unsigned char *)malloc(9); |
96 | 96 | ||
97 | if ((fp = fopen(fname,"r")) == NULL) return NULL; | 97 | if ((fp = fopen(fname,"r")) == NULL) { |
98 | free(passwd); | ||
99 | return NULL; | ||
100 | } | ||
98 | 101 | ||
99 | for (i = 0; i < 8; i++) { | 102 | for (i = 0; i < 8; i++) { |
100 | ch = getc(fp); | 103 | ch = getc(fp); |
101 | if (ch == EOF) { | 104 | if (ch == EOF) { |
102 | fclose(fp); | 105 | fclose(fp); |
106 | free(passwd); | ||
103 | return NULL; | 107 | return NULL; |
104 | } | 108 | } |
105 | passwd[i] = ch; | 109 | passwd[i] = ch; |
106 | } | 110 | } |
107 | 111 | ||
108 | deskey(fixedkey, DE1); | 112 | deskey(fixedkey, DE1); |
109 | des(passwd, passwd); | 113 | des(passwd, passwd); |
110 | 114 | ||
111 | passwd[8] = 0; | 115 | passwd[8] = 0; |
112 | 116 | ||
113 | return (char *)passwd; | 117 | return (char *)passwd; |
114 | } | 118 | } |
115 | 119 | ||
116 | 120 | ||
117 | /* | 121 | /* |
118 | * Generate CHALLENGESIZE random bytes for use in challenge-response | 122 | * Generate CHALLENGESIZE random bytes for use in challenge-response |
119 | * authentication. | 123 | * authentication. |
120 | */ | 124 | */ |
121 | 125 | ||
122 | void | 126 | void |
123 | vncRandomBytes(unsigned char *bytes) | 127 | vncRandomBytes(unsigned char *bytes) |
124 | { | 128 | { |
125 | int i; | 129 | int i; |
126 | unsigned int seed = (unsigned int) time(0); | 130 | unsigned int seed = (unsigned int) time(0); |
127 | 131 | ||
128 | srandom(seed); | 132 | srandom(seed); |
129 | for (i = 0; i < CHALLENGESIZE; i++) { | 133 | for (i = 0; i < CHALLENGESIZE; i++) { |
130 | bytes[i] = (unsigned char)(random() & 255); | 134 | bytes[i] = (unsigned char)(random() & 255); |
131 | } | 135 | } |
132 | } | 136 | } |
133 | 137 | ||
134 | 138 | ||
135 | /* | 139 | /* |
136 | * Encrypt CHALLENGESIZE bytes in memory using a password. | 140 | * Encrypt CHALLENGESIZE bytes in memory using a password. |
137 | */ | 141 | */ |
138 | 142 | ||
139 | void | 143 | void |
140 | vncEncryptBytes(unsigned char *bytes, char *passwd) | 144 | vncEncryptBytes(unsigned char *bytes, char *passwd) |
141 | { | 145 | { |
142 | unsigned char key[8]; | 146 | unsigned char key[8]; |
143 | int i; | 147 | int i; |
144 | 148 | ||
145 | /* key is simply password padded with nulls */ | 149 | /* key is simply password padded with nulls */ |
146 | 150 | ||
147 | for (i = 0; i < 8; i++) { | 151 | for (i = 0; i < 8; i++) { |
148 | if (i < strlen(passwd)) { | 152 | if (i < strlen(passwd)) { |
149 | key[i] = passwd[i]; | 153 | key[i] = passwd[i]; |
150 | } else { | 154 | } else { |
151 | key[i] = 0; | 155 | key[i] = 0; |
152 | } | 156 | } |
153 | } | 157 | } |
154 | 158 | ||
155 | deskey(key, EN0); | 159 | deskey(key, EN0); |
156 | 160 | ||
157 | for (i = 0; i < CHALLENGESIZE; i += 8) { | 161 | for (i = 0; i < CHALLENGESIZE; i += 8) { |
158 | des(bytes+i, bytes+i); | 162 | des(bytes+i, bytes+i); |
159 | } | 163 | } |
160 | } | 164 | } |
diff --git a/noncore/net/ftplib/ftplib.c b/noncore/net/ftplib/ftplib.c index efcd6f0..addf9d2 100644 --- a/noncore/net/ftplib/ftplib.c +++ b/noncore/net/ftplib/ftplib.c | |||
@@ -791,560 +791,564 @@ static int FtpAcceptConnection(netbuf *nData, netbuf *nControl) | |||
791 | printf("<<<<<<<<<<<<<<<<%d\n",ACCEPT_TIMEOUT); | 791 | printf("<<<<<<<<<<<<<<<<%d\n",ACCEPT_TIMEOUT); |
792 | i = nControl->handle; | 792 | i = nControl->handle; |
793 | if (i < nData->handle) | 793 | if (i < nData->handle) |
794 | i = nData->handle; | 794 | i = nData->handle; |
795 | i = select(i+1, &mask, NULL, NULL, &tv); | 795 | i = select(i+1, &mask, NULL, NULL, &tv); |
796 | if (i == -1) | 796 | if (i == -1) |
797 | { | 797 | { |
798 | strncpy(nControl->response, strerror(errno), | 798 | strncpy(nControl->response, strerror(errno), |
799 | sizeof(nControl->response)); | 799 | sizeof(nControl->response)); |
800 | net_close(nData->handle); | 800 | net_close(nData->handle); |
801 | nData->handle = 0; | 801 | nData->handle = 0; |
802 | rv = 0; | 802 | rv = 0; |
803 | } | 803 | } |
804 | else if (i == 0) | 804 | else if (i == 0) |
805 | { | 805 | { |
806 | strcpy(nControl->response, "timed out waiting for connection"); | 806 | strcpy(nControl->response, "timed out waiting for connection"); |
807 | net_close(nData->handle); | 807 | net_close(nData->handle); |
808 | nData->handle = 0; | 808 | nData->handle = 0; |
809 | rv = 0; | 809 | rv = 0; |
810 | } | 810 | } |
811 | else | 811 | else |
812 | { | 812 | { |
813 | if (FD_ISSET(nData->handle, &mask)) | 813 | if (FD_ISSET(nData->handle, &mask)) |
814 | { | 814 | { |
815 | l = sizeof(addr); | 815 | l = sizeof(addr); |
816 | sData = accept(nData->handle, &addr, &l); | 816 | sData = accept(nData->handle, &addr, &l); |
817 | i = errno; | 817 | i = errno; |
818 | net_close(nData->handle); | 818 | net_close(nData->handle); |
819 | if (sData > 0) | 819 | if (sData > 0) |
820 | { | 820 | { |
821 | rv = 1; | 821 | rv = 1; |
822 | nData->handle = sData; | 822 | nData->handle = sData; |
823 | } | 823 | } |
824 | else | 824 | else |
825 | { | 825 | { |
826 | strncpy(nControl->response, strerror(i), | 826 | strncpy(nControl->response, strerror(i), |
827 | sizeof(nControl->response)); | 827 | sizeof(nControl->response)); |
828 | nData->handle = 0; | 828 | nData->handle = 0; |
829 | rv = 0; | 829 | rv = 0; |
830 | } | 830 | } |
831 | } | 831 | } |
832 | else if (FD_ISSET(nControl->handle, &mask)) | 832 | else if (FD_ISSET(nControl->handle, &mask)) |
833 | { | 833 | { |
834 | net_close(nData->handle); | 834 | net_close(nData->handle); |
835 | nData->handle = 0; | 835 | nData->handle = 0; |
836 | readresp('2', nControl); | 836 | readresp('2', nControl); |
837 | rv = 0; | 837 | rv = 0; |
838 | } | 838 | } |
839 | } | 839 | } |
840 | return rv; | 840 | return rv; |
841 | } | 841 | } |
842 | 842 | ||
843 | /* | 843 | /* |
844 | * FtpAccess - return a handle for a data stream | 844 | * FtpAccess - return a handle for a data stream |
845 | * | 845 | * |
846 | * return 1 if successful, 0 otherwise | 846 | * return 1 if successful, 0 otherwise |
847 | */ | 847 | */ |
848 | GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, | 848 | GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, |
849 | netbuf **nData) | 849 | netbuf **nData) |
850 | { | 850 | { |
851 | char buf[256]; | 851 | char buf[256]; |
852 | int dir; | 852 | int dir; |
853 | if ((path == NULL) && | 853 | if ((path == NULL) && |
854 | ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) | 854 | ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) |
855 | { | 855 | { |
856 | sprintf(nControl->response, | 856 | sprintf(nControl->response, |
857 | "Missing path argument for file transfer\n"); | 857 | "Missing path argument for file transfer\n"); |
858 | return 0; | 858 | return 0; |
859 | } | 859 | } |
860 | sprintf(buf, "TYPE %c", mode); | 860 | sprintf(buf, "TYPE %c", mode); |
861 | if (!FtpSendCmd(buf, '2', nControl)) | 861 | if (!FtpSendCmd(buf, '2', nControl)) |
862 | return 0; | 862 | return 0; |
863 | switch (typ) | 863 | switch (typ) |
864 | { | 864 | { |
865 | case FTPLIB_DIR: | 865 | case FTPLIB_DIR: |
866 | strcpy(buf,"NLST"); | 866 | strcpy(buf,"NLST"); |
867 | dir = FTPLIB_READ; | 867 | dir = FTPLIB_READ; |
868 | break; | 868 | break; |
869 | case FTPLIB_DIR_VERBOSE: | 869 | case FTPLIB_DIR_VERBOSE: |
870 | strcpy(buf,"LIST"); | 870 | strcpy(buf,"LIST"); |
871 | dir = FTPLIB_READ; | 871 | dir = FTPLIB_READ; |
872 | break; | 872 | break; |
873 | case FTPLIB_FILE_READ: | 873 | case FTPLIB_FILE_READ: |
874 | strcpy(buf,"RETR"); | 874 | strcpy(buf,"RETR"); |
875 | dir = FTPLIB_READ; | 875 | dir = FTPLIB_READ; |
876 | break; | 876 | break; |
877 | case FTPLIB_FILE_WRITE: | 877 | case FTPLIB_FILE_WRITE: |
878 | strcpy(buf,"STOR"); | 878 | strcpy(buf,"STOR"); |
879 | dir = FTPLIB_WRITE; | 879 | dir = FTPLIB_WRITE; |
880 | break; | 880 | break; |
881 | default: | 881 | default: |
882 | sprintf(nControl->response, "Invalid open type %d\n", typ); | 882 | sprintf(nControl->response, "Invalid open type %d\n", typ); |
883 | return 0; | 883 | return 0; |
884 | } | 884 | } |
885 | if (path != NULL) | 885 | if (path != NULL) |
886 | { | 886 | { |
887 | int i = strlen(buf); | 887 | int i = strlen(buf); |
888 | buf[i++] = ' '; | 888 | buf[i++] = ' '; |
889 | if ((strlen(path) + i) >= sizeof(buf)) | 889 | if ((strlen(path) + i) >= sizeof(buf)) |
890 | return 0; | 890 | return 0; |
891 | strcpy(&buf[i],path); | 891 | strcpy(&buf[i],path); |
892 | } | 892 | } |
893 | if (FtpOpenPort(nControl, nData, mode, dir) == -1) | 893 | if (FtpOpenPort(nControl, nData, mode, dir) == -1) |
894 | return 0; | 894 | return 0; |
895 | if (!FtpSendCmd(buf, '1', nControl)) | 895 | if (!FtpSendCmd(buf, '1', nControl)) |
896 | { | 896 | { |
897 | FtpClose(*nData); | 897 | FtpClose(*nData); |
898 | *nData = NULL; | 898 | *nData = NULL; |
899 | return 0; | 899 | return 0; |
900 | } | 900 | } |
901 | (*nData)->ctrl = nControl; | 901 | (*nData)->ctrl = nControl; |
902 | nControl->data = *nData; | 902 | nControl->data = *nData; |
903 | if (nControl->cmode == FTPLIB_PORT) | 903 | if (nControl->cmode == FTPLIB_PORT) |
904 | { | 904 | { |
905 | if (!FtpAcceptConnection(*nData,nControl)) | 905 | if (!FtpAcceptConnection(*nData,nControl)) |
906 | { | 906 | { |
907 | FtpClose(*nData); | 907 | FtpClose(*nData); |
908 | *nData = NULL; | 908 | *nData = NULL; |
909 | nControl->data = NULL; | 909 | nControl->data = NULL; |
910 | return 0; | 910 | return 0; |
911 | } | 911 | } |
912 | } | 912 | } |
913 | return 1; | 913 | return 1; |
914 | } | 914 | } |
915 | 915 | ||
916 | /* | 916 | /* |
917 | * FtpRead - read from a data connection | 917 | * FtpRead - read from a data connection |
918 | */ | 918 | */ |
919 | GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) | 919 | GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) |
920 | { | 920 | { |
921 | int i; | 921 | int i; |
922 | if (nData->dir != FTPLIB_READ) | 922 | if (nData->dir != FTPLIB_READ) |
923 | return 0; | 923 | return 0; |
924 | if (nData->buf) | 924 | if (nData->buf) |
925 | i = readline(buf, max, nData); | 925 | i = readline(buf, max, nData); |
926 | else | 926 | else |
927 | { | 927 | { |
928 | i = socket_wait(nData); | 928 | i = socket_wait(nData); |
929 | if (i != 1) | 929 | if (i != 1) |
930 | return 0; | 930 | return 0; |
931 | i = net_read(nData->handle, buf, max); | 931 | i = net_read(nData->handle, buf, max); |
932 | } | 932 | } |
933 | if (i == -1) | 933 | if (i == -1) |
934 | return 0; | 934 | return 0; |
935 | nData->xfered += i; | 935 | nData->xfered += i; |
936 | if (nData->idlecb && nData->cbbytes) | 936 | if (nData->idlecb && nData->cbbytes) |
937 | { | 937 | { |
938 | nData->xfered1 += i; | 938 | nData->xfered1 += i; |
939 | if (nData->xfered1 > nData->cbbytes) | 939 | if (nData->xfered1 > nData->cbbytes) |
940 | { | 940 | { |
941 | if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) | 941 | if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) |
942 | return 0; | 942 | return 0; |
943 | nData->xfered1 = 0; | 943 | nData->xfered1 = 0; |
944 | } | 944 | } |
945 | } | 945 | } |
946 | return i; | 946 | return i; |
947 | } | 947 | } |
948 | 948 | ||
949 | /* | 949 | /* |
950 | * FtpWrite - write to a data connection | 950 | * FtpWrite - write to a data connection |
951 | */ | 951 | */ |
952 | GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) | 952 | GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) |
953 | { | 953 | { |
954 | int i; | 954 | int i; |
955 | if (nData->dir != FTPLIB_WRITE) | 955 | if (nData->dir != FTPLIB_WRITE) |
956 | return 0; | 956 | return 0; |
957 | if (nData->buf) | 957 | if (nData->buf) |
958 | i = writeline(buf, len, nData); | 958 | i = writeline(buf, len, nData); |
959 | else | 959 | else |
960 | { | 960 | { |
961 | if (socket_wait(nData) < 0) | 961 | if (socket_wait(nData) < 0) |
962 | fprintf(stderr, "FtpWrite: socket_wait failed with %s\n", nData->ctrl->response); | 962 | fprintf(stderr, "FtpWrite: socket_wait failed with %s\n", nData->ctrl->response); |
963 | i = net_write(nData->handle, buf, len); | 963 | i = net_write(nData->handle, buf, len); |
964 | } | 964 | } |
965 | if (i == -1) | 965 | if (i == -1) |
966 | return 0; | 966 | return 0; |
967 | nData->xfered += i; | 967 | nData->xfered += i; |
968 | if (nData->idlecb && nData->cbbytes) | 968 | if (nData->idlecb && nData->cbbytes) |
969 | { | 969 | { |
970 | nData->xfered1 += i; | 970 | nData->xfered1 += i; |
971 | if (nData->xfered1 > nData->cbbytes) | 971 | if (nData->xfered1 > nData->cbbytes) |
972 | { | 972 | { |
973 | nData->idlecb(nData, nData->xfered, nData->idlearg); | 973 | nData->idlecb(nData, nData->xfered, nData->idlearg); |
974 | nData->xfered1 = 0; | 974 | nData->xfered1 = 0; |
975 | } | 975 | } |
976 | } | 976 | } |
977 | return i; | 977 | return i; |
978 | } | 978 | } |
979 | 979 | ||
980 | /* | 980 | /* |
981 | * FtpClose - close a data connection | 981 | * FtpClose - close a data connection |
982 | */ | 982 | */ |
983 | GLOBALDEF int FtpClose(netbuf *nData) | 983 | GLOBALDEF int FtpClose(netbuf *nData) |
984 | { | 984 | { |
985 | netbuf *ctrl; | 985 | netbuf *ctrl; |
986 | switch (nData->dir) | 986 | switch (nData->dir) |
987 | { | 987 | { |
988 | case FTPLIB_WRITE: | 988 | case FTPLIB_WRITE: |
989 | /* potential problem - if buffer flush fails, how to notify user? */ | 989 | /* potential problem - if buffer flush fails, how to notify user? */ |
990 | if (nData->buf != NULL) | 990 | if (nData->buf != NULL) |
991 | writeline(NULL, 0, nData); | 991 | writeline(NULL, 0, nData); |
992 | case FTPLIB_READ: | 992 | case FTPLIB_READ: |
993 | if (nData->buf) | 993 | if (nData->buf) |
994 | free(nData->buf); | 994 | free(nData->buf); |
995 | shutdown(nData->handle,2); | 995 | shutdown(nData->handle,2); |
996 | net_close(nData->handle); | 996 | net_close(nData->handle); |
997 | ctrl = nData->ctrl; | 997 | ctrl = nData->ctrl; |
998 | free(nData); | 998 | free(nData); |
999 | if (ctrl) | 999 | if (ctrl) |
1000 | { | 1000 | { |
1001 | ctrl->data = NULL; | 1001 | ctrl->data = NULL; |
1002 | return(readresp('2', ctrl)); | 1002 | return(readresp('2', ctrl)); |
1003 | } | 1003 | } |
1004 | return 1; | 1004 | return 1; |
1005 | case FTPLIB_CONTROL: | 1005 | case FTPLIB_CONTROL: |
1006 | if (nData->data) | 1006 | if (nData->data) |
1007 | { | 1007 | { |
1008 | nData->ctrl = NULL; | 1008 | nData->ctrl = NULL; |
1009 | FtpClose(nData); | 1009 | FtpClose(nData); |
1010 | } | 1010 | } |
1011 | net_close(nData->handle); | 1011 | net_close(nData->handle); |
1012 | free(nData); | 1012 | free(nData); |
1013 | return 0; | 1013 | return 0; |
1014 | } | 1014 | } |
1015 | return 1; | 1015 | return 1; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | /* | 1018 | /* |
1019 | * FtpSite - send a SITE command | 1019 | * FtpSite - send a SITE command |
1020 | * | 1020 | * |
1021 | * return 1 if command successful, 0 otherwise | 1021 | * return 1 if command successful, 0 otherwise |
1022 | */ | 1022 | */ |
1023 | GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) | 1023 | GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) |
1024 | { | 1024 | { |
1025 | char buf[256]; | 1025 | char buf[256]; |
1026 | 1026 | ||
1027 | if ((strlen(cmd) + 7) > sizeof(buf)) | 1027 | if ((strlen(cmd) + 7) > sizeof(buf)) |
1028 | return 0; | 1028 | return 0; |
1029 | sprintf(buf,"SITE %s",cmd); | 1029 | sprintf(buf,"SITE %s",cmd); |
1030 | if (!FtpSendCmd(buf,'2',nControl)) | 1030 | if (!FtpSendCmd(buf,'2',nControl)) |
1031 | return 0; | 1031 | return 0; |
1032 | return 1; | 1032 | return 1; |
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | /* | 1035 | /* |
1036 | * FtpSysType - send a SYST command | 1036 | * FtpSysType - send a SYST command |
1037 | * | 1037 | * |
1038 | * Fills in the user buffer with the remote system type. If more | 1038 | * Fills in the user buffer with the remote system type. If more |
1039 | * information from the response is required, the user can parse | 1039 | * information from the response is required, the user can parse |
1040 | * it out of the response buffer returned by FtpLastResponse(). | 1040 | * it out of the response buffer returned by FtpLastResponse(). |
1041 | * | 1041 | * |
1042 | * return 1 if command successful, 0 otherwise | 1042 | * return 1 if command successful, 0 otherwise |
1043 | */ | 1043 | */ |
1044 | GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) | 1044 | GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) |
1045 | { | 1045 | { |
1046 | int l = max; | 1046 | int l = max; |
1047 | char *b = buf; | 1047 | char *b = buf; |
1048 | char *s; | 1048 | char *s; |
1049 | if (!FtpSendCmd("SYST",'2',nControl)) | 1049 | if (!FtpSendCmd("SYST",'2',nControl)) |
1050 | return 0; | 1050 | return 0; |
1051 | s = &nControl->response[4]; | 1051 | s = &nControl->response[4]; |
1052 | while ((--l) && (*s != ' ')) | 1052 | while ((--l) && (*s != ' ')) |
1053 | *b++ = *s++; | 1053 | *b++ = *s++; |
1054 | *b++ = '\0'; | 1054 | *b++ = '\0'; |
1055 | return 1; | 1055 | return 1; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | /* | 1058 | /* |
1059 | * FtpMkdir - create a directory at server | 1059 | * FtpMkdir - create a directory at server |
1060 | * | 1060 | * |
1061 | * return 1 if successful, 0 otherwise | 1061 | * return 1 if successful, 0 otherwise |
1062 | */ | 1062 | */ |
1063 | GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) | 1063 | GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) |
1064 | { | 1064 | { |
1065 | char buf[256]; | 1065 | char buf[256]; |
1066 | 1066 | ||
1067 | if ((strlen(path) + 6) > sizeof(buf)) | 1067 | if ((strlen(path) + 6) > sizeof(buf)) |
1068 | return 0; | 1068 | return 0; |
1069 | sprintf(buf,"MKD %s",path); | 1069 | sprintf(buf,"MKD %s",path); |
1070 | if (!FtpSendCmd(buf,'2', nControl)) | 1070 | if (!FtpSendCmd(buf,'2', nControl)) |
1071 | return 0; | 1071 | return 0; |
1072 | return 1; | 1072 | return 1; |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | /* | 1075 | /* |
1076 | * FtpChdir - change path at remote | 1076 | * FtpChdir - change path at remote |
1077 | * | 1077 | * |
1078 | * return 1 if successful, 0 otherwise | 1078 | * return 1 if successful, 0 otherwise |
1079 | */ | 1079 | */ |
1080 | GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) | 1080 | GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) |
1081 | { | 1081 | { |
1082 | char buf[256]; | 1082 | char buf[256]; |
1083 | 1083 | ||
1084 | if ((strlen(path) + 6) > sizeof(buf)) | 1084 | if ((strlen(path) + 6) > sizeof(buf)) |
1085 | return 0; | 1085 | return 0; |
1086 | sprintf(buf,"CWD %s",path); | 1086 | sprintf(buf,"CWD %s",path); |
1087 | if (!FtpSendCmd(buf,'2',nControl)) | 1087 | if (!FtpSendCmd(buf,'2',nControl)) |
1088 | return 0; | 1088 | return 0; |
1089 | return 1; | 1089 | return 1; |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | /* | 1092 | /* |
1093 | * FtpCDUp - move to parent directory at remote | 1093 | * FtpCDUp - move to parent directory at remote |
1094 | * | 1094 | * |
1095 | * return 1 if successful, 0 otherwise | 1095 | * return 1 if successful, 0 otherwise |
1096 | */ | 1096 | */ |
1097 | GLOBALDEF int FtpCDUp(netbuf *nControl) | 1097 | GLOBALDEF int FtpCDUp(netbuf *nControl) |
1098 | { | 1098 | { |
1099 | if (!FtpSendCmd("CDUP",'2',nControl)) | 1099 | if (!FtpSendCmd("CDUP",'2',nControl)) |
1100 | return 0; | 1100 | return 0; |
1101 | return 1; | 1101 | return 1; |
1102 | } | 1102 | } |
1103 | 1103 | ||
1104 | /* | 1104 | /* |
1105 | * FtpRmdir - remove directory at remote | 1105 | * FtpRmdir - remove directory at remote |
1106 | * | 1106 | * |
1107 | * return 1 if successful, 0 otherwise | 1107 | * return 1 if successful, 0 otherwise |
1108 | */ | 1108 | */ |
1109 | GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) | 1109 | GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) |
1110 | { | 1110 | { |
1111 | char buf[256]; | 1111 | char buf[256]; |
1112 | 1112 | ||
1113 | if ((strlen(path) + 6) > sizeof(buf)) | 1113 | if ((strlen(path) + 6) > sizeof(buf)) |
1114 | return 0; | 1114 | return 0; |
1115 | sprintf(buf,"RMD %s",path); | 1115 | sprintf(buf,"RMD %s",path); |
1116 | if (!FtpSendCmd(buf,'2',nControl)) | 1116 | if (!FtpSendCmd(buf,'2',nControl)) |
1117 | return 0; | 1117 | return 0; |
1118 | return 1; | 1118 | return 1; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | /* | 1121 | /* |
1122 | * FtpPwd - get working directory at remote | 1122 | * FtpPwd - get working directory at remote |
1123 | * | 1123 | * |
1124 | * return 1 if successful, 0 otherwise | 1124 | * return 1 if successful, 0 otherwise |
1125 | */ | 1125 | */ |
1126 | GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) | 1126 | GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) |
1127 | { | 1127 | { |
1128 | int l = max; | 1128 | int l = max; |
1129 | char *b = path; | 1129 | char *b = path; |
1130 | char *s; | 1130 | char *s; |
1131 | if (!FtpSendCmd("PWD",'2',nControl)) | 1131 | if (!FtpSendCmd("PWD",'2',nControl)) |
1132 | return 0; | 1132 | return 0; |
1133 | s = strchr(nControl->response, '"'); | 1133 | s = strchr(nControl->response, '"'); |
1134 | if (s == NULL) | 1134 | if (s == NULL) |
1135 | return 0; | 1135 | return 0; |
1136 | s++; | 1136 | s++; |
1137 | while ((--l) && (*s) && (*s != '"')) | 1137 | while ((--l) && (*s) && (*s != '"')) |
1138 | *b++ = *s++; | 1138 | *b++ = *s++; |
1139 | *b++ = '\0'; | 1139 | *b++ = '\0'; |
1140 | return 1; | 1140 | return 1; |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | /* | 1143 | /* |
1144 | * FtpXfer - issue a command and transfer data | 1144 | * FtpXfer - issue a command and transfer data |
1145 | * | 1145 | * |
1146 | * return 1 if successful, 0 otherwise | 1146 | * return 1 if successful, 0 otherwise |
1147 | */ | 1147 | */ |
1148 | static int FtpXfer(const char *localfile, const char *path, | 1148 | static int FtpXfer(const char *localfile, const char *path, |
1149 | netbuf *nControl, int typ, int mode) | 1149 | netbuf *nControl, int typ, int mode) |
1150 | { | 1150 | { |
1151 | int l,c; | 1151 | int l,c; |
1152 | char *dbuf; | 1152 | char *dbuf; |
1153 | FILE *local = NULL; | 1153 | FILE *local = NULL; |
1154 | netbuf *nData; | 1154 | netbuf *nData; |
1155 | int rv=1; | 1155 | int rv=1; |
1156 | 1156 | ||
1157 | if (localfile != NULL) | 1157 | if (localfile != NULL) |
1158 | { | 1158 | { |
1159 | char ac[4] = "w"; | 1159 | char ac[4] = "w"; |
1160 | if (typ == FTPLIB_FILE_WRITE) | 1160 | if (typ == FTPLIB_FILE_WRITE) |
1161 | ac[0] = 'r'; | 1161 | ac[0] = 'r'; |
1162 | if (mode == FTPLIB_IMAGE) | 1162 | if (mode == FTPLIB_IMAGE) |
1163 | ac[1] = 'b'; | 1163 | ac[1] = 'b'; |
1164 | local = fopen(localfile, ac); | 1164 | local = fopen(localfile, ac); |
1165 | if (local == NULL) | 1165 | if (local == NULL) |
1166 | { | 1166 | { |
1167 | strncpy(nControl->response, strerror(errno), | 1167 | strncpy(nControl->response, strerror(errno), |
1168 | sizeof(nControl->response)); | 1168 | sizeof(nControl->response)); |
1169 | return 0; | 1169 | return 0; |
1170 | } | 1170 | } |
1171 | } | 1171 | } |
1172 | if (local == NULL) | 1172 | if (local == NULL) |
1173 | local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; | 1173 | local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; |
1174 | if (!FtpAccess(path, typ, mode, nControl, &nData)) | 1174 | if (!FtpAccess(path, typ, mode, nControl, &nData)) |
1175 | { | ||
1176 | if (localfile != NULL) | ||
1177 | fclose(local); | ||
1175 | return 0; | 1178 | return 0; |
1179 | } | ||
1176 | dbuf = malloc(FTPLIB_BUFSIZ); | 1180 | dbuf = malloc(FTPLIB_BUFSIZ); |
1177 | if (typ == FTPLIB_FILE_WRITE) | 1181 | if (typ == FTPLIB_FILE_WRITE) |
1178 | { | 1182 | { |
1179 | while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) | 1183 | while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) |
1180 | if ((c = FtpWrite(dbuf, l, nData)) < l) | 1184 | if ((c = FtpWrite(dbuf, l, nData)) < l) |
1181 | { | 1185 | { |
1182 | printf("short write: passed %d, wrote %d\n", l, c); | 1186 | printf("short write: passed %d, wrote %d\n", l, c); |
1183 | rv = 0; | 1187 | rv = 0; |
1184 | break; | 1188 | break; |
1185 | } | 1189 | } |
1186 | } | 1190 | } |
1187 | else | 1191 | else |
1188 | { | 1192 | { |
1189 | while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) | 1193 | while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) |
1190 | if (fwrite(dbuf, 1, l, local) <= 0) | 1194 | if (fwrite(dbuf, 1, l, local) <= 0) |
1191 | { | 1195 | { |
1192 | perror("localfile write"); | 1196 | perror("localfile write"); |
1193 | rv = 0; | 1197 | rv = 0; |
1194 | break; | 1198 | break; |
1195 | } | 1199 | } |
1196 | } | 1200 | } |
1197 | free(dbuf); | 1201 | free(dbuf); |
1198 | fflush(local); | 1202 | fflush(local); |
1199 | if (localfile != NULL) | 1203 | if (localfile != NULL) |
1200 | fclose(local); | 1204 | fclose(local); |
1201 | FtpClose(nData); | 1205 | FtpClose(nData); |
1202 | return rv; | 1206 | return rv; |
1203 | } | 1207 | } |
1204 | 1208 | ||
1205 | /* | 1209 | /* |
1206 | * FtpNlst - issue an NLST command and write response to output | 1210 | * FtpNlst - issue an NLST command and write response to output |
1207 | * | 1211 | * |
1208 | * return 1 if successful, 0 otherwise | 1212 | * return 1 if successful, 0 otherwise |
1209 | */ | 1213 | */ |
1210 | GLOBALDEF int FtpNlst(const char *outputfile, const char *path, | 1214 | GLOBALDEF int FtpNlst(const char *outputfile, const char *path, |
1211 | netbuf *nControl) | 1215 | netbuf *nControl) |
1212 | { | 1216 | { |
1213 | return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII); | 1217 | return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII); |
1214 | } | 1218 | } |
1215 | 1219 | ||
1216 | /* | 1220 | /* |
1217 | * FtpDir - issue a LIST command and write response to output | 1221 | * FtpDir - issue a LIST command and write response to output |
1218 | * | 1222 | * |
1219 | * return 1 if successful, 0 otherwise | 1223 | * return 1 if successful, 0 otherwise |
1220 | */ | 1224 | */ |
1221 | GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) | 1225 | GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) |
1222 | { | 1226 | { |
1223 | return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII); | 1227 | return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII); |
1224 | } | 1228 | } |
1225 | 1229 | ||
1226 | /* | 1230 | /* |
1227 | * FtpSize - determine the size of a remote file | 1231 | * FtpSize - determine the size of a remote file |
1228 | * | 1232 | * |
1229 | * return 1 if successful, 0 otherwise | 1233 | * return 1 if successful, 0 otherwise |
1230 | */ | 1234 | */ |
1231 | GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) | 1235 | GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) |
1232 | { | 1236 | { |
1233 | char cmd[256]; | 1237 | char cmd[256]; |
1234 | int resp,sz,rv=1; | 1238 | int resp,sz,rv=1; |
1235 | 1239 | ||
1236 | if ((strlen(path) + 7) > sizeof(cmd)) | 1240 | if ((strlen(path) + 7) > sizeof(cmd)) |
1237 | return 0; | 1241 | return 0; |
1238 | sprintf(cmd, "TYPE %c", mode); | 1242 | sprintf(cmd, "TYPE %c", mode); |
1239 | if (!FtpSendCmd(cmd, '2', nControl)) | 1243 | if (!FtpSendCmd(cmd, '2', nControl)) |
1240 | return 0; | 1244 | return 0; |
1241 | sprintf(cmd,"SIZE %s",path); | 1245 | sprintf(cmd,"SIZE %s",path); |
1242 | if (!FtpSendCmd(cmd,'2',nControl)) | 1246 | if (!FtpSendCmd(cmd,'2',nControl)) |
1243 | rv = 0; | 1247 | rv = 0; |
1244 | else | 1248 | else |
1245 | { | 1249 | { |
1246 | if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) | 1250 | if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) |
1247 | *size = sz; | 1251 | *size = sz; |
1248 | else | 1252 | else |
1249 | rv = 0; | 1253 | rv = 0; |
1250 | } | 1254 | } |
1251 | return rv; | 1255 | return rv; |
1252 | } | 1256 | } |
1253 | 1257 | ||
1254 | /* | 1258 | /* |
1255 | * FtpModDate - determine the modification date of a remote file | 1259 | * FtpModDate - determine the modification date of a remote file |
1256 | * | 1260 | * |
1257 | * return 1 if successful, 0 otherwise | 1261 | * return 1 if successful, 0 otherwise |
1258 | */ | 1262 | */ |
1259 | GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) | 1263 | GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) |
1260 | { | 1264 | { |
1261 | char buf[256]; | 1265 | char buf[256]; |
1262 | int rv = 1; | 1266 | int rv = 1; |
1263 | 1267 | ||
1264 | if ((strlen(path) + 7) > sizeof(buf)) | 1268 | if ((strlen(path) + 7) > sizeof(buf)) |
1265 | return 0; | 1269 | return 0; |
1266 | sprintf(buf,"MDTM %s",path); | 1270 | sprintf(buf,"MDTM %s",path); |
1267 | if (!FtpSendCmd(buf,'2',nControl)) | 1271 | if (!FtpSendCmd(buf,'2',nControl)) |
1268 | rv = 0; | 1272 | rv = 0; |
1269 | else | 1273 | else |
1270 | strncpy(dt, &nControl->response[4], max); | 1274 | strncpy(dt, &nControl->response[4], max); |
1271 | return rv; | 1275 | return rv; |
1272 | } | 1276 | } |
1273 | 1277 | ||
1274 | /* | 1278 | /* |
1275 | * FtpGet - issue a GET command and write received data to output | 1279 | * FtpGet - issue a GET command and write received data to output |
1276 | * | 1280 | * |
1277 | * return 1 if successful, 0 otherwise | 1281 | * return 1 if successful, 0 otherwise |
1278 | */ | 1282 | */ |
1279 | GLOBALDEF int FtpGet(const char *outputfile, const char *path, | 1283 | GLOBALDEF int FtpGet(const char *outputfile, const char *path, |
1280 | char mode, netbuf *nControl) | 1284 | char mode, netbuf *nControl) |
1281 | { | 1285 | { |
1282 | return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode); | 1286 | return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode); |
1283 | } | 1287 | } |
1284 | 1288 | ||
1285 | /* | 1289 | /* |
1286 | * FtpPut - issue a PUT command and send data from input | 1290 | * FtpPut - issue a PUT command and send data from input |
1287 | * | 1291 | * |
1288 | * return 1 if successful, 0 otherwise | 1292 | * return 1 if successful, 0 otherwise |
1289 | */ | 1293 | */ |
1290 | GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, | 1294 | GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, |
1291 | netbuf *nControl) | 1295 | netbuf *nControl) |
1292 | { | 1296 | { |
1293 | return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode); | 1297 | return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode); |
1294 | } | 1298 | } |
1295 | 1299 | ||
1296 | /* | 1300 | /* |
1297 | * FtpRename - rename a file at remote | 1301 | * FtpRename - rename a file at remote |
1298 | * | 1302 | * |
1299 | * return 1 if successful, 0 otherwise | 1303 | * return 1 if successful, 0 otherwise |
1300 | */ | 1304 | */ |
1301 | GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) | 1305 | GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) |
1302 | { | 1306 | { |
1303 | char cmd[256]; | 1307 | char cmd[256]; |
1304 | 1308 | ||
1305 | if (((strlen(src) + 7) > sizeof(cmd)) || | 1309 | if (((strlen(src) + 7) > sizeof(cmd)) || |
1306 | ((strlen(dst) + 7) > sizeof(cmd))) | 1310 | ((strlen(dst) + 7) > sizeof(cmd))) |
1307 | return 0; | 1311 | return 0; |
1308 | sprintf(cmd,"RNFR %s",src); | 1312 | sprintf(cmd,"RNFR %s",src); |
1309 | if (!FtpSendCmd(cmd,'3',nControl)) | 1313 | if (!FtpSendCmd(cmd,'3',nControl)) |
1310 | return 0; | 1314 | return 0; |
1311 | sprintf(cmd,"RNTO %s",dst); | 1315 | sprintf(cmd,"RNTO %s",dst); |
1312 | if (!FtpSendCmd(cmd,'2',nControl)) | 1316 | if (!FtpSendCmd(cmd,'2',nControl)) |
1313 | return 0; | 1317 | return 0; |
1314 | return 1; | 1318 | return 1; |
1315 | } | 1319 | } |
1316 | 1320 | ||
1317 | /* | 1321 | /* |
1318 | * FtpDelete - delete a file at remote | 1322 | * FtpDelete - delete a file at remote |
1319 | * | 1323 | * |
1320 | * return 1 if successful, 0 otherwise | 1324 | * return 1 if successful, 0 otherwise |
1321 | */ | 1325 | */ |
1322 | GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) | 1326 | GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) |
1323 | { | 1327 | { |
1324 | char cmd[256]; | 1328 | char cmd[256]; |
1325 | 1329 | ||
1326 | if ((strlen(fnm) + 7) > sizeof(cmd)) | 1330 | if ((strlen(fnm) + 7) > sizeof(cmd)) |
1327 | return 0; | 1331 | return 0; |
1328 | sprintf(cmd,"DELE %s",fnm); | 1332 | sprintf(cmd,"DELE %s",fnm); |
1329 | if (!FtpSendCmd(cmd,'2', nControl)) | 1333 | if (!FtpSendCmd(cmd,'2', nControl)) |
1330 | return 0; | 1334 | return 0; |
1331 | return 1; | 1335 | return 1; |
1332 | } | 1336 | } |
1333 | 1337 | ||
1334 | /* | 1338 | /* |
1335 | * FtpQuit - disconnect from remote | 1339 | * FtpQuit - disconnect from remote |
1336 | * | 1340 | * |
1337 | * return 1 if successful, 0 otherwise | 1341 | * return 1 if successful, 0 otherwise |
1338 | */ | 1342 | */ |
1339 | GLOBALDEF void FtpQuit(netbuf *nControl) | 1343 | GLOBALDEF void FtpQuit(netbuf *nControl) |
1340 | { | 1344 | { |
1341 | if (nControl->dir != FTPLIB_CONTROL) | 1345 | if (nControl->dir != FTPLIB_CONTROL) |
1342 | return; | 1346 | return; |
1343 | if (FtpSendCmd("QUIT",'2',nControl) == 1) { | 1347 | if (FtpSendCmd("QUIT",'2',nControl) == 1) { |
1344 | if (ftplib_debug > 2) | 1348 | if (ftplib_debug > 2) |
1345 | fprintf(stderr, "FtpQuit: FtpSendCmd(QUIT) failed\n"); | 1349 | fprintf(stderr, "FtpQuit: FtpSendCmd(QUIT) failed\n"); |
1346 | } | 1350 | } |
1347 | net_close(nControl->handle); | 1351 | net_close(nControl->handle); |
1348 | free(nControl->buf); | 1352 | free(nControl->buf); |
1349 | free(nControl); | 1353 | free(nControl); |
1350 | } | 1354 | } |
diff --git a/noncore/todayplugins/stockticker/libstocks/csv.c b/noncore/todayplugins/stockticker/libstocks/csv.c index 86d8607..110df7c 100644 --- a/noncore/todayplugins/stockticker/libstocks/csv.c +++ b/noncore/todayplugins/stockticker/libstocks/csv.c | |||
@@ -1,406 +1,480 @@ | |||
1 | /* libstocks - Library to get current stock quotes from Yahoo Finance | 1 | /* libstocks - Library to get current stock quotes from Yahoo Finance |
2 | * | 2 | * |
3 | * Copyright (C) 2000 Eric Laeuffer | 3 | * Copyright (C) 2000 Eric Laeuffer |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public | 6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either | 7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. | 8 | * version 2 of the License, or (at your option) any later version. |
9 | * | 9 | * |
10 | * This library is distributed in the hope that it will be useful, | 10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. | 13 | * Library General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU Library General Public | 15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library; if not, write to the | 16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. | 18 | * Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define __CSV_C__ | 21 | #define __CSV_C__ |
22 | #ifndef __UNIX__ | 22 | #ifndef __UNIX__ |
23 | #define __UNIX__ | 23 | #define __UNIX__ |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | 29 | ||
30 | #ifdef __WINDOWS__ | 30 | #ifdef __WINDOWS__ |
31 | #include <mbstring.h> | 31 | #include <mbstring.h> |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #include "csv.h" | 34 | #include "csv.h" |
35 | #include "stocks.h" | 35 | #include "stocks.h" |
36 | #include "lists.h" | 36 | #include "lists.h" |
37 | 37 | ||
38 | #define DATE_LENGTH 7 /*YYMMDD*/ | 38 | #define DATE_LENGTH 7 /*YYMMDD*/ |
39 | 39 | ||
40 | const char *months[12]= | 40 | const char *months[12]= |
41 | { | 41 | { |
42 | "Jan", | 42 | "Jan", |
43 | "Feb", | 43 | "Feb", |
44 | "Mar", | 44 | "Mar", |
45 | "Apr", | 45 | "Apr", |
46 | "May", | 46 | "May", |
47 | "Jun", | 47 | "Jun", |
48 | "Jul", | 48 | "Jul", |
49 | "Aug", | 49 | "Aug", |
50 | "Sep", | 50 | "Sep", |
51 | "Oct", | 51 | "Oct", |
52 | "Nov", | 52 | "Nov", |
53 | "Dec" | 53 | "Dec" |
54 | }; | 54 | }; |
55 | 55 | ||
56 | /*****************************************************************************/ | 56 | /*****************************************************************************/ |
57 | /* Replacement of the strtok function. This one forgets "delim" when it is */ | 57 | /* Replacement of the strtok function. This one forgets "delim" when it is */ |
58 | /* between two commas. */ | 58 | /* between two commas. */ |
59 | /* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */ | 59 | /* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */ |
60 | /*****************************************************************************/ | 60 | /*****************************************************************************/ |
61 | char *csv_strtok(char *s, char *delim) | 61 | char *csv_strtok(char *s, char *delim) |
62 | { | 62 | { |
63 | static char *next=NULL; | 63 | static char *next=NULL; |
64 | char *temp, *first; | 64 | char *temp, *first; |
65 | int comma=0; | 65 | int comma=0; |
66 | 66 | ||
67 | if (s!=NULL) first=s; | 67 | if (s!=NULL) first=s; |
68 | else first=next; | 68 | else first=next; |
69 | 69 | ||
70 | temp=first; | 70 | temp=first; |
71 | if (*temp=='\0') return NULL; | 71 | if (*temp=='\0') return NULL; |
72 | 72 | ||
73 | while (*temp!='\0' && ((*temp!=*delim) || comma)) | 73 | while (*temp!='\0' && ((*temp!=*delim) || comma)) |
74 | { | 74 | { |
75 | if (*temp=='"') comma ^= 1; | 75 | if (*temp=='"') comma ^= 1; |
76 | temp++; | 76 | temp++; |
77 | } | 77 | } |
78 | 78 | ||
79 | if (*temp=='\0') next=temp; | 79 | if (*temp=='\0') next=temp; |
80 | else | 80 | else |
81 | { | 81 | { |
82 | *temp='\0'; | 82 | *temp='\0'; |
83 | next=temp+1; | 83 | next=temp+1; |
84 | } | 84 | } |
85 | 85 | ||
86 | return first; | 86 | return first; |
87 | } | 87 | } |
88 | 88 | ||
89 | /*****************************************************************************/ | 89 | /*****************************************************************************/ |
90 | /* Parses the csv file and return a list of stocks structure. */ | 90 | /* Parses the csv file and return a list of stocks structure. */ |
91 | /* *csv points on the csv file in memory */ | 91 | /* *csv points on the csv file in memory */ |
92 | /* count defines the country, because csv depends on the country */ | 92 | /* count defines the country, because csv depends on the country */ |
93 | /*****************************************************************************/ | 93 | /*****************************************************************************/ |
94 | stock *parse_csv_file(char *csv) | 94 | stock *parse_csv_file(char *csv) |
95 | { | 95 | { |
96 | char *line; | 96 | char *line; |
97 | char *end_line; | 97 | char *end_line; |
98 | 98 | ||
99 | char *ptr; | 99 | char *ptr; |
100 | 100 | ||
101 | char *date; | 101 | char *date; |
102 | char *time; | 102 | char *time; |
103 | char *name; | 103 | char *name; |
104 | char *symbol; | 104 | char *symbol; |
105 | 105 | ||
106 | stock *StockPtr=NULL; | 106 | stock *StockPtr=NULL; |
107 | stock *LastStockPtr=NULL; | 107 | stock *LastStockPtr=NULL; |
108 | 108 | ||
109 | /* Used to return the pointer to the list */ | 109 | /* Used to return the pointer to the list */ |
110 | stock *FirstStockPtr=NULL; | 110 | stock *FirstStockPtr=NULL; |
111 | 111 | ||
112 | /* used to see if symbol is valid */ | 112 | /* used to see if symbol is valid */ |
113 | int valid; | 113 | int valid; |
114 | char *test; | 114 | char *test; |
115 | 115 | ||
116 | line = csv; | 116 | line = csv; |
117 | end_line = csv; | 117 | end_line = csv; |
118 | 118 | ||
119 | while ((end_line = strstr(line, "\n"))) | 119 | while ((end_line = strstr(line, "\n"))) |
120 | { | 120 | { |
121 | *end_line = 0; | 121 | *end_line = 0; |
122 | 122 | ||
123 | /* Check if symbol valid */ | 123 | /* Check if symbol valid */ |
124 | /* if 1 "N/A" then ok because Indices have N/A for volume */ | 124 | /* if 1 "N/A" then ok because Indices have N/A for volume */ |
125 | /* if 4 "N/A" then ok because Mutual funds have */ | 125 | /* if 4 "N/A" then ok because Mutual funds have */ |
126 | /* if 5 "N/A" then ok because currencies have */ | 126 | /* if 5 "N/A" then ok because currencies have */ |
127 | /* So if >5 then stock not valid */ | 127 | /* So if >5 then stock not valid */ |
128 | 128 | ||
129 | test = line; | 129 | test = line; |
130 | valid = 0; | 130 | valid = 0; |
131 | while ( (test = strstr(test, "N/A")) ) | 131 | while ( (test = strstr(test, "N/A")) ) |
132 | { | 132 | { |
133 | valid ++; | 133 | valid ++; |
134 | test = test +3; | 134 | test = test +3; |
135 | } | 135 | } |
136 | 136 | ||
137 | if (valid < 6) | 137 | if (valid < 6) |
138 | { | 138 | { |
139 | /* This Symbol is valid */ | 139 | /* This Symbol is valid */ |
140 | 140 | ||
141 | StockPtr = malloc_stock(); | 141 | StockPtr = malloc_stock(); |
142 | 142 | ||
143 | ptr = csv_strtok(line, ","); | 143 | ptr = csv_strtok(line, ","); |
144 | if (!ptr) return 0; | 144 | if (!ptr) |
145 | { | ||
146 | free_stock(StockPtr); | ||
147 | return 0; | ||
148 | } | ||
145 | 149 | ||
146 | symbol = (char *)malloc(strlen(ptr)+1); | 150 | symbol = (char *)malloc(strlen(ptr)+1); |
147 | if (symbol==NULL) | 151 | if (symbol==NULL) |
148 | { | 152 | { |
149 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 153 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
150 | ,__FILE__, __LINE__); | 154 | ,__FILE__, __LINE__); |
151 | exit(1); | 155 | exit(1); |
152 | } | 156 | } |
153 | strcpy((char *)(symbol), ptr); | 157 | strcpy((char *)(symbol), ptr); |
154 | StockPtr->Symbol = symbol; | 158 | StockPtr->Symbol = symbol; |
155 | 159 | ||
156 | ptr = csv_strtok(NULL, ","); | 160 | ptr = csv_strtok(NULL, ","); |
157 | if (!ptr) return 0; | 161 | if (!ptr) |
162 | { | ||
163 | free_stock(StockPtr); | ||
164 | return 0; | ||
165 | } | ||
158 | 166 | ||
159 | name = (char *)malloc(strlen(ptr)+1); | 167 | name = (char *)malloc(strlen(ptr)+1); |
160 | if (name==NULL) | 168 | if (name==NULL) |
161 | { | 169 | { |
162 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 170 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
163 | ,__FILE__, __LINE__); | 171 | ,__FILE__, __LINE__); |
164 | exit(1); | 172 | exit(1); |
165 | } | 173 | } |
166 | strcpy((char *)(name), ptr); | 174 | strcpy((char *)(name), ptr); |
167 | StockPtr->Name = name; | 175 | StockPtr->Name = name; |
168 | 176 | ||
169 | ptr = csv_strtok(NULL, ","); | 177 | ptr = csv_strtok(NULL, ","); |
170 | if (!ptr) return 0; | 178 | if (!ptr) |
179 | { | ||
180 | free_stock(StockPtr); | ||
181 | return 0; | ||
182 | } | ||
171 | sscanf(ptr,"%f",&(StockPtr->CurrentPrice)); | 183 | sscanf(ptr,"%f",&(StockPtr->CurrentPrice)); |
172 | 184 | ||
173 | ptr = csv_strtok(NULL, ","); | 185 | ptr = csv_strtok(NULL, ","); |
174 | if (!ptr) return 0; | 186 | if (!ptr) |
187 | { | ||
188 | free_stock(StockPtr); | ||
189 | return 0; | ||
190 | } | ||
175 | 191 | ||
176 | date = (char *)malloc(strlen(ptr)+1); | 192 | date = (char *)malloc(strlen(ptr)+1); |
177 | if (date==NULL) | 193 | if (date==NULL) |
178 | { | 194 | { |
179 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 195 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
180 | ,__FILE__, __LINE__); | 196 | ,__FILE__, __LINE__); |
181 | exit(1); | 197 | exit(1); |
182 | } | 198 | } |
183 | strcpy((char *)(date), ptr); | 199 | strcpy((char *)(date), ptr); |
184 | StockPtr->Date = date; | 200 | StockPtr->Date = date; |
185 | 201 | ||
186 | ptr = csv_strtok(NULL, ","); | 202 | ptr = csv_strtok(NULL, ","); |
187 | if (!ptr) return 0; | 203 | if (!ptr) |
204 | { | ||
205 | free_stock(StockPtr); | ||
206 | return 0; | ||
207 | } | ||
188 | 208 | ||
189 | time = (char *)malloc(strlen(ptr)+1); | 209 | time = (char *)malloc(strlen(ptr)+1); |
190 | if (time==NULL) | 210 | if (time==NULL) |
191 | { | 211 | { |
192 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 212 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
193 | ,__FILE__, __LINE__); | 213 | ,__FILE__, __LINE__); |
194 | exit(1); | 214 | exit(1); |
195 | } | 215 | } |
196 | strcpy((char *)(time), ptr); | 216 | strcpy((char *)(time), ptr); |
197 | StockPtr->Time = time; | 217 | StockPtr->Time = time; |
198 | 218 | ||
199 | ptr = csv_strtok(NULL, ","); | 219 | ptr = csv_strtok(NULL, ","); |
200 | if (!ptr) return 0; | 220 | if (!ptr) |
221 | { | ||
222 | free_stock(StockPtr); | ||
223 | return 0; | ||
224 | } | ||
201 | sscanf(ptr,"%f",&(StockPtr->Variation)); | 225 | sscanf(ptr,"%f",&(StockPtr->Variation)); |
202 | 226 | ||
203 | StockPtr->Pourcentage = 100 * StockPtr->Variation / | 227 | StockPtr->Pourcentage = 100 * StockPtr->Variation / |
204 | (StockPtr->CurrentPrice - StockPtr->Variation); | 228 | (StockPtr->CurrentPrice - StockPtr->Variation); |
205 | 229 | ||
206 | StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation; | 230 | StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation; |
207 | 231 | ||
208 | ptr = csv_strtok(NULL, ","); | 232 | ptr = csv_strtok(NULL, ","); |
209 | if (!ptr) return 0; | 233 | if (!ptr) |
234 | { | ||
235 | free_stock(StockPtr); | ||
236 | return 0; | ||
237 | } | ||
210 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); | 238 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); |
211 | 239 | ||
212 | ptr = csv_strtok(NULL, ","); | 240 | ptr = csv_strtok(NULL, ","); |
213 | if (!ptr) return 0; | 241 | if (!ptr) |
242 | { | ||
243 | free_stock(StockPtr); | ||
244 | return 0; | ||
245 | } | ||
214 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); | 246 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); |
215 | 247 | ||
216 | ptr = csv_strtok(NULL, ","); | 248 | ptr = csv_strtok(NULL, ","); |
217 | if (!ptr) return 0; | 249 | if (!ptr) |
250 | { | ||
251 | free_stock(StockPtr); | ||
252 | return 0; | ||
253 | } | ||
218 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); | 254 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); |
219 | 255 | ||
220 | ptr = csv_strtok(NULL, ","); | 256 | ptr = csv_strtok(NULL, ","); |
221 | if (!ptr) return 0; | 257 | if (!ptr) |
258 | { | ||
259 | free_stock(StockPtr); | ||
260 | return 0; | ||
261 | } | ||
222 | StockPtr->Volume = atoi(ptr); | 262 | StockPtr->Volume = atoi(ptr); |
223 | 263 | ||
224 | if( !FirstStockPtr ) | 264 | if( !FirstStockPtr ) |
225 | { | 265 | { |
226 | FirstStockPtr = StockPtr; | 266 | FirstStockPtr = StockPtr; |
227 | StockPtr->PreviousStock = 0; | 267 | StockPtr->PreviousStock = 0; |
228 | } | 268 | } |
229 | 269 | ||
230 | StockPtr->NextStock = 0; | 270 | StockPtr->NextStock = 0; |
231 | 271 | ||
232 | if (LastStockPtr) | 272 | if (LastStockPtr) |
233 | { | 273 | { |
234 | LastStockPtr->NextStock = StockPtr; | 274 | LastStockPtr->NextStock = StockPtr; |
235 | StockPtr->PreviousStock = LastStockPtr; | 275 | StockPtr->PreviousStock = LastStockPtr; |
236 | } | 276 | } |
237 | 277 | ||
238 | LastStockPtr = StockPtr; | 278 | LastStockPtr = StockPtr; |
239 | 279 | ||
240 | } | 280 | } |
241 | else | 281 | else |
242 | { | 282 | { |
243 | /* this symbol is not valid */ | 283 | /* this symbol is not valid */ |
244 | /* Set the stock struct just with Symbol, all other are NULL */ | 284 | /* Set the stock struct just with Symbol, all other are NULL */ |
245 | /* This can be used to see if the symbol has been reached are not */ | 285 | /* This can be used to see if the symbol has been reached are not */ |
246 | 286 | ||
247 | StockPtr = malloc_stock(); | 287 | StockPtr = malloc_stock(); |
248 | 288 | ||
249 | ptr = csv_strtok(line, ","); | 289 | ptr = csv_strtok(line, ","); |
250 | if (!ptr) return 0; | 290 | if (!ptr) |
291 | { | ||
292 | free_stock(StockPtr); | ||
293 | return 0; | ||
294 | } | ||
251 | 295 | ||
252 | symbol = (char *)malloc(strlen(ptr)+1); | 296 | symbol = (char *)malloc(strlen(ptr)+1); |
253 | if (symbol==NULL) | 297 | if (symbol==NULL) |
254 | { | 298 | { |
255 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 299 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
256 | ,__FILE__, __LINE__); | 300 | ,__FILE__, __LINE__); |
257 | exit(1); | 301 | exit(1); |
258 | } | 302 | } |
259 | strcpy((char *)(symbol), ptr); | 303 | strcpy((char *)(symbol), ptr); |
260 | StockPtr->Symbol = symbol; | 304 | StockPtr->Symbol = symbol; |
261 | 305 | ||
262 | if( !FirstStockPtr ) | 306 | if( !FirstStockPtr ) |
263 | { | 307 | { |
264 | FirstStockPtr = StockPtr; | 308 | FirstStockPtr = StockPtr; |
265 | StockPtr->PreviousStock = 0; | 309 | StockPtr->PreviousStock = 0; |
266 | } | 310 | } |
267 | 311 | ||
268 | StockPtr->NextStock = 0; | 312 | StockPtr->NextStock = 0; |
269 | 313 | ||
270 | if (LastStockPtr) | 314 | if (LastStockPtr) |
271 | { | 315 | { |
272 | LastStockPtr->NextStock = StockPtr; | 316 | LastStockPtr->NextStock = StockPtr; |
273 | StockPtr->PreviousStock = LastStockPtr; | 317 | StockPtr->PreviousStock = LastStockPtr; |
274 | } | 318 | } |
275 | 319 | ||
276 | LastStockPtr = StockPtr; | 320 | LastStockPtr = StockPtr; |
277 | } | 321 | } |
278 | 322 | ||
279 | end_line++; | 323 | end_line++; |
280 | line = end_line; | 324 | line = end_line; |
281 | 325 | ||
282 | } | 326 | } |
283 | 327 | ||
284 | return (FirstStockPtr); | 328 | return (FirstStockPtr); |
285 | } | 329 | } |
286 | 330 | ||
287 | /*****************************************************************************/ | 331 | /*****************************************************************************/ |
288 | /* Parses the history quotes file and return a stock structure list. */ | 332 | /* Parses the history quotes file and return a stock structure list. */ |
289 | /*****************************************************************************/ | 333 | /*****************************************************************************/ |
290 | stock *parse_csv_history_file(char *csv_file) | 334 | stock *parse_csv_history_file(char *csv_file) |
291 | { | 335 | { |
292 | 336 | ||
293 | char *line; | 337 | char *line; |
294 | char *end_line; | 338 | char *end_line; |
295 | char *ptr; | 339 | char *ptr; |
296 | 340 | ||
297 | int day; | 341 | int day; |
298 | char smonth[10]; | 342 | char smonth[10]; |
299 | int month; | 343 | int month; |
300 | int year; | 344 | int year; |
301 | 345 | ||
302 | char *date; | 346 | char *date; |
303 | 347 | ||
304 | int i; | 348 | int i; |
305 | int test; | 349 | int test; |
306 | 350 | ||
307 | stock *StockPtr=NULL; | 351 | stock *StockPtr=NULL; |
308 | stock *LastStockPtr=NULL; | 352 | stock *LastStockPtr=NULL; |
309 | 353 | ||
310 | /* Used to return the pointer to the list */ | 354 | /* Used to return the pointer to the list */ |
311 | stock *FirstStockPtr=NULL; | 355 | stock *FirstStockPtr=NULL; |
312 | 356 | ||
313 | line = csv_file; | 357 | line = csv_file; |
314 | end_line = csv_file; | 358 | end_line = csv_file; |
315 | 359 | ||
316 | /* do not use the first line */ | 360 | /* do not use the first line */ |
317 | if (!(end_line = strstr(line, "\n"))) | 361 | if (!(end_line = strstr(line, "\n"))) |
318 | return 0; | 362 | return 0; |
319 | *end_line = 0; | 363 | *end_line = 0; |
320 | end_line++; | 364 | end_line++; |
321 | line = end_line; | 365 | line = end_line; |
322 | 366 | ||
323 | while ((end_line = strstr(line, "\n"))) | 367 | while ((end_line = strstr(line, "\n"))) |
324 | { | 368 | { |
325 | *end_line = 0; | 369 | *end_line = 0; |
326 | 370 | ||
327 | StockPtr = malloc_stock(); | 371 | StockPtr = malloc_stock(); |
328 | 372 | ||
329 | /* Date */ | 373 | /* Date */ |
330 | ptr = strtok(line, ","); | 374 | ptr = strtok(line, ","); |
331 | if (!ptr) return 0; | 375 | if (!ptr) |
376 | { | ||
377 | free_stock(StockPtr); | ||
378 | free_stock(FirstStockPtr); | ||
379 | free_stock(LastStockPtr); | ||
380 | return 0; | ||
381 | } | ||
332 | 382 | ||
333 | sscanf(ptr,"%d-%3s-%d",&day,smonth,&year); | 383 | sscanf(ptr,"%d-%3s-%d",&day,smonth,&year); |
334 | 384 | ||
335 | i=0; | 385 | i=0; |
336 | 386 | ||
337 | #ifdef __UNIX__ | 387 | #ifdef __UNIX__ |
338 | while((test=strcasecmp(months[i], smonth))) i++; | 388 | while((test=strcasecmp(months[i], smonth))) i++; |
339 | #elif __WINDOWS__ | 389 | #elif __WINDOWS__ |
340 | while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++; | 390 | while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++; |
341 | #endif | 391 | #endif |
342 | 392 | ||
343 | month = i+1; | 393 | month = i+1; |
344 | 394 | ||
345 | date = (char *)malloc(DATE_LENGTH); | 395 | date = (char *)malloc(DATE_LENGTH); |
346 | if (date==NULL) | 396 | if (date==NULL) |
347 | { | 397 | { |
348 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 398 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
349 | ,__FILE__, __LINE__); | 399 | ,__FILE__, __LINE__); |
350 | exit(1); | 400 | exit(1); |
351 | } | 401 | } |
352 | sprintf(date,"%.2d%.2d%.2d", year, month, day); | 402 | sprintf(date,"%.2d%.2d%.2d", year, month, day); |
353 | StockPtr->Date = date; | 403 | StockPtr->Date = date; |
354 | 404 | ||
355 | /* Open */ | 405 | /* Open */ |
356 | ptr = strtok(NULL, ","); | 406 | ptr = strtok(NULL, ","); |
357 | if (!ptr) return 0; | 407 | if (!ptr) |
408 | { | ||
409 | free_stock(StockPtr); | ||
410 | free_stock(FirstStockPtr); | ||
411 | free_stock(LastStockPtr); | ||
412 | return 0; | ||
413 | } | ||
358 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); | 414 | sscanf(ptr,"%f",&(StockPtr->OpenPrice)); |
359 | 415 | ||
360 | /* High */ | 416 | /* High */ |
361 | ptr = strtok(NULL, ","); | 417 | ptr = strtok(NULL, ","); |
362 | if (!ptr) return 0; | 418 | if (!ptr) |
419 | { | ||
420 | free_stock(StockPtr); | ||
421 | free_stock(FirstStockPtr); | ||
422 | free_stock(LastStockPtr); | ||
423 | return 0; | ||
424 | } | ||
363 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); | 425 | sscanf(ptr,"%f",&(StockPtr->MaxPrice)); |
364 | 426 | ||
365 | /* Low */ | 427 | /* Low */ |
366 | ptr = strtok(NULL, ","); | 428 | ptr = strtok(NULL, ","); |
367 | if (!ptr) return 0; | 429 | if (!ptr) |
430 | { | ||
431 | free_stock(StockPtr); | ||
432 | free_stock(FirstStockPtr); | ||
433 | free_stock(LastStockPtr); | ||
434 | return 0; | ||
435 | } | ||
368 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); | 436 | sscanf(ptr,"%f",&(StockPtr->MinPrice)); |
369 | 437 | ||
370 | /* Close */ | 438 | /* Close */ |
371 | ptr = strtok(NULL, ","); | 439 | ptr = strtok(NULL, ","); |
372 | if (!ptr) return 0; | 440 | if (!ptr) |
441 | { | ||
442 | free_stock(StockPtr); | ||
443 | free_stock(FirstStockPtr); | ||
444 | free_stock(LastStockPtr); | ||
445 | return 0; | ||
446 | } | ||
373 | sscanf(ptr,"%f",&(StockPtr->LastPrice)); | 447 | sscanf(ptr,"%f",&(StockPtr->LastPrice)); |
374 | 448 | ||
375 | /* Volume */ | 449 | /* Volume */ |
376 | 450 | ||
377 | ptr = strtok(NULL, ","); | 451 | ptr = strtok(NULL, ","); |
378 | if (!ptr) | 452 | if (!ptr) |
379 | /* It seems to be an indice */ | 453 | /* It seems to be an indice */ |
380 | /* No volume for indices */ | 454 | /* No volume for indices */ |
381 | StockPtr->Volume = 0; | 455 | StockPtr->Volume = 0; |
382 | else | 456 | else |
383 | StockPtr->Volume = atoi(ptr); | 457 | StockPtr->Volume = atoi(ptr); |
384 | 458 | ||
385 | if( !FirstStockPtr ) | 459 | if( !FirstStockPtr ) |
386 | { | 460 | { |
387 | FirstStockPtr = StockPtr; | 461 | FirstStockPtr = StockPtr; |
388 | StockPtr->PreviousStock = 0; | 462 | StockPtr->PreviousStock = 0; |
389 | } | 463 | } |
390 | 464 | ||
391 | StockPtr->NextStock = 0; | 465 | StockPtr->NextStock = 0; |
392 | 466 | ||
393 | if (LastStockPtr) | 467 | if (LastStockPtr) |
394 | { | 468 | { |
395 | LastStockPtr->NextStock = StockPtr; | 469 | LastStockPtr->NextStock = StockPtr; |
396 | StockPtr->PreviousStock = LastStockPtr; | 470 | StockPtr->PreviousStock = LastStockPtr; |
397 | } | 471 | } |
398 | 472 | ||
399 | LastStockPtr = StockPtr; | 473 | LastStockPtr = StockPtr; |
400 | 474 | ||
401 | end_line++; | 475 | end_line++; |
402 | line = end_line; | 476 | line = end_line; |
403 | } | 477 | } |
404 | 478 | ||
405 | return (FirstStockPtr); | 479 | return (FirstStockPtr); |
406 | } | 480 | } |
diff --git a/noncore/todayplugins/stockticker/libstocks/currency.c b/noncore/todayplugins/stockticker/libstocks/currency.c index 9a08a9d..e0090e2 100644 --- a/noncore/todayplugins/stockticker/libstocks/currency.c +++ b/noncore/todayplugins/stockticker/libstocks/currency.c | |||
@@ -1,66 +1,67 @@ | |||
1 | /* libstocks - Library to get current stock quotes from Yahoo Finance | 1 | /* libstocks - Library to get current stock quotes from Yahoo Finance |
2 | * | 2 | * |
3 | * Copyright (C) 2000 Eric Laeuffer | 3 | * Copyright (C) 2000 Eric Laeuffer |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public | 6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either | 7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. | 8 | * version 2 of the License, or (at your option) any later version. |
9 | * | 9 | * |
10 | * This library is distributed in the hope that it will be useful, | 10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. | 13 | * Library General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU Library General Public | 15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library; if not, write to the | 16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. | 18 | * Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define __CURRENCY_C__ | 21 | #define __CURRENCY_C__ |
22 | 22 | ||
23 | 23 | ||
24 | #include <stdio.h> | 24 | #include <stdio.h> |
25 | #include <string.h> | 25 | #include <string.h> |
26 | #include <malloc.h> | 26 | #include <malloc.h> |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | 28 | ||
29 | #include "stocks.h" | 29 | #include "stocks.h" |
30 | 30 | ||
31 | /*****************************************************************************/ | 31 | /*****************************************************************************/ |
32 | /* returns the currency exchange rate of "from" currency into */ | 32 | /* returns the currency exchange rate of "from" currency into */ |
33 | /* "into" currency. */ | 33 | /* "into" currency. */ |
34 | /*****************************************************************************/ | 34 | /*****************************************************************************/ |
35 | libstocks_return_code get_currency_exchange(char *from, | 35 | libstocks_return_code get_currency_exchange(char *from, |
36 | char *into, | 36 | char *into, |
37 | float *exchange) | 37 | float *exchange) |
38 | { | 38 | { |
39 | char *symbol; | 39 | char *symbol; |
40 | stock *data; | 40 | stock *data; |
41 | libstocks_return_code error; | 41 | libstocks_return_code error; |
42 | 42 | ||
43 | if((symbol = (char *)malloc(strlen(from)+strlen(into)+3))==NULL) | 43 | if((symbol = (char *)malloc(strlen(from)+strlen(into)+3))==NULL) |
44 | { | 44 | { |
45 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 45 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
46 | ,__FILE__, __LINE__); | 46 | ,__FILE__, __LINE__); |
47 | exit(1); | 47 | exit(1); |
48 | } | 48 | } |
49 | 49 | ||
50 | strcpy(symbol, from); | 50 | strcpy(symbol, from); |
51 | strcat(symbol, into); | 51 | strcat(symbol, into); |
52 | strcat(symbol, "=X"); | 52 | strcat(symbol, "=X"); |
53 | 53 | ||
54 | error = get_stocks(symbol, &data); | 54 | error = get_stocks(symbol, &data); |
55 | free(symbol); | ||
55 | if (error) | 56 | if (error) |
56 | { | 57 | { |
57 | *exchange = 0; | 58 | *exchange = 0; |
58 | return(error); | 59 | return(error); |
59 | } | 60 | } |
60 | 61 | ||
61 | free_stocks(data); | 62 | free_stocks(data); |
62 | 63 | ||
63 | *exchange = data->CurrentPrice; | 64 | *exchange = data->CurrentPrice; |
64 | return(error); | 65 | return(error); |
65 | 66 | ||
66 | } | 67 | } |
diff --git a/noncore/todayplugins/stockticker/libstocks/lists.h b/noncore/todayplugins/stockticker/libstocks/lists.h index 0132317..a0eb434 100644 --- a/noncore/todayplugins/stockticker/libstocks/lists.h +++ b/noncore/todayplugins/stockticker/libstocks/lists.h | |||
@@ -1,35 +1,36 @@ | |||
1 | /* libstocks - Library to get current stock quotes from Yahoo Finance | 1 | /* libstocks - Library to get current stock quotes from Yahoo Finance |
2 | * | 2 | * |
3 | * Copyright (C) 2000 Eric Laeuffer | 3 | * Copyright (C) 2000 Eric Laeuffer |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public | 6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either | 7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. | 8 | * version 2 of the License, or (at your option) any later version. |
9 | * | 9 | * |
10 | * This library is distributed in the hope that it will be useful, | 10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. | 13 | * Library General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU Library General Public | 15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library; if not, write to the | 16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. | 18 | * Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifndef __LISTS_H__ | 21 | #ifndef __LISTS_H__ |
22 | #define __LISTS_H__ | 22 | #define __LISTS_H__ |
23 | 23 | ||
24 | #ifndef __LISTS_C__ | 24 | #ifndef __LISTS_C__ |
25 | #define PUBEXT_LISTS extern | 25 | #define PUBEXT_LISTS extern |
26 | #else | 26 | #else |
27 | #define PUBEXT_LISTS | 27 | #define PUBEXT_LISTS |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #include "stocks.h" | 30 | #include "stocks.h" |
31 | 31 | ||
32 | PUBEXT_LISTS stock *malloc_stock(void); | 32 | PUBEXT_LISTS stock *malloc_stock(void); |
33 | PUBEXT_LISTS void free_stock(stock*); | ||
33 | 34 | ||
34 | 35 | ||
35 | #endif /* __LISTS_H */ | 36 | #endif /* __LISTS_H */ |
diff --git a/noncore/todayplugins/stockticker/libstocks/stocks.c b/noncore/todayplugins/stockticker/libstocks/stocks.c index eb04ba9..3a26a47 100644 --- a/noncore/todayplugins/stockticker/libstocks/stocks.c +++ b/noncore/todayplugins/stockticker/libstocks/stocks.c | |||
@@ -1,347 +1,348 @@ | |||
1 | /* libstocks - Library to get current stock quotes from Yahoo Finance | 1 | /* libstocks - Library to get current stock quotes from Yahoo Finance |
2 | * | 2 | * |
3 | * Copyright (C) 2000 Eric Laeuffer | 3 | * Copyright (C) 2000 Eric Laeuffer |
4 | * | 4 | * |
5 | * This library is free software; you can redistribute it and/or | 5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public | 6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either | 7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. | 8 | * version 2 of the License, or (at your option) any later version. |
9 | * | 9 | * |
10 | * This library is distributed in the hope that it will be useful, | 10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. | 13 | * Library General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU Library General Public | 15 | * You should have received a copy of the GNU Library General Public |
16 | * License along with this library; if not, write to the | 16 | * License along with this library; if not, write to the |
17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | * Boston, MA 02111-1307, USA. | 18 | * Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define __STOCKS_C__ | 21 | #define __STOCKS_C__ |
22 | 22 | ||
23 | #include <stdio.h> | 23 | #include <stdio.h> |
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include <malloc.h> | 25 | #include <malloc.h> |
26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
27 | 27 | ||
28 | #ifdef __WINDOWS__ | 28 | #ifdef __WINDOWS__ |
29 | #include <mbstring.h> | 29 | #include <mbstring.h> |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #include "http.h" | 32 | #include "http.h" |
33 | #include "csv.h" | 33 | #include "csv.h" |
34 | 34 | ||
35 | #include "stocks.h" | 35 | #include "stocks.h" |
36 | 36 | ||
37 | /* | 37 | /* |
38 | s = symbol | 38 | s = symbol |
39 | n = name | 39 | n = name |
40 | l1 = last trade | 40 | l1 = last trade |
41 | d1 = date | 41 | d1 = date |
42 | t1 = time | 42 | t1 = time |
43 | c1 = variation | 43 | c1 = variation |
44 | o = open | 44 | o = open |
45 | h = higher price | 45 | h = higher price |
46 | g = lower price | 46 | g = lower price |
47 | v = volume | 47 | v = volume |
48 | */ | 48 | */ |
49 | 49 | ||
50 | const char yahoo_us_stocks_server[]="finance.yahoo.com"; | 50 | const char yahoo_us_stocks_server[]="finance.yahoo.com"; |
51 | const char yahoo_eu_stocks_server[]="finance.yahoo.com"; | 51 | const char yahoo_eu_stocks_server[]="finance.yahoo.com"; |
52 | //const char yahoo_eu_stocks_server[]="fr.finance.yahoo.com"; | 52 | //const char yahoo_eu_stocks_server[]="fr.finance.yahoo.com"; |
53 | 53 | ||
54 | const char yahoo_url_beg[]="/d/quotes.csv?s="; | 54 | const char yahoo_url_beg[]="/d/quotes.csv?s="; |
55 | const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; | 55 | const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; |
56 | 56 | ||
57 | typedef enum { | 57 | typedef enum { |
58 | YAHOO_EUROPE, | 58 | YAHOO_EUROPE, |
59 | YAHOO_US | 59 | YAHOO_US |
60 | } yahoo_source; | 60 | } yahoo_source; |
61 | 61 | ||
62 | #define YAHOO_US_EXT_NB 11 | 62 | #define YAHOO_US_EXT_NB 11 |
63 | const char *yahoo_us_ext[YAHOO_US_EXT_NB] = | 63 | const char *yahoo_us_ext[YAHOO_US_EXT_NB] = |
64 | { | 64 | { |
65 | ".US", /* United States */ | 65 | ".US", /* United States */ |
66 | ".TO", /* Canada */ | 66 | ".TO", /* Canada */ |
67 | ".M", /* Canada */ | 67 | ".M", /* Canada */ |
68 | ".V", /* Canada */ | 68 | ".V", /* Canada */ |
69 | ".AL", /* Canada */ | 69 | ".AL", /* Canada */ |
70 | ".MX", /* Mexico */ | 70 | ".MX", /* Mexico */ |
71 | ".SA", /* Brasil */ | 71 | ".SA", /* Brasil */ |
72 | ".BA", /* Argentina */ | 72 | ".BA", /* Argentina */ |
73 | ".CR", /* Venezuela */ | 73 | ".CR", /* Venezuela */ |
74 | ".SN", /* Chili */ | 74 | ".SN", /* Chili */ |
75 | ".AX" /* Australia */ | 75 | ".AX" /* Australia */ |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /*****************************************************************************/ | 78 | /*****************************************************************************/ |
79 | /* Finds, according to the symbol extension, the http source of the quotes. */ | 79 | /* Finds, according to the symbol extension, the http source of the quotes. */ |
80 | /* Actually just finance.yahoo.com and fr.finance.yahoo.com are supported. */ | 80 | /* Actually just finance.yahoo.com and fr.finance.yahoo.com are supported. */ |
81 | /* The function returns the country source (US or EUROPE). */ | 81 | /* The function returns the country source (US or EUROPE). */ |
82 | /*****************************************************************************/ | 82 | /*****************************************************************************/ |
83 | yahoo_source find_yahoo_source(char *symbol) | 83 | yahoo_source find_yahoo_source(char *symbol) |
84 | { | 84 | { |
85 | char *ptr; | 85 | char *ptr; |
86 | int i; | 86 | int i; |
87 | int test; | 87 | int test; |
88 | 88 | ||
89 | ptr = strrchr(symbol, '.'); | 89 | ptr = strrchr(symbol, '.'); |
90 | 90 | ||
91 | /* If no extension we suppose it is a US stock */ | 91 | /* If no extension we suppose it is a US stock */ |
92 | if (!ptr) return YAHOO_US; | 92 | if (!ptr) return YAHOO_US; |
93 | 93 | ||
94 | /* extension is found */ | 94 | /* extension is found */ |
95 | 95 | ||
96 | /* Test if it is canadian stock */ | 96 | /* Test if it is canadian stock */ |
97 | for (i=0; i<YAHOO_US_EXT_NB; i++) | 97 | for (i=0; i<YAHOO_US_EXT_NB; i++) |
98 | { | 98 | { |
99 | 99 | ||
100 | #ifdef __UNIX__ | 100 | #ifdef __UNIX__ |
101 | test = strcasecmp(yahoo_us_ext[i], ptr); | 101 | test = strcasecmp(yahoo_us_ext[i], ptr); |
102 | #elif __WINDOWS__ | 102 | #elif __WINDOWS__ |
103 | test = _mbsnbicmp(yahoo_us_ext[i], ptr, strlen(yahoo_us_ext[i])); | 103 | test = _mbsnbicmp(yahoo_us_ext[i], ptr, strlen(yahoo_us_ext[i])); |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | if (!test) return YAHOO_US; | 106 | if (!test) return YAHOO_US; |
107 | } | 107 | } |
108 | 108 | ||
109 | /* We suppose now it is a European stock */ | 109 | /* We suppose now it is a European stock */ |
110 | return YAHOO_EUROPE; | 110 | return YAHOO_EUROPE; |
111 | } | 111 | } |
112 | 112 | ||
113 | /*****************************************************************************/ | 113 | /*****************************************************************************/ |
114 | /* Gets quotes csv file, parses the file and create the quotes list */ | 114 | /* Gets quotes csv file, parses the file and create the quotes list */ |
115 | /* *stocks points to the stocks to fetch */ | 115 | /* *stocks points to the stocks to fetch */ |
116 | /* *stock_datas points to the beginning of the list */ | 116 | /* *stock_datas points to the beginning of the list */ |
117 | /* count allows to connect to all country servers */ | 117 | /* count allows to connect to all country servers */ |
118 | /*****************************************************************************/ | 118 | /*****************************************************************************/ |
119 | libstocks_return_code download_stocks(char *stocks, | 119 | libstocks_return_code download_stocks(char *stocks, |
120 | stock **stock_datas, | 120 | stock **stock_datas, |
121 | yahoo_source source) | 121 | yahoo_source source) |
122 | { | 122 | { |
123 | char *stocks_server=NULL; | 123 | char *stocks_server=NULL; |
124 | char *url_beg=NULL; | 124 | char *url_beg=NULL; |
125 | char *url_end=NULL; | 125 | char *url_end=NULL; |
126 | 126 | ||
127 | char *url; | 127 | char *url; |
128 | char *data; | 128 | char *data; |
129 | 129 | ||
130 | libstocks_return_code error; | 130 | libstocks_return_code error; |
131 | 131 | ||
132 | #ifdef DEBUG | 132 | #ifdef DEBUG |
133 | printf("*download_stocks\n"); | 133 | printf("*download_stocks\n"); |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | switch (source) | 136 | switch (source) |
137 | { | 137 | { |
138 | case YAHOO_US: | 138 | case YAHOO_US: |
139 | stocks_server = (char *)yahoo_us_stocks_server; | 139 | stocks_server = (char *)yahoo_us_stocks_server; |
140 | break; | 140 | break; |
141 | 141 | ||
142 | case YAHOO_EUROPE: | 142 | case YAHOO_EUROPE: |
143 | stocks_server = (char *)yahoo_eu_stocks_server; | 143 | stocks_server = (char *)yahoo_eu_stocks_server; |
144 | break; | 144 | break; |
145 | default: | 145 | default: |
146 | stocks_server = (char *)yahoo_us_stocks_server; | 146 | stocks_server = (char *)yahoo_us_stocks_server; |
147 | break; | 147 | break; |
148 | 148 | ||
149 | } | 149 | } |
150 | 150 | ||
151 | url_beg = (char *)yahoo_url_beg; | 151 | url_beg = (char *)yahoo_url_beg; |
152 | url_end = (char *)yahoo_url_end; | 152 | url_end = (char *)yahoo_url_end; |
153 | 153 | ||
154 | url = (char *)malloc(strlen(url_beg) | 154 | url = (char *)malloc(strlen(url_beg) |
155 | +strlen(url_end) | 155 | +strlen(url_end) |
156 | +strlen(stocks)+1); | 156 | +strlen(stocks)+1); |
157 | if (url==NULL) | 157 | if (url==NULL) |
158 | { | 158 | { |
159 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 159 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
160 | ,__FILE__, __LINE__); | 160 | ,__FILE__, __LINE__); |
161 | exit(1); | 161 | exit(1); |
162 | } | 162 | } |
163 | 163 | ||
164 | strcpy(url, url_beg); | 164 | strcpy(url, url_beg); |
165 | strcat(url, stocks); | 165 | strcat(url, stocks); |
166 | strcat(url, url_end); | 166 | strcat(url, url_end); |
167 | 167 | ||
168 | error=http_get(url, stocks_server, &data); | 168 | error=http_get(url, stocks_server, &data); |
169 | 169 | ||
170 | free(url); | 170 | free(url); |
171 | 171 | ||
172 | if (error) return error; | 172 | if (error) return error; |
173 | 173 | ||
174 | *stock_datas = parse_csv_file(data); | 174 | *stock_datas = parse_csv_file(data); |
175 | 175 | ||
176 | free(data); | 176 | free(data); |
177 | 177 | ||
178 | if (!(*stock_datas)) return ERRPCSV; | 178 | if (!(*stock_datas)) return ERRPCSV; |
179 | 179 | ||
180 | return 0; | 180 | return 0; |
181 | 181 | ||
182 | } | 182 | } |
183 | 183 | ||
184 | /*****************************************************************************/ | 184 | /*****************************************************************************/ |
185 | /* Gets quotes from yahoo */ | 185 | /* Gets quotes from yahoo */ |
186 | /* Choses to fetch European or US depending on the symbol extension */ | 186 | /* Choses to fetch European or US depending on the symbol extension */ |
187 | /* and merges the two lists to one */ | 187 | /* and merges the two lists to one */ |
188 | /* *stocks points to the stocks to fetch */ | 188 | /* *stocks points to the stocks to fetch */ |
189 | /* *stock_datas points to the beginning of the list */ | 189 | /* *stock_datas points to the beginning of the list */ |
190 | /*****************************************************************************/ | 190 | /*****************************************************************************/ |
191 | libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) | 191 | libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) |
192 | { | 192 | { |
193 | char *tok_ptr; | 193 | char *tok_ptr; |
194 | char *eu_quotes=NULL; | 194 | char *eu_quotes=NULL; |
195 | char *eu_quotes_temp=NULL; | 195 | char *eu_quotes_temp=NULL; |
196 | int lgr_eu_quotes=0; | 196 | int lgr_eu_quotes=0; |
197 | 197 | ||
198 | char *us_quotes=NULL; | 198 | char *us_quotes=NULL; |
199 | char *us_quotes_temp=NULL; | 199 | char *us_quotes_temp=NULL; |
200 | int lgr_us_quotes=0; | 200 | int lgr_us_quotes=0; |
201 | 201 | ||
202 | char *symbol; | 202 | char *symbol; |
203 | 203 | ||
204 | yahoo_source source; | 204 | yahoo_source source; |
205 | 205 | ||
206 | int lgr_symbol=0; | 206 | int lgr_symbol=0; |
207 | 207 | ||
208 | libstocks_return_code error; | 208 | libstocks_return_code error; |
209 | 209 | ||
210 | stock *stocks_tmp=NULL; | 210 | stock *stocks_tmp=NULL; |
211 | stock *stocks_tmp2=NULL; | 211 | stock *stocks_tmp2=NULL; |
212 | stock *stocks_getted=NULL; | 212 | stock *stocks_getted=NULL; |
213 | stock *last_stock=NULL; | 213 | stock *last_stock=NULL; |
214 | 214 | ||
215 | #ifdef DEBUG | 215 | #ifdef DEBUG |
216 | printf("*get_stocks\n"); | 216 | printf("*get_stocks\n"); |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | /* to preserve stocks */ | 219 | /* to preserve stocks */ |
220 | tok_ptr = malloc(strlen(stocks)+1); | 220 | tok_ptr = malloc(strlen(stocks)+1); |
221 | if(tok_ptr==NULL) | 221 | if(tok_ptr==NULL) |
222 | { | 222 | { |
223 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 223 | fprintf(stderr,"Memory allocating error (%s line %d)\n" |
224 | ,__FILE__, __LINE__); | 224 | ,__FILE__, __LINE__); |
225 | exit(1); | 225 | exit(1); |
226 | } | 226 | } |
227 | strcpy(tok_ptr, stocks); | 227 | strcpy(tok_ptr, stocks); |
228 | 228 | ||
229 | while( (symbol = strtok(tok_ptr, "+"))!=0) | 229 | while( (symbol = strtok(tok_ptr, "+"))!=0) |
230 | { | 230 | { |
231 | /* clear tok_ptr for next strtok */ | 231 | /* clear tok_ptr for next strtok */ |
232 | tok_ptr = NULL; | 232 | tok_ptr = NULL; |
233 | 233 | ||
234 | /* look for "." in the symbol */ | 234 | /* look for "." in the symbol */ |
235 | source = find_yahoo_source(symbol); | 235 | source = find_yahoo_source(symbol); |
236 | 236 | ||
237 | switch (source) | 237 | switch (source) |
238 | { | 238 | { |
239 | case YAHOO_US: | 239 | case YAHOO_US: |
240 | 240 | if (us_quotes) | |
241 | if (us_quotes) | 241 | { |
242 | { | 242 | lgr_us_quotes = strlen(us_quotes); |
243 | lgr_us_quotes = strlen(us_quotes); | 243 | lgr_symbol = strlen(symbol); |
244 | lgr_symbol = strlen(symbol); | 244 | |
245 | 245 | us_quotes_temp = malloc(lgr_us_quotes + lgr_symbol +2); | |
246 | us_quotes_temp = malloc(lgr_us_quotes + lgr_symbol +2); | 246 | if(us_quotes_temp==NULL) |
247 | if(us_quotes_temp==NULL) | 247 | { |
248 | { | 248 | fprintf(stderr,"Memory allocating error (%s line %d)\n", |
249 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 249 | __FILE__, __LINE__); |
250 | ,__FILE__, __LINE__); | 250 | exit(1); |
251 | exit(1); | 251 | } |
252 | } | 252 | strcpy(us_quotes_temp, us_quotes); |
253 | strcpy(us_quotes_temp, us_quotes); | 253 | strcat(us_quotes_temp,"+"); |
254 | strcat(us_quotes_temp,"+"); | 254 | strcat(us_quotes_temp,symbol); |
255 | strcat(us_quotes_temp,symbol); | 255 | |
256 | 256 | free(us_quotes); | |
257 | free(us_quotes); | 257 | us_quotes = us_quotes_temp; |
258 | us_quotes = us_quotes_temp; | 258 | } |
259 | } | 259 | else |
260 | else | 260 | { |
261 | { | 261 | us_quotes = malloc(strlen(symbol)+1); |
262 | us_quotes = malloc(strlen(symbol)+1); | 262 | |
263 | 263 | if(us_quotes==NULL) | |
264 | if(us_quotes==NULL) | 264 | { |
265 | { | 265 | fprintf(stderr,"Memory allocating error (%s line %d)\n", |
266 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 266 | __FILE__, __LINE__); |
267 | ,__FILE__, __LINE__); | 267 | exit(1); |
268 | exit(1); | 268 | } |
269 | } | 269 | strcpy(us_quotes, symbol); |
270 | strcpy(us_quotes, symbol); | 270 | } |
271 | } | 271 | |
272 | 272 | break; | |
273 | break; | 273 | |
274 | 274 | case YAHOO_EUROPE: | |
275 | case YAHOO_EUROPE: | 275 | if (eu_quotes) |
276 | 276 | { | |
277 | if (eu_quotes) | 277 | lgr_eu_quotes = strlen(eu_quotes); |
278 | { | 278 | lgr_symbol = strlen(symbol); |
279 | lgr_eu_quotes = strlen(eu_quotes); | 279 | |
280 | lgr_symbol = strlen(symbol); | 280 | eu_quotes_temp = malloc(lgr_eu_quotes + lgr_symbol +2); |
281 | 281 | if(eu_quotes_temp==NULL) | |
282 | eu_quotes_temp = malloc(lgr_eu_quotes + lgr_symbol +2); | 282 | { |
283 | if(eu_quotes_temp==NULL) | 283 | fprintf(stderr,"Memory allocating error (%s line %d)\n", |
284 | { | 284 | __FILE__, __LINE__); |
285 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 285 | exit(1); |
286 | ,__FILE__, __LINE__); | 286 | } |
287 | exit(1); | 287 | strcpy(eu_quotes_temp, eu_quotes); |
288 | } | 288 | strcat(eu_quotes_temp, "+"); |
289 | strcpy(eu_quotes_temp, eu_quotes); | 289 | strcat(eu_quotes_temp, symbol); |
290 | strcat(eu_quotes_temp, "+"); | 290 | |
291 | strcat(eu_quotes_temp, symbol); | 291 | free(eu_quotes); |
292 | 292 | eu_quotes = eu_quotes_temp; | |
293 | free(eu_quotes); | 293 | } |
294 | eu_quotes = eu_quotes_temp; | 294 | else |
295 | } | 295 | { |
296 | else | 296 | eu_quotes = malloc(strlen(symbol)+1); |
297 | { | 297 | if(eu_quotes==NULL) |
298 | eu_quotes = malloc(strlen(symbol)+1); | 298 | { |
299 | if(eu_quotes==NULL) | 299 | fprintf(stderr,"Memory allocating error (%s line %d)\n", |
300 | { | 300 | __FILE__, __LINE__); |
301 | fprintf(stderr,"Memory allocating error (%s line %d)\n" | 301 | exit(1); |
302 | ,__FILE__, __LINE__); | 302 | } |
303 | exit(1); | 303 | strcpy(eu_quotes, symbol); |
304 | } | 304 | } |
305 | strcpy(eu_quotes, symbol); | 305 | break; |
306 | } | 306 | } |
307 | break; | ||
308 | } | ||
309 | } | 307 | } |
310 | 308 | ||
311 | free(tok_ptr); | 309 | free(tok_ptr); |
312 | 310 | ||
313 | if (us_quotes) | 311 | if (us_quotes) |
314 | { | 312 | { |
315 | /* Gets us quotes */ | 313 | /* Gets us quotes */ |
316 | error = download_stocks(us_quotes, &stocks_tmp, YAHOO_US); | 314 | error = download_stocks(us_quotes, &stocks_tmp, YAHOO_US); |
315 | free(us_quotes); | ||
317 | if (error) return error; | 316 | if (error) return error; |
318 | } | 317 | } |
319 | 318 | ||
320 | if (eu_quotes) | 319 | if (eu_quotes) |
321 | { | 320 | { |
322 | /* Gets european quotes */ | 321 | /* Gets european quotes */ |
323 | error = download_stocks(eu_quotes, &stocks_getted, YAHOO_EUROPE); | 322 | error = download_stocks(eu_quotes, &stocks_getted, YAHOO_EUROPE); |
323 | free(eu_quotes); | ||
324 | if (error) return error; | 324 | if (error) return error; |
325 | 325 | ||
326 | /* concats lists if needed */ | 326 | /* concats lists if needed */ |
327 | if (stocks_tmp) | 327 | if (stocks_tmp) |
328 | { | 328 | { |
329 | stocks_tmp2 = stocks_tmp; | 329 | stocks_tmp2 = stocks_tmp; |
330 | 330 | ||
331 | while(stocks_tmp2 != NULL) | 331 | while(stocks_tmp2 != NULL) |
332 | { | 332 | { |
333 | last_stock = stocks_tmp2; | 333 | last_stock = stocks_tmp2; |
334 | stocks_tmp2 = next_stock(stocks_tmp2); | 334 | stocks_tmp2 = next_stock(stocks_tmp2); |
335 | } | 335 | } |
336 | 336 | ||
337 | last_stock->NextStock = stocks_getted; | 337 | last_stock->NextStock = stocks_getted; |
338 | stocks_getted->PreviousStock = last_stock; | 338 | stocks_getted->PreviousStock = last_stock; |
339 | 339 | ||
340 | } | 340 | } |
341 | else (stocks_tmp = stocks_getted); | 341 | else |
342 | (stocks_tmp = stocks_getted); | ||
342 | } | 343 | } |
343 | 344 | ||
344 | *stock_datas = stocks_tmp; | 345 | *stock_datas = stocks_tmp; |
345 | 346 | ||
346 | return(0); | 347 | return(0); |
347 | } | 348 | } |
diff --git a/rsync/delta.c b/rsync/delta.c index 323c079..42f3afb 100644 --- a/rsync/delta.c +++ b/rsync/delta.c | |||
@@ -1,351 +1,353 @@ | |||
1 | /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- | 1 | /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- |
2 | * | 2 | * |
3 | * librsync -- library for network deltas | 3 | * librsync -- library for network deltas |
4 | * $Id$ | 4 | * $Id$ |
5 | * | 5 | * |
6 | * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org> | 6 | * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU Lesser General Public License as published by | 9 | * it under the terms of the GNU Lesser General Public License as published by |
10 | * the Free Software Foundation; either version 2.1 of the License, or | 10 | * the Free Software Foundation; either version 2.1 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU Lesser General Public License for more details. | 16 | * GNU Lesser General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU Lesser General Public License | 18 | * You should have received a copy of the GNU Lesser General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
24 | | Let's climb to the TOP of that | 24 | | Let's climb to the TOP of that |
25 | | MOUNTAIN and think about STRIP | 25 | | MOUNTAIN and think about STRIP |
26 | | MINING!! | 26 | | MINING!! |
27 | */ | 27 | */ |
28 | 28 | ||
29 | 29 | ||
30 | /* | 30 | /* |
31 | * delta.c -- Generate in streaming mode an rsync delta given a set of | 31 | * delta.c -- Generate in streaming mode an rsync delta given a set of |
32 | * signatures, and a new file. | 32 | * signatures, and a new file. |
33 | * | 33 | * |
34 | * The size of blocks for signature generation is determined by the | 34 | * The size of blocks for signature generation is determined by the |
35 | * block size in the incoming signature. | 35 | * block size in the incoming signature. |
36 | * | 36 | * |
37 | * To calculate a signature, we need to be able to see at least one | 37 | * To calculate a signature, we need to be able to see at least one |
38 | * block of the new file at a time. Once we have that, we calculate | 38 | * block of the new file at a time. Once we have that, we calculate |
39 | * its weak signature, and see if there is any block in the signature | 39 | * its weak signature, and see if there is any block in the signature |
40 | * hash table that has the same weak sum. If there is one, then we | 40 | * hash table that has the same weak sum. If there is one, then we |
41 | * also compute the strong sum of the new block, and cross check that. | 41 | * also compute the strong sum of the new block, and cross check that. |
42 | * If they're the same, then we can assume we have a match. | 42 | * If they're the same, then we can assume we have a match. |
43 | * | 43 | * |
44 | * The final block of the file has to be handled a little differently, | 44 | * The final block of the file has to be handled a little differently, |
45 | * because it may be a short match. Short blocks in the signature | 45 | * because it may be a short match. Short blocks in the signature |
46 | * don't include their length -- we just allow for the final short | 46 | * don't include their length -- we just allow for the final short |
47 | * block of the file to match any block in the signature, and if they | 47 | * block of the file to match any block in the signature, and if they |
48 | * have the same checksum we assume they must have the same length. | 48 | * have the same checksum we assume they must have the same length. |
49 | * Therefore, when we emit a COPY command, we have to send it with a | 49 | * Therefore, when we emit a COPY command, we have to send it with a |
50 | * length that is the same as the block matched, and not the block | 50 | * length that is the same as the block matched, and not the block |
51 | * length from the signature. | 51 | * length from the signature. |
52 | */ | 52 | */ |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Profiling results as of v1.26, 2001-03-18: | 55 | * Profiling results as of v1.26, 2001-03-18: |
56 | * | 56 | * |
57 | * If everything matches, then we spend almost all our time in | 57 | * If everything matches, then we spend almost all our time in |
58 | * rs_mdfour64 and rs_weak_sum, which is unavoidable and therefore a | 58 | * rs_mdfour64 and rs_weak_sum, which is unavoidable and therefore a |
59 | * good profile. | 59 | * good profile. |
60 | * | 60 | * |
61 | * If nothing matches, it is not so good. | 61 | * If nothing matches, it is not so good. |
62 | */ | 62 | */ |
63 | 63 | ||
64 | 64 | ||
65 | #include <config_rsync.h> | 65 | #include <config_rsync.h> |
66 | 66 | ||
67 | #include <assert.h> | 67 | #include <assert.h> |
68 | #include <stdlib.h> | 68 | #include <stdlib.h> |
69 | #include <stdio.h> | 69 | #include <stdio.h> |
70 | 70 | ||
71 | #include "rsync.h" | 71 | #include "rsync.h" |
72 | #include "emit.h" | 72 | #include "emit.h" |
73 | #include "stream.h" | 73 | #include "stream.h" |
74 | #include "util.h" | 74 | #include "util.h" |
75 | #include "sumset.h" | 75 | #include "sumset.h" |
76 | #include "job.h" | 76 | #include "job.h" |
77 | #include "trace.h" | 77 | #include "trace.h" |
78 | #include "checksum.h" | 78 | #include "checksum.h" |
79 | #include "search.h" | 79 | #include "search.h" |
80 | #include "types.h" | 80 | #include "types.h" |
81 | 81 | ||
82 | 82 | ||
83 | /** | 83 | /** |
84 | * Turn this on to make all rolling checksums be checked from scratch. | 84 | * Turn this on to make all rolling checksums be checked from scratch. |
85 | */ | 85 | */ |
86 | int rs_roll_paranoia = 0; | 86 | int rs_roll_paranoia = 0; |
87 | 87 | ||
88 | 88 | ||
89 | static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); | 89 | static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); |
90 | 90 | ||
91 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job); | 91 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job); |
92 | 92 | ||
93 | 93 | ||
94 | 94 | ||
95 | static rs_result rs_delta_s_end(rs_job_t *job) | 95 | static rs_result rs_delta_s_end(rs_job_t *job) |
96 | { | 96 | { |
97 | rs_emit_end_cmd(job); | 97 | rs_emit_end_cmd(job); |
98 | return RS_DONE; | 98 | return RS_DONE; |
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
102 | /** | 102 | /** |
103 | * \brief Get a block of data if possible, and see if it matches. | 103 | * \brief Get a block of data if possible, and see if it matches. |
104 | * | 104 | * |
105 | * On each call, we try to process all of the input data available on | 105 | * On each call, we try to process all of the input data available on |
106 | * the scoop and input buffer. | 106 | * the scoop and input buffer. |
107 | */ | 107 | */ |
108 | static rs_result | 108 | static rs_result |
109 | rs_delta_s_scan(rs_job_t *job) | 109 | rs_delta_s_scan(rs_job_t *job) |
110 | { | 110 | { |
111 | size_t this_len, avail_len; | 111 | size_t this_len, avail_len; |
112 | int is_ending; | 112 | int is_ending; |
113 | void *inptr; | 113 | void *inptr; |
114 | rs_result result; | 114 | rs_result result; |
115 | 115 | ||
116 | rs_job_check(job); | 116 | rs_job_check(job); |
117 | 117 | ||
118 | avail_len = rs_scoop_total_avail(job); | 118 | avail_len = rs_scoop_total_avail(job); |
119 | this_len = job->block_len; | 119 | this_len = job->block_len; |
120 | is_ending = job->stream->eof_in; | 120 | is_ending = job->stream->eof_in; |
121 | 121 | ||
122 | /* Now, we have avail_len bytes, and we need to scan through them | 122 | /* Now, we have avail_len bytes, and we need to scan through them |
123 | * looking for a match. We'll always end up emitting exactly one | 123 | * looking for a match. We'll always end up emitting exactly one |
124 | * command, either a literal or a copy, and after discovering that | 124 | * command, either a literal or a copy, and after discovering that |
125 | * we will skip over the appropriate number of bytes. */ | 125 | * we will skip over the appropriate number of bytes. */ |
126 | if (avail_len == 0) { | 126 | if (avail_len == 0) { |
127 | if (is_ending) { | 127 | if (is_ending) { |
128 | /* no more delta to do */ | 128 | /* no more delta to do */ |
129 | job->statefn = rs_delta_s_end; | 129 | job->statefn = rs_delta_s_end; |
130 | } | 130 | } |
131 | return RS_BLOCKED; | 131 | return RS_BLOCKED; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* must read at least one block, or give up */ | 134 | /* must read at least one block, or give up */ |
135 | if ((avail_len < job->block_len) && !is_ending) { | 135 | if ((avail_len < job->block_len) && !is_ending) { |
136 | /* we know we won't get it, but we have to try for a whole | 136 | /* we know we won't get it, but we have to try for a whole |
137 | * block anyhow so that it gets into the scoop. */ | 137 | * block anyhow so that it gets into the scoop. */ |
138 | rs_scoop_input(job, job->block_len); | 138 | rs_scoop_input(job, job->block_len); |
139 | return RS_BLOCKED; | 139 | return RS_BLOCKED; |
140 | } | 140 | } |
141 | 141 | ||
142 | result = rs_scoop_readahead(job, avail_len, &inptr); | 142 | result = rs_scoop_readahead(job, avail_len, &inptr); |
143 | if (result != RS_DONE) | 143 | if (result != RS_DONE) |
144 | return result; | 144 | return result; |
145 | 145 | ||
146 | return rs_delta_scan(job, avail_len, inptr); | 146 | return rs_delta_scan(job, avail_len, inptr); |
147 | } | 147 | } |
148 | 148 | ||
149 | 149 | ||
150 | 150 | ||
151 | /** | 151 | /** |
152 | * Scan for a matching block in the next \p avail_len bytes of input. | 152 | * Scan for a matching block in the next \p avail_len bytes of input. |
153 | * | 153 | * |
154 | * If nonmatching data is found, then a LITERAL command will be put in | 154 | * If nonmatching data is found, then a LITERAL command will be put in |
155 | * the tube immediately. If matching data is found, then its position | 155 | * the tube immediately. If matching data is found, then its position |
156 | * will be saved in the job, and the job state set up to write out a | 156 | * will be saved in the job, and the job state set up to write out a |
157 | * COPY command after handling the literal. | 157 | * COPY command after handling the literal. |
158 | */ | 158 | */ |
159 | static rs_result | 159 | static rs_result |
160 | rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) | 160 | rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) |
161 | { | 161 | { |
162 | rs_long_t match_where; | 162 | rs_long_t match_where; |
163 | int search_pos, end_pos; | 163 | int search_pos, end_pos; |
164 | unsigned char *inptr = (unsigned char *) p; | 164 | unsigned char *inptr = (unsigned char *) p; |
165 | uint32_t s1 = job->weak_sig & 0xFFFF; | 165 | uint32_t s1 = job->weak_sig & 0xFFFF; |
166 | uint32_t s2 = job->weak_sig >> 16; | 166 | uint32_t s2 = job->weak_sig >> 16; |
167 | 167 | ||
168 | /* So, we have avail_len bytes of data, and we want to look | 168 | /* So, we have avail_len bytes of data, and we want to look |
169 | * through it for a match at some point. It's OK if it's not at | 169 | * through it for a match at some point. It's OK if it's not at |
170 | * the start of the available input data. If we're approaching | 170 | * the start of the available input data. If we're approaching |
171 | * the end and can't get a match, then we just block and get more | 171 | * the end and can't get a match, then we just block and get more |
172 | * later. */ | 172 | * later. */ |
173 | 173 | ||
174 | /* FIXME: Perhaps we should be working in signed chars for the | 174 | /* FIXME: Perhaps we should be working in signed chars for the |
175 | * rolling sum? */ | 175 | * rolling sum? */ |
176 | 176 | ||
177 | if (job->stream->eof_in) | 177 | if (job->stream->eof_in) |
178 | end_pos = avail_len - 1; | 178 | end_pos = avail_len - 1; |
179 | else | 179 | else |
180 | end_pos = avail_len - job->block_len; | 180 | end_pos = avail_len - job->block_len; |
181 | 181 | ||
182 | for (search_pos = 0; search_pos <= end_pos; search_pos++) { | 182 | for (search_pos = 0; search_pos <= end_pos; search_pos++) { |
183 | size_t this_len = job->block_len; | 183 | size_t this_len = job->block_len; |
184 | 184 | ||
185 | if (search_pos + this_len > avail_len) { | 185 | if (search_pos + this_len > avail_len) { |
186 | this_len = avail_len - search_pos; | 186 | this_len = avail_len - search_pos; |
187 | rs_trace("block reduced to %d", this_len); | 187 | rs_trace("block reduced to %d", this_len); |
188 | } else if (job->have_weak_sig) { | 188 | } else if (job->have_weak_sig) { |
189 | unsigned char a = inptr[search_pos + this_len - 1]; | 189 | unsigned char a = inptr[search_pos + this_len - 1]; |
190 | /* roll in the newly added byte, if any */ | 190 | /* roll in the newly added byte, if any */ |
191 | s1 += a + RS_CHAR_OFFSET; | 191 | s1 += a + RS_CHAR_OFFSET; |
192 | s2 += s1; | 192 | s2 += s1; |
193 | 193 | ||
194 | job->weak_sig = (s1 & 0xffff) | (s2 << 16); | 194 | job->weak_sig = (s1 & 0xffff) | (s2 << 16); |
195 | } | 195 | } |
196 | 196 | ||
197 | if (!job->have_weak_sig) { | 197 | if (!job->have_weak_sig) { |
198 | rs_trace("calculate weak sum from scratch"); | 198 | rs_trace("calculate weak sum from scratch"); |
199 | job->weak_sig = rs_calc_weak_sum(inptr + search_pos, this_len); | 199 | job->weak_sig = rs_calc_weak_sum(inptr + search_pos, this_len); |
200 | s1 = job->weak_sig & 0xFFFF; | 200 | s1 = job->weak_sig & 0xFFFF; |
201 | s2 = job->weak_sig >> 16; | 201 | s2 = job->weak_sig >> 16; |
202 | job->have_weak_sig = 1; | 202 | job->have_weak_sig = 1; |
203 | } | 203 | } |
204 | 204 | ||
205 | if (rs_roll_paranoia) { | 205 | if (rs_roll_paranoia) { |
206 | rs_weak_sum_t verify = rs_calc_weak_sum(inptr + search_pos, this_len); | 206 | rs_weak_sum_t verify = rs_calc_weak_sum(inptr + search_pos, this_len); |
207 | if (verify != job->weak_sig) { | 207 | if (verify != job->weak_sig) { |
208 | rs_fatal("mismatch between rolled sum %#x and check %#x", | 208 | rs_fatal("mismatch between rolled sum %#x and check %#x", |
209 | job->weak_sig, verify); | 209 | job->weak_sig, verify); |
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | if (rs_search_for_block(job->weak_sig, inptr + search_pos, this_len, | 213 | if (rs_search_for_block(job->weak_sig, inptr + search_pos, this_len, |
214 | job->signature, &job->stats, &match_where)) { | 214 | job->signature, &job->stats, &match_where)) { |
215 | /* So, we got a match. Cool. However, there may be | 215 | /* So, we got a match. Cool. However, there may be |
216 | * leading unmatched data that we need to flush. Thus we | 216 | * leading unmatched data that we need to flush. Thus we |
217 | * set our statefn to be rs_delta_s_deferred_copy so that | 217 | * set our statefn to be rs_delta_s_deferred_copy so that |
218 | * we can write out the command later. */ | 218 | * we can write out the command later. */ |
219 | 219 | ||
220 | rs_trace("matched %.0f bytes at %.0f!", | 220 | rs_trace("matched %.0f bytes at %.0f!", |
221 | (double) this_len, (double) match_where); | 221 | (double) this_len, (double) match_where); |
222 | job->basis_pos = match_where; | 222 | job->basis_pos = match_where; |
223 | job->basis_len = this_len; | 223 | job->basis_len = this_len; |
224 | job->statefn = rs_delta_s_deferred_copy; | 224 | job->statefn = rs_delta_s_deferred_copy; |
225 | job->have_weak_sig = 0; | 225 | job->have_weak_sig = 0; |
226 | break; | 226 | break; |
227 | } else { | 227 | } else { |
228 | /* advance by one; roll out the byte we just moved over. */ | 228 | /* advance by one; roll out the byte we just moved over. */ |
229 | unsigned char a = inptr[search_pos]; | 229 | unsigned char a = inptr[search_pos]; |
230 | unsigned char shift = a + RS_CHAR_OFFSET; | 230 | unsigned char shift = a + RS_CHAR_OFFSET; |
231 | 231 | ||
232 | s1 -= shift; | 232 | s1 -= shift; |
233 | s2 -= this_len * shift; | 233 | s2 -= this_len * shift; |
234 | job->weak_sig = (s1 & 0xffff) | (s2 << 16); | 234 | job->weak_sig = (s1 & 0xffff) | (s2 << 16); |
235 | } | 235 | } |
236 | } | 236 | } |
237 | 237 | ||
238 | if (search_pos > 0) { | 238 | if (search_pos > 0) { |
239 | /* We may or may not have found a block, but we know we found | 239 | /* We may or may not have found a block, but we know we found |
240 | * some literal data at the start of the buffer. Therefore, | 240 | * some literal data at the start of the buffer. Therefore, |
241 | * we have to flush that out before we can continue on and | 241 | * we have to flush that out before we can continue on and |
242 | * emit the copy command or keep searching. */ | 242 | * emit the copy command or keep searching. */ |
243 | 243 | ||
244 | /* FIXME: At the moment, if you call with very short buffers, | 244 | /* FIXME: At the moment, if you call with very short buffers, |
245 | * then you will get a series of very short LITERAL commands. | 245 | * then you will get a series of very short LITERAL commands. |
246 | * Perhaps this is what you deserve, or perhaps we should try | 246 | * Perhaps this is what you deserve, or perhaps we should try |
247 | * to get more readahead and avoid that. */ | 247 | * to get more readahead and avoid that. */ |
248 | 248 | ||
249 | /* There's some literal data at the start of this window which | 249 | /* There's some literal data at the start of this window which |
250 | * we know is not in any block. */ | 250 | * we know is not in any block. */ |
251 | rs_trace("got %d bytes of literal data", search_pos); | 251 | rs_trace("got %d bytes of literal data", search_pos); |
252 | rs_emit_literal_cmd(job, search_pos); | 252 | rs_emit_literal_cmd(job, search_pos); |
253 | rs_tube_copy(job, search_pos); | 253 | rs_tube_copy(job, search_pos); |
254 | } | 254 | } |
255 | 255 | ||
256 | return RS_RUNNING; | 256 | return RS_RUNNING; |
257 | } | 257 | } |
258 | 258 | ||
259 | 259 | ||
260 | 260 | ||
261 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job) | 261 | static rs_result rs_delta_s_deferred_copy(rs_job_t *job) |
262 | { | 262 | { |
263 | if (!job->basis_len) { | 263 | if (!job->basis_len) { |
264 | rs_log(RS_LOG_ERR, "somehow got zero basis_len"); | 264 | rs_log(RS_LOG_ERR, "somehow got zero basis_len"); |
265 | return RS_INTERNAL_ERROR; | 265 | return RS_INTERNAL_ERROR; |
266 | } | 266 | } |
267 | 267 | ||
268 | rs_emit_copy_cmd(job, job->basis_pos, job->basis_len); | 268 | rs_emit_copy_cmd(job, job->basis_pos, job->basis_len); |
269 | rs_scoop_advance(job, job->basis_len); | 269 | rs_scoop_advance(job, job->basis_len); |
270 | 270 | ||
271 | job->statefn = rs_delta_s_scan; | 271 | job->statefn = rs_delta_s_scan; |
272 | 272 | ||
273 | return RS_RUNNING; | 273 | return RS_RUNNING; |
274 | } | 274 | } |
275 | 275 | ||
276 | 276 | ||
277 | /** | 277 | /** |
278 | * \brief State function that does a slack delta containing only | 278 | * \brief State function that does a slack delta containing only |
279 | * literal data to recreate the input. | 279 | * literal data to recreate the input. |
280 | */ | 280 | */ |
281 | static rs_result rs_delta_s_slack(rs_job_t *job) | 281 | static rs_result rs_delta_s_slack(rs_job_t *job) |
282 | { | 282 | { |
283 | rs_buffers_t * const stream = job->stream; | 283 | rs_buffers_t * const stream = job->stream; |
284 | size_t avail = stream->avail_in; | 284 | size_t avail = stream->avail_in; |
285 | 285 | ||
286 | if (avail) { | 286 | if (avail) { |
287 | rs_trace("emit slack delta for %.0f available bytes", (double) avail); | 287 | rs_trace("emit slack delta for %.0f available bytes", (double) avail); |
288 | rs_emit_literal_cmd(job, avail); | 288 | rs_emit_literal_cmd(job, avail); |
289 | rs_tube_copy(job, avail); | 289 | rs_tube_copy(job, avail); |
290 | return RS_RUNNING; | 290 | return RS_RUNNING; |
291 | } else { | 291 | } else { |
292 | if (rs_job_input_is_ending(job)) { | 292 | if (rs_job_input_is_ending(job)) { |
293 | job->statefn = rs_delta_s_end; | 293 | job->statefn = rs_delta_s_end; |
294 | return RS_RUNNING; | 294 | return RS_RUNNING; |
295 | } else { | 295 | } else { |
296 | return RS_BLOCKED; | 296 | return RS_BLOCKED; |
297 | } | 297 | } |
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | 301 | ||
302 | /** | 302 | /** |
303 | * State function for writing out the header of the encoding job. | 303 | * State function for writing out the header of the encoding job. |
304 | */ | 304 | */ |
305 | static rs_result rs_delta_s_header(rs_job_t *job) | 305 | static rs_result rs_delta_s_header(rs_job_t *job) |
306 | { | 306 | { |
307 | rs_emit_delta_header(job); | 307 | rs_emit_delta_header(job); |
308 | 308 | ||
309 | if (job->block_len) { | 309 | if (job->block_len) { |
310 | if (!job->signature) { | 310 | if (!job->signature) { |
311 | rs_error("no signature is loaded into the job"); | 311 | rs_error("no signature is loaded into the job"); |
312 | return RS_PARAM_ERROR; | 312 | return RS_PARAM_ERROR; |
313 | } | 313 | } |
314 | job->statefn = rs_delta_s_scan; | 314 | job->statefn = rs_delta_s_scan; |
315 | } else { | 315 | } else { |
316 | rs_trace("block length is zero for this delta; " | 316 | rs_trace("block length is zero for this delta; " |
317 | "therefore using slack deltas"); | 317 | "therefore using slack deltas"); |
318 | job->statefn = rs_delta_s_slack; | 318 | job->statefn = rs_delta_s_slack; |
319 | } | 319 | } |
320 | 320 | ||
321 | return RS_RUNNING; | 321 | return RS_RUNNING; |
322 | } | 322 | } |
323 | 323 | ||
324 | 324 | ||
325 | /** | 325 | /** |
326 | * Prepare to compute a streaming delta. | 326 | * Prepare to compute a streaming delta. |
327 | */ | 327 | */ |
328 | rs_job_t *rs_delta_begin(rs_signature_t *sig) | 328 | rs_job_t *rs_delta_begin(rs_signature_t *sig) |
329 | { | 329 | { |
330 | rs_job_t *job; | 330 | rs_job_t *job; |
331 | 331 | ||
332 | job = rs_job_new("delta", rs_delta_s_header); | 332 | job = rs_job_new("delta", rs_delta_s_header); |
333 | job->signature = sig; | 333 | job->signature = sig; |
334 | 334 | ||
335 | if ((job->block_len = sig->block_len) < 0) { | 335 | if ((job->block_len = sig->block_len) < 0) { |
336 | rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature", | 336 | rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature", |
337 | job->block_len); | 337 | job->block_len); |
338 | rs_job_free(job); | ||
338 | return NULL; | 339 | return NULL; |
339 | } | 340 | } |
340 | 341 | ||
341 | job->strong_sum_len = sig->strong_sum_len; | 342 | job->strong_sum_len = sig->strong_sum_len; |
342 | if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) { | 343 | if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) { |
343 | rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature", | 344 | rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature", |
344 | job->strong_sum_len); | 345 | job->strong_sum_len); |
346 | rs_job_free(job); | ||
345 | return NULL; | 347 | return NULL; |
346 | } | 348 | } |
347 | 349 | ||
348 | return job; | 350 | return job; |
349 | } | 351 | } |
350 | 352 | ||
351 | 353 | ||