summaryrefslogtreecommitdiff
authorerik <erik>2007-01-24 19:46:19 (UTC)
committer erik <erik>2007-01-24 19:46:19 (UTC)
commita017bf21dd89159052f2f7a3fbc043a24956c08c (patch) (unidiff)
tree008be2b62ee5487dc55b8a7c7f043c94268f8362
parenta4a7bd22feb060a80e20c81cded43cc24f5cd423 (diff)
downloadopie-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.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3.c2
-rw-r--r--libopie2/opieui/oimageeffect.cpp5
-rw-r--r--library/global.cpp30
-rw-r--r--noncore/apps/opie-reader/Bkmks.cpp1
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp4
-rw-r--r--noncore/apps/zsafe/zsafe.cpp57
-rw-r--r--noncore/comm/keypebble/vncauth.c6
-rw-r--r--noncore/net/ftplib/ftplib.c4
-rw-r--r--noncore/todayplugins/stockticker/libstocks/csv.c140
-rw-r--r--noncore/todayplugins/stockticker/libstocks/currency.c1
-rw-r--r--noncore/todayplugins/stockticker/libstocks/lists.h1
-rw-r--r--noncore/todayplugins/stockticker/libstocks/stocks.c189
-rw-r--r--rsync/delta.c2
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
9mpeg3_t* mpeg3_new(char *path) 9mpeg3_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
20int mpeg3_delete(mpeg3_t *file) 20int 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
35int mpeg3_check_sig(char *path) 35int 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
89mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) 89mpeg3_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
230mpeg3_t* mpeg3_open(char *path) 230mpeg3_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
235int mpeg3_close(mpeg3_t *file) 235int 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
242int mpeg3_set_cpus(mpeg3_t *file, int cpus) 242int 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
251int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) 251int 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
260int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) 260int 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
287int mpeg3_read_toc(mpeg3_t *file) 287int 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
303int mpeg3_has_audio(mpeg3_t *file) 303int mpeg3_has_audio(mpeg3_t *file)
304{ 304{
305 return file->has_audio; 305 return file->has_audio;
306} 306}
307 307
308int mpeg3_total_astreams(mpeg3_t *file) 308int mpeg3_total_astreams(mpeg3_t *file)
309{ 309{
310 return file->total_astreams; 310 return file->total_astreams;
311} 311}
312 312
313int mpeg3_audio_channels(mpeg3_t *file, 313int 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
321int mpeg3_sample_rate(mpeg3_t *file, 321int 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
329long mpeg3_get_sample(mpeg3_t *file, 329long 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
337int mpeg3_set_sample(mpeg3_t *file, 337int 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
350long mpeg3_audio_samples(mpeg3_t *file, 350long 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
358int mpeg3_has_video(mpeg3_t *file) 358int mpeg3_has_video(mpeg3_t *file)
359{ 359{
360 return file->has_video; 360 return file->has_video;
361} 361}
362 362
363int mpeg3_total_vstreams(mpeg3_t *file) 363int mpeg3_total_vstreams(mpeg3_t *file)
364{ 364{
365 return file->total_vstreams; 365 return file->total_vstreams;
366} 366}
367 367
368int mpeg3_video_width(mpeg3_t *file, 368int 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
376int mpeg3_video_height(mpeg3_t *file, 376int 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
384float mpeg3_frame_rate(mpeg3_t *file, 384float 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
392long mpeg3_video_frames(mpeg3_t *file, 392long 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
400long mpeg3_get_frame(mpeg3_t *file, 400long 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
408int mpeg3_set_frame(mpeg3_t *file, 408int 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
421int mpeg3_seek_percentage(mpeg3_t *file, double percentage) 421int 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
1734int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) 1734int 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
1764bool OImageEffect::blend( 1764bool 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...
1821bool OImageEffect::blend( 1821bool 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
1834bool OImageEffect::blend( 1834bool 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
1898bool OImageEffect::blendOnLower( 1898bool 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
1969QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) 1969QImage& 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
1981void OImageEffect::normalize(QImage &img) 1981void 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
2097void OImageEffect::equalize(QImage &img) 2100void 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
2182QImage OImageEffect::sample(QImage &src, int w, int h) 2185QImage 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
2275void OImageEffect::threshold(QImage &img, unsigned int threshold) 2278void 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
2291QImage OImageEffect::charcoal(QImage &src, double factor) 2294QImage 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
2303void OImageEffect::hull(const int x_offset, const int y_offset, 2306void 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
2383QImage OImageEffect::despeckle(QImage &src) 2386QImage 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*/
206Global::Global() 206Global::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*/
216const QDawg& Global::fixedDawg() 216const 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*/
262const QDawg& Global::addedDawg() 262const 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*/
273const QDawg& Global::dawg(const QString& name) 273const 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*/
298void Global::addWords(const QStringList& wordlist) 298void 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*/
311void Global::addWords(const QString& dictname, const QStringList& wordlist) 311void 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*/
337QString Global::applicationFileName(const QString& appname, const QString& filename) 337QString 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*/
356void Global::createDocDir() 356void 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*/
369void Global::statusMessage(const QString& message) 369void 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*/
380void Global::applyStyle() 380void 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*/
392QWidget *Global::shutdown( bool ) 392QWidget *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*/
403QWidget *Global::restart( bool ) 403QWidget *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*/
421void Global::showInputMethod() 421void 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*/
436void Global::hideInputMethod() 436void 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*/
447bool Global::isBuiltinCommand( const QString &name ) 447bool 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
459Global::Command* Global::builtin=0; 459Global::Command* Global::builtin=0;
460QGuardedPtr<QWidget> *Global::running=0; 460QGuardedPtr<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*/
471void Global::setBuiltinCommands( Command* list ) 471void 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*/
489void Global::setDocument( QWidget* receiver, const QString& document ) 489void 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*/
497bool Global::terminateBuiltin( const QString& n ) 497bool 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*/
513void Global::terminate( const AppLnk* app ) 513void 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*/
532void Global::invoke(const QString &c) 532void 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*/
661void Global::execute( const QString &c, const QString& document ) 665void 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*/
682QString Global::shellQuote(const QString& s) 686QString 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*/
703QString Global::stringQuote(const QString& s) 707QString 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*/
723void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) 727void 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
776QStringList Global::languageList() 780QStringList 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
790QStringList Global::helpPath() 794QStringList 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 */
816bool Global::truncateFile(QFile &f, int size){ 820bool 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*/
835QString Global::tempDir() 839QString 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
11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); 11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE);
12 12
13Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : 13Bkmk::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
23Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) 23Bkmk::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
28Bkmk::Bkmk(const Bkmk& rhs) : 28Bkmk::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
39Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) 39Bkmk::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
52Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) 52Bkmk::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
67void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) 67void 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
96Bkmk::~Bkmk() 96Bkmk::~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
104Bkmk& Bkmk::operator=(const Bkmk& rhs) 104Bkmk& 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
141bool Bkmk::operator==(const Bkmk& rhs) 141bool 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
146void Bkmk::setAnno(unsigned char* t, unsigned short len) 146void 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
167void Bkmk::setAnno(tchar* t) 167void 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
189BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) 189BkmkFile::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
203BkmkFile::~BkmkFile() 203BkmkFile::~BkmkFile()
204{ 204{
205 if (f != NULL) fclose(f); 205 if (f != NULL) fclose(f);
206} 206}
207 207
208void BkmkFile::write(const Bkmk& b) 208void 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
228void BkmkFile::write(CList<Bkmk>& bl) 228void 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
240CList<Bkmk>* BkmkFile::readall() 240CList<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
290CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) 290CList<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
303Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) 303Bkmk* 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
328Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) 328Bkmk* 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
351Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) 352Bkmk* 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
379Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) 380Bkmk* 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
39static xfrecord formatter[] = { 39static 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
78int ExcelBook::Integer2Byte(int b1, int b2) 78int 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
86int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) 86int 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
94int ExcelBook::Integer2ByteFile(FILE *f) 94int 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
102float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) 102float 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
116double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) 116double 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
159void ExcelBook::DetectEndian(void) 159void 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
177double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) 177double 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
201bool ExcelBook::OpenFile(char *Filename) 201bool 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
215bool ExcelBook::CloseFile(void) 215bool 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
244void ExcelBook::SeekPosition(int pos) 244void 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
254void ExcelBook::SeekSkip(int pos) 254void 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
264int ExcelBook::FileEOF(void) 264int 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
270int ExcelBook::Get2Bytes(void) 270int 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
287char* ExcelBook::Read(int pos, int length) 287char* 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
301QString ExcelBook::ReadUnicodeChar(int pos, int length) 301QString 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
318QString* ExcelBook::GetString(int num) 318QString* 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
327int ExcelBook::SeekBOF(void) 327int 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
353ExcelBREC* ExcelBook::GetBREC(void) 353ExcelBREC* 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
366ExcelBREC* ExcelBook::PeekBREC(void) 366ExcelBREC* 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
376char* ExcelBook::GetDataOfBREC(ExcelBREC* record) 376char* 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
385void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) 387void 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
393bool ExcelSheet::InitCells() 395bool 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
405void ExcelSheet::Set(int row, int col, ExcelCell* cell) 407void 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
413ExcelCell* ExcelSheet::Get(int row, int col) 415ExcelCell* 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
421int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) 423int 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
489int ExcelBook::ReadSheet(ExcelSheet* sheet) 491int 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
505ExcelSheet* ExcelBook::GetSheet(void) 507ExcelSheet* 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
525void ExcelBook::ParseSheets(void) 527void 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
574void ExcelBook::GetSheets(void) 576void 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
588bool ExcelBook::ParseBook(char *file) 590bool 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
600QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) 602QString 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
611QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) 613QString 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
626void ExcelBook::HandleBoundSheet(ExcelBREC* rec) 628void 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
652void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) 654void 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
666ExcelFormat* ExcelBook::GetFormatting(int xf) 668ExcelFormat* 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
682void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) 684void 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
743char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) 745char* 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
1497void ZSafe::resume(int) 1497void 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
1535bool ZSafe::openDocument(const char* _filename, const char* ) 1535bool 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
1759int ZSafe::loadInit(const char* _filename, const char *password) 1759int 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
1840int ZSafe::loadEntry(char *entry[FIELD_SIZE]) 1846int 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
1868int ZSafe::loadFinalize(void) 1874int 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
1875bool ZSafe::saveDocument(const char* _filename, 1881bool 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
2052PasswordForm *newPwdDialog; 2058PasswordForm *newPwdDialog;
2053bool newPwdDialogResult = false; 2059bool newPwdDialogResult = false;
2054void ZSafe::setPasswordDialogDone() 2060void ZSafe::setPasswordDialogDone()
2055{ 2061{
2056 newPwdDialogResult = true; 2062 newPwdDialogResult = true;
2057 newPwdDialog->close(); 2063 newPwdDialog->close();
2058} 2064}
2059 2065
2060void ZSafe::getDocPassword(QString title) 2066void 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
2093int ZSafe::saveInit(const char *_filename, const char *password) 2099int 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
2146int ZSafe::saveEntry(char *entry[FIELD_SIZE]) 2140int 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
2202int ZSafe::saveFinalize(void) 2202int 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
2234void ZSafe::quitMe () 2235void 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
2268void ZSafe::categoryFieldActivated( const QString& category) 2269void 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
2274void ZSafe::addCategory() 2275void 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
2434void ZSafe::delCategory() 2435void 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
2477void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) 2478void 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
2542void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) 2543void 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
2595void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) 2596void 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
2612void ZSafe::editCategory() 2613void 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
40unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; 40unsigned 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
48int 48int
49vncEncryptAndStorePasswd(char *passwd, char *fname) 49vncEncryptAndStorePasswd(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
90char * 90char *
91vncDecryptPasswdFromFile(char *fname) 91vncDecryptPasswdFromFile(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
122void 126void
123vncRandomBytes(unsigned char *bytes) 127vncRandomBytes(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
139void 143void
140vncEncryptBytes(unsigned char *bytes, char *passwd) 144vncEncryptBytes(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 */
848GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, 848GLOBALDEF 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 */
919GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) 919GLOBALDEF 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 */
952GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) 952GLOBALDEF 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 */
983GLOBALDEF int FtpClose(netbuf *nData) 983GLOBALDEF 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 */
1023GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) 1023GLOBALDEF 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 */
1044GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) 1044GLOBALDEF 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 */
1063GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) 1063GLOBALDEF 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 */
1080GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) 1080GLOBALDEF 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 */
1097GLOBALDEF int FtpCDUp(netbuf *nControl) 1097GLOBALDEF 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 */
1109GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) 1109GLOBALDEF 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 */
1126GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) 1126GLOBALDEF 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 */
1148static int FtpXfer(const char *localfile, const char *path, 1148static 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 */
1210GLOBALDEF int FtpNlst(const char *outputfile, const char *path, 1214GLOBALDEF 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 */
1221GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) 1225GLOBALDEF 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 */
1231GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) 1235GLOBALDEF 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 */
1259GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) 1263GLOBALDEF 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 */
1279GLOBALDEF int FtpGet(const char *outputfile, const char *path, 1283GLOBALDEF 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 */
1290GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, 1294GLOBALDEF 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 */
1301GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) 1305GLOBALDEF 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 */
1322GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) 1326GLOBALDEF 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 */
1339GLOBALDEF void FtpQuit(netbuf *nControl) 1343GLOBALDEF 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
40const char *months[12]= 40const 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/*****************************************************************************/
61char *csv_strtok(char *s, char *delim) 61char *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/*****************************************************************************/
94stock *parse_csv_file(char *csv) 94stock *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/*****************************************************************************/
290stock *parse_csv_history_file(char *csv_file) 334stock *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/*****************************************************************************/
35libstocks_return_code get_currency_exchange(char *from, 35libstocks_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
32PUBEXT_LISTS stock *malloc_stock(void); 32PUBEXT_LISTS stock *malloc_stock(void);
33PUBEXT_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/*
38s = symbol 38s = symbol
39n = name 39n = name
40l1 = last trade 40l1 = last trade
41d1 = date 41d1 = date
42t1 = time 42t1 = time
43c1 = variation 43c1 = variation
44o = open 44o = open
45h = higher price 45h = higher price
46g = lower price 46g = lower price
47v = volume 47v = volume
48*/ 48*/
49 49
50const char yahoo_us_stocks_server[]="finance.yahoo.com"; 50const char yahoo_us_stocks_server[]="finance.yahoo.com";
51const char yahoo_eu_stocks_server[]="finance.yahoo.com"; 51const 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
54const char yahoo_url_beg[]="/d/quotes.csv?s="; 54const char yahoo_url_beg[]="/d/quotes.csv?s=";
55const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; 55const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv";
56 56
57typedef enum { 57typedef 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
63const char *yahoo_us_ext[YAHOO_US_EXT_NB] = 63const 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/*****************************************************************************/
83yahoo_source find_yahoo_source(char *symbol) 83yahoo_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/*****************************************************************************/
119libstocks_return_code download_stocks(char *stocks, 119libstocks_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/*****************************************************************************/
191libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) 191libstocks_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 */
86int rs_roll_paranoia = 0; 86int rs_roll_paranoia = 0;
87 87
88 88
89static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); 89static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *);
90 90
91static rs_result rs_delta_s_deferred_copy(rs_job_t *job); 91static rs_result rs_delta_s_deferred_copy(rs_job_t *job);
92 92
93 93
94 94
95static rs_result rs_delta_s_end(rs_job_t *job) 95static 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 */
108static rs_result 108static rs_result
109rs_delta_s_scan(rs_job_t *job) 109rs_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 */
159static rs_result 159static rs_result
160rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) 160rs_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
261static rs_result rs_delta_s_deferred_copy(rs_job_t *job) 261static 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 */
281static rs_result rs_delta_s_slack(rs_job_t *job) 281static 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 */
305static rs_result rs_delta_s_header(rs_job_t *job) 305static 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 */
328rs_job_t *rs_delta_begin(rs_signature_t *sig) 328rs_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