author | erik <erik> | 2007-01-24 19:46:19 (UTC) |
---|---|---|
committer | erik <erik> | 2007-01-24 19:46:19 (UTC) |
commit | a017bf21dd89159052f2f7a3fbc043a24956c08c (patch) (side-by-side diff) | |
tree | 008be2b62ee5487dc55b8a7c7f043c94268f8362 | |
parent | a4a7bd22feb060a80e20c81cded43cc24f5cd423 (diff) | |
download | opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.zip opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.tar.gz opie-a017bf21dd89159052f2f7a3fbc043a24956c08c.tar.bz2 |
Every file in this commit has a memory leak of some kind or another. I think
all of them are minor and should not effect properly running code. But if I
were you I would give libstocks and the stockticker plugin in Today a wide
berth. That library is atrocious.
-rw-r--r-- | core/multimedia/opieplayer/libmpeg3/libmpeg3.c | 2 | ||||
-rw-r--r-- | libopie2/opieui/oimageeffect.cpp | 5 | ||||
-rw-r--r-- | library/global.cpp | 6 | ||||
-rw-r--r-- | noncore/apps/opie-reader/Bkmks.cpp | 1 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/Excel.cpp | 4 | ||||
-rw-r--r-- | noncore/apps/zsafe/zsafe.cpp | 45 | ||||
-rw-r--r-- | noncore/comm/keypebble/vncauth.c | 6 | ||||
-rw-r--r-- | noncore/net/ftplib/ftplib.c | 4 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/csv.c | 106 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/currency.c | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/lists.h | 1 | ||||
-rw-r--r-- | noncore/todayplugins/stockticker/libstocks/stocks.c | 23 | ||||
-rw-r--r-- | rsync/delta.c | 2 |
13 files changed, 152 insertions, 54 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 @@ #include "libmpeg3.h" #include "mpeg3protos.h" #include <stdlib.h> #include <string.h> #define MAX(a, b) ((a) > (b) ? (a) : (b)) mpeg3_t* mpeg3_new(char *path) { int i; mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t)); file->cpus = 1; file->fs = mpeg3_new_fs(path); file->have_mmx = mpeg3_mmx_test(); file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); return file; } int mpeg3_delete(mpeg3_t *file) { int i; for(i = 0; i < file->total_vstreams; i++) mpeg3_delete_vtrack(file, file->vtrack[i]); for(i = 0; i < file->total_astreams; i++) mpeg3_delete_atrack(file, file->atrack[i]); mpeg3_delete_fs(file->fs); mpeg3_delete_demuxer(file->demuxer); free(file); } int mpeg3_check_sig(char *path) { mpeg3_fs_t *fs; unsigned int bits; char *ext; int result = 0; fs = mpeg3_new_fs(path); if(mpeg3io_open_file(fs)) { /* File not found */ - return 0; + return mpeg3_delete_fs(fs); } bits = mpeg3io_read_int32(fs); /* Test header */ if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) { result = 1; } else if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || (bits == MPEG3_PACK_START_CODE) || ((bits & 0xfff00000) == 0xfff00000) || (bits == MPEG3_SEQUENCE_START_CODE) || (bits == MPEG3_PICTURE_START_CODE) || (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || ((bits >> 8) == MPEG3_ID3_PREFIX) || (bits == MPEG3_RIFF_CODE)) { result = 1; ext = strrchr(path, '.'); if(ext) { /* Test file extension. */ if(strncasecmp(ext, ".mp2", 4) && // strncasecmp(ext, ".mp3", 4) && strncasecmp(ext, ".m1v", 4) && strncasecmp(ext, ".m2v", 4) && strncasecmp(ext, ".m2s", 4) && strncasecmp(ext, ".mpg", 4) && strncasecmp(ext, ".vob", 4) && strncasecmp(ext, ".mpeg", 4) && strncasecmp(ext, ".ac3", 4)) result = 0; } } mpeg3io_close_file(fs); mpeg3_delete_fs(fs); return result; } mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file) { mpeg3_t *file = 0; unsigned int bits; int i, done; /* Initialize the file structure */ file = mpeg3_new(path); /* Need to perform authentication before reading a single byte. */ if(mpeg3io_open_file(file->fs)) { mpeg3_delete(file); return 0; } /* =============================== Create the title objects ========================= */ bits = mpeg3io_read_int32(file->fs); if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */ { /* Table of contents for another file */ if(mpeg3_read_toc(file)) { mpeg3_delete(file); return 0; } mpeg3io_close_file(file->fs); } else if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) { /* Transport stream */ file->packet_size = MPEG3_TS_PACKET_SIZE; file->is_transport_stream = 1; } else if(bits == MPEG3_PACK_START_CODE) { /* Program stream */ file->packet_size = MPEG3_DVD_PACKET_SIZE; file->is_program_stream = 1; } else if((bits & 0xfff00000) == 0xfff00000 || ((bits >> 8) == MPEG3_ID3_PREFIX) || (bits == MPEG3_RIFF_CODE)) { /* MPEG Audio only */ file->packet_size = MPEG3_DVD_PACKET_SIZE; file->has_audio = 1; file->is_audio_stream = 1; } else if(bits == MPEG3_SEQUENCE_START_CODE || bits == MPEG3_PICTURE_START_CODE) { /* Video only */ file->packet_size = MPEG3_DVD_PACKET_SIZE; file->is_video_stream = 1; } else if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) { /* AC3 Audio only */ file->packet_size = MPEG3_DVD_PACKET_SIZE; file->has_audio = 1; file->is_audio_stream = 1; } else { /* file->packet_size = MPEG3_DVD_PACKET_SIZE; */ /* file->is_audio_stream = 1; */ mpeg3_delete(file); fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n"); return 0; } /* Create title */ /* Copy timecodes from an old demuxer */ if(old_file && mpeg3_get_demuxer(old_file)) { mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file)); } else /* Start from scratch */ if(!file->demuxer->total_titles) { mpeg3demux_create_title(file->demuxer, 0, 0); } /* =============================== Get title information ========================= */ if(file->is_transport_stream || file->is_program_stream) { /* Create video tracks */ /* Video must be created before audio because audio uses the video timecode */ /* to get its length. */ for(i = 0; i < MPEG3_MAX_STREAMS; i++) { if(file->demuxer->vstream_table[i]) { file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer); if(file->vtrack[file->total_vstreams]) file->total_vstreams++; } } /* Create audio tracks */ for(i = 0; i < MPEG3_MAX_STREAMS; i++) { if(file->demuxer->astream_table[i]) { file->atrack[file->total_astreams] = mpeg3_new_atrack(file, i, file->demuxer->astream_table[i], file->demuxer); if(file->atrack[file->total_astreams]) file->total_astreams++; } } } else if(file->is_video_stream) { /* Create video tracks */ file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer); if(file->vtrack[0]) file->total_vstreams++; } else if(file->is_audio_stream) { /* Create audio tracks */ file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer); if(file->atrack[0]) file->total_astreams++; } if(file->total_vstreams) file->has_video = 1; if(file->total_astreams) file->has_audio = 1; mpeg3io_close_file(file->fs); return file; } mpeg3_t* mpeg3_open(char *path) { return mpeg3_open_copy(path, 0); } int mpeg3_close(mpeg3_t *file) { /* File is closed in the same procedure it is opened in. */ mpeg3_delete(file); return 0; } int mpeg3_set_cpus(mpeg3_t *file, int cpus) { int i; file->cpus = cpus; for(i = 0; i < file->total_vstreams; i++) mpeg3video_set_cpus(file->vtrack[i]->video, cpus); return 0; } int mpeg3_set_mmx(mpeg3_t *file, int use_mmx) { int i; file->have_mmx = use_mmx; for(i = 0; i < file->total_vstreams; i++) mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx); return 0; } int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams) { mpeg3_t *file = mpeg3_open(path); mpeg3_demuxer_t *demuxer; int i; if(file) { fprintf(output, "TOCVERSION 2\n" "PATH: %s\n", path); demuxer = mpeg3_new_demuxer(file, 0, 0, -1); mpeg3demux_create_title(demuxer, timecode_search, output); /* Just print the first title's streams */ if(print_streams) mpeg3demux_print_streams(demuxer, output); fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes); fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size); mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output); mpeg3_delete_demuxer(demuxer); mpeg3_close(file); return 0; } return 1; } int mpeg3_read_toc(mpeg3_t *file) { char string[MPEG3_STRLEN]; int number1; /* Test version number */ file->is_program_stream = 1; mpeg3io_seek(file->fs, 0); fscanf(file->fs->fd, "%s %d", string, &number1); if(number1 > 2 || number1 < 2) return 1; /* Read titles */ mpeg3demux_read_titles(file->demuxer); return 0; } int mpeg3_has_audio(mpeg3_t *file) { return file->has_audio; } int mpeg3_total_astreams(mpeg3_t *file) { return file->total_astreams; } int mpeg3_audio_channels(mpeg3_t *file, int stream) { if(file->has_audio) return file->atrack[stream]->channels; return -1; } int mpeg3_sample_rate(mpeg3_t *file, int stream) { if(file->has_audio) return file->atrack[stream]->sample_rate; return -1; } long mpeg3_get_sample(mpeg3_t *file, int stream) { if(file->has_audio) return file->atrack[stream]->current_position; return -1; } int mpeg3_set_sample(mpeg3_t *file, long sample, int stream) { if(file->has_audio) { file->atrack[stream]->current_position = sample; mpeg3audio_seek_sample(file->atrack[stream]->audio, sample); return 0; } return -1; } long mpeg3_audio_samples(mpeg3_t *file, int stream) { if(file->has_audio) return file->atrack[stream]->total_samples; return -1; } int mpeg3_has_video(mpeg3_t *file) { return file->has_video; } int mpeg3_total_vstreams(mpeg3_t *file) { return file->total_vstreams; } int mpeg3_video_width(mpeg3_t *file, int stream) { if(file->has_video) return file->vtrack[stream]->width; return -1; } int mpeg3_video_height(mpeg3_t *file, int stream) { if(file->has_video) return file->vtrack[stream]->height; return -1; } float mpeg3_frame_rate(mpeg3_t *file, int stream) { if(file->has_video) return file->vtrack[stream]->frame_rate; return -1; } long mpeg3_video_frames(mpeg3_t *file, int stream) { if(file->has_video) return file->vtrack[stream]->total_frames; return -1; } long mpeg3_get_frame(mpeg3_t *file, int stream) { if(file->has_video) return file->vtrack[stream]->current_position; return -1; } int mpeg3_set_frame(mpeg3_t *file, long frame, int stream) { if(file->has_video) { file->vtrack[stream]->current_position = frame; mpeg3video_seek_frame(file->vtrack[stream]->video, frame); return 0; } return -1; } int mpeg3_seek_percentage(mpeg3_t *file, double percentage) { int i; for(i = 0; i < file->total_astreams; i++) { mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage); } for(i = 0; i < file->total_vstreams; i++) { 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,771 +1670,774 @@ QImage& OImageEffect::dither(QImage &img, const QColor *palette, int size) int *berr2 = berr1 + img.width(); for ( int j = 0; j < img.height(); j++ ) { uint *ip = (uint * )img.scanLine( j ); uchar *dp = dImage.scanLine( j ); for ( i = 0; i < img.width(); i++ ) { rerr1[i] = rerr2[i] + qRed( *ip ); rerr2[i] = 0; gerr1[i] = gerr2[i] + qGreen( *ip ); gerr2[i] = 0; berr1[i] = berr2[i] + qBlue( *ip ); berr2[i] = 0; ip++; } *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); for ( i = 1; i < img.width()-1; i++ ) { int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); *dp = indx; int rerr = rerr1[i]; rerr -= palette[indx].red(); int gerr = gerr1[i]; gerr -= palette[indx].green(); int berr = berr1[i]; berr -= palette[indx].blue(); // diffuse red error rerr1[ i+1 ] += ( rerr * 7 ) >> 4; rerr2[ i-1 ] += ( rerr * 3 ) >> 4; rerr2[ i ] += ( rerr * 5 ) >> 4; rerr2[ i+1 ] += ( rerr ) >> 4; // diffuse green error gerr1[ i+1 ] += ( gerr * 7 ) >> 4; gerr2[ i-1 ] += ( gerr * 3 ) >> 4; gerr2[ i ] += ( gerr * 5 ) >> 4; gerr2[ i+1 ] += ( gerr ) >> 4; // diffuse red error berr1[ i+1 ] += ( berr * 7 ) >> 4; berr2[ i-1 ] += ( berr * 3 ) >> 4; berr2[ i ] += ( berr * 5 ) >> 4; berr2[ i+1 ] += ( berr ) >> 4; dp++; } *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); } delete [] rerr1; delete [] gerr1; delete [] berr1; img = dImage; return img; } int OImageEffect::nearestColor( int r, int g, int b, const QColor *palette, int size ) { if (palette == 0) return 0; int dr = palette[0].red() - r; int dg = palette[0].green() - g; int db = palette[0].blue() - b; int minDist = dr*dr + dg*dg + db*db; int nearest = 0; for (int i = 1; i < size; i++ ) { dr = palette[i].red() - r; dg = palette[i].green() - g; db = palette[i].blue() - b; int dist = dr*dr + dg*dg + db*db; if ( dist < minDist ) { minDist = dist; nearest = i; } } return nearest; } bool OImageEffect::blend( const QImage & upper, const QImage & lower, QImage & output ) { if ( upper.width() > lower.width() || upper.height() > lower.height() || upper.depth() != 32 || lower.depth() != 32 ) { odebug << "OImageEffect::blend : Sizes not correct" << oendl; return false; } output = lower.copy(); register uchar *i, *o; register int a; register int col; register int w = upper.width(); int row(upper.height() - 1); do { i = upper.scanLine(row); o = output.scanLine(row); col = w << 2; --col; do { while (!(a = i[col]) && (col != 3)) { --col; --col; --col; --col; } --col; o[col] += ((i[col] - o[col]) * a) >> 8; --col; o[col] += ((i[col] - o[col]) * a) >> 8; --col; o[col] += ((i[col] - o[col]) * a) >> 8; } while (col--); } while (row--); return true; } #if 0 // Not yet... bool OImageEffect::blend( const QImage & upper, const QImage & lower, QImage & output, const QRect & destRect ) { output = lower.copy(); return output; } #endif bool OImageEffect::blend( int &x, int &y, const QImage & upper, const QImage & lower, QImage & output ) { int cx=0, cy=0, cw=upper.width(), ch=upper.height(); if ( upper.width() + x > lower.width() || upper.height() + y > lower.height() || x < 0 || y < 0 || upper.depth() != 32 || lower.depth() != 32 ) { if ( x > lower.width() || y > lower.height() ) return false; if ( upper.width()<=0 || upper.height() <= 0 ) return false; if ( lower.width()<=0 || lower.height() <= 0 ) return false; if (x<0) {cx=-x; cw+=x; x=0; }; if (cw + x > lower.width()) { cw=lower.width()-x; }; if (y<0) {cy=-y; ch+=y; y=0; }; if (ch + y > lower.height()) { ch=lower.height()-y; }; if ( cx >= upper.width() || cy >= upper.height() ) return true; if ( cw <= 0 || ch <= 0 ) return true; } output.create(cw,ch,32); // output.setAlphaBuffer(true); // I should do some benchmarks to see if // this is worth the effort register QRgb *i, *o, *b; register int a; register int j,k; for (j=0; j<ch; j++) { b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); k=cw-1; --b; --i; --o; do { while ( !(a=qAlpha(*i)) && k>0 ) { i--; // *o=0; *o=*b; --o; --b; k--; }; // *o=0xFF; *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); --i; --o; --b; } while (k--); } return true; } bool OImageEffect::blendOnLower( int x, int y, const QImage & upper, const QImage & lower ) { int cx=0, cy=0, cw=upper.width(), ch=upper.height(); if ( upper.depth() != 32 || lower.depth() != 32 ) return false; if ( x + cw > lower.width() || y + ch > lower.height() || x < 0 || y < 0 ) { if ( x > lower.width() || y > lower.height() ) return true; if ( upper.width()<=0 || upper.height() <= 0 ) return true; if ( lower.width()<=0 || lower.height() <= 0 ) return true; if (x<0) {cx=-x; cw+=x; x=0; }; if (cw + x > lower.width()) { cw=lower.width()-x; }; if (y<0) {cy=-y; ch+=y; y=0; }; if (ch + y > lower.height()) { ch=lower.height()-y; }; if ( cx >= upper.width() || cy >= upper.height() ) return true; if ( cw <= 0 || ch <= 0 ) return true; } register uchar *i, *b; register int a; register int k; for (int j=0; j<ch; j++) { b=&lower.scanLine(y+j) [ (x+cw) << 2 ]; i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ]; k=cw-1; --b; --i; do { #ifndef WORDS_BIGENDIAN while ( !(a=*i) && k>0 ) #else while ( !(a=*(i-3)) && k>0 ) #endif { i-=4; b-=4; k--; }; #ifndef WORDS_BIGENDIAN --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; #else *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); i -= 2; b -= 2; #endif } while (k--); } return true; } // For selected icons QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) { return blend( col, img, 0.5); } // // =================================================================== // Effects originally ported from ImageMagick for PixiePlus, plus a few // new ones. (mosfet 12/29/01) // =================================================================== // void OImageEffect::normalize(QImage &img) { int *histogram, threshold_intensity, intense; int x, y, i; unsigned int gray_value; unsigned int *normalize_map; unsigned int high, low; // allocate histogram and normalize map histogram = (int *)calloc(MaxRGB+1, sizeof(int)); normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int)); if(!normalize_map || !histogram){ owarn << "Unable to allocate normalize histogram and map" << oendl; free(normalize_map); free(histogram); return; } // form histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ gray_value = intensityValue(data[x]); histogram[gray_value]++; } } } else{ // PsudeoClass unsigned char *data; unsigned int *cTable = img.colorTable(); for(y=0; y < img.height(); ++y){ data = (unsigned char *)img.scanLine(y); for(x=0; x < img.width(); ++x){ gray_value = intensityValue(*(cTable+data[x])); histogram[gray_value]++; } } } // find histogram boundaries by locating the 1 percent levels threshold_intensity = (img.width()*img.height())/100; intense = 0; for(low=0; low < MaxRGB; ++low){ intense+=histogram[low]; if(intense > threshold_intensity) break; } intense=0; for(high=MaxRGB; high != 0; --high){ intense+=histogram[high]; if(intense > threshold_intensity) break; } if (low == high){ // Unreasonable contrast; use zero threshold to determine boundaries. threshold_intensity=0; intense=0; for(low=0; low < MaxRGB; ++low){ intense+=histogram[low]; if(intense > threshold_intensity) break; } intense=0; for(high=MaxRGB; high != 0; --high) { intense+=histogram[high]; if(intense > threshold_intensity) break; } - if(low == high) + if(low == high) { + free(histogram); + free(normalize_map); return; // zero span bound } + } // Stretch the histogram to create the normalized image mapping. for(i=0; i <= MaxRGB; i++){ if (i < (int) low) normalize_map[i]=0; else{ if(i > (int) high) normalize_map[i]=MaxRGB; else normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low); } } // Normalize if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ data[x] = qRgba(normalize_map[qRed(data[x])], normalize_map[qGreen(data[x])], normalize_map[qBlue(data[x])], qAlpha(data[x])); } } } else{ // PsudeoClass int colors = img.numColors(); unsigned int *cTable = img.colorTable(); for(i=0; i < colors; ++i){ cTable[i] = qRgba(normalize_map[qRed(cTable[i])], normalize_map[qGreen(cTable[i])], normalize_map[qBlue(cTable[i])], qAlpha(cTable[i])); } } free(histogram); free(normalize_map); } void OImageEffect::equalize(QImage &img) { int *histogram, *map, *equalize_map; int x, y, i, j; unsigned int high, low; // allocate histogram and maps histogram = (int *)calloc(MaxRGB+1, sizeof(int)); map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); if(!histogram || !map || !equalize_map){ owarn << "Unable to allocate equalize histogram and maps" << oendl; free(histogram); free(map); free(equalize_map); return; } // form histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ histogram[intensityValue(data[x])]++; } } } else{ // PsudeoClass unsigned char *data; unsigned int *cTable = img.colorTable(); for(y=0; y < img.height(); ++y){ data = (unsigned char *)img.scanLine(y); for(x=0; x < img.width(); ++x){ histogram[intensityValue(*(cTable+data[x]))]++; } } } // integrate the histogram to get the equalization map. j=0; for(i=0; i <= MaxRGB; i++){ j+=histogram[i]; map[i]=j; } free(histogram); if(map[MaxRGB] == 0){ free(equalize_map); free(map); return; } // equalize low=map[0]; high=map[MaxRGB]; for(i=0; i <= MaxRGB; i++) equalize_map[i]=(unsigned int) ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1)); free(map); // stretch the histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ data[x] = qRgba(equalize_map[qRed(data[x])], equalize_map[qGreen(data[x])], equalize_map[qBlue(data[x])], qAlpha(data[x])); } } } else{ // PsudeoClass int colors = img.numColors(); unsigned int *cTable = img.colorTable(); for(i=0; i < colors; ++i){ cTable[i] = qRgba(equalize_map[qRed(cTable[i])], equalize_map[qGreen(cTable[i])], equalize_map[qBlue(cTable[i])], qAlpha(cTable[i])); } } free(equalize_map); } QImage OImageEffect::sample(QImage &src, int w, int h) { if(w == src.width() && h == src.height()) return(src); double *x_offset, *y_offset; int j, k, y; register int x; QImage dest(w, h, src.depth()); x_offset = (double *)malloc(w*sizeof(double)); y_offset = (double *)malloc(h*sizeof(double)); if(!x_offset || !y_offset){ owarn << "Unable to allocate pixels buffer" << oendl; free(x_offset); free(y_offset); return(src); } // init pixel offsets for(x=0; x < w; ++x) x_offset[x] = x*src.width()/((double)w); for(y=0; y < h; ++y) y_offset[y] = y*src.height()/((double)h); // sample each row if(src.depth() > 8){ // DirectClass source image unsigned int *srcData, *destData; unsigned int *pixels; pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int)); if(!pixels){ owarn << "Unable to allocate pixels buffer" << oendl; free(pixels); free(x_offset); free(y_offset); return(src); } j = (-1); for(y=0; y < h; ++y){ destData = (unsigned int *)dest.scanLine(y); if(j != y_offset[y]){ // read a scan line j = (int)(y_offset[y]); srcData = (unsigned int *)src.scanLine(j); (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int)); } // sample each column for(x=0; x < w; ++x){ k = (int)(x_offset[x]); destData[x] = pixels[k]; } } free(pixels); } else{ // PsudeoClass source image unsigned char *srcData, *destData; unsigned char *pixels; pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char)); if(!pixels){ owarn << "Unable to allocate pixels buffer" << oendl; free(pixels); free(x_offset); free(y_offset); return(src); } // copy colortable dest.setNumColors(src.numColors()); (void)memcpy(dest.colorTable(), src.colorTable(), src.numColors()*sizeof(unsigned int)); // sample image j = (-1); for(y=0; y < h; ++y){ destData = (unsigned char *)dest.scanLine(y); if(j != y_offset[y]){ // read a scan line j = (int)(y_offset[y]); srcData = (unsigned char *)src.scanLine(j); (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned char)); } // sample each column for(x=0; x < w; ++x){ k = (int)(x_offset[x]); destData[x] = pixels[k]; } } free(pixels); } free(x_offset); free(y_offset); return(dest); } void OImageEffect::threshold(QImage &img, unsigned int threshold) { int i, count; unsigned int *data; if(img.depth() > 8){ // DirectClass count = img.width()*img.height(); data = (unsigned int *)img.bits(); } else{ // PsudeoClass count = img.numColors(); data = (unsigned int *)img.colorTable(); } for(i=0; i < count; ++i) data[i] = intensityValue(data[i]) < threshold ? Qt::black.rgb() : Qt::white.rgb(); } QImage OImageEffect::charcoal(QImage &src, double factor) { QImage dest(src); dest.detach(); toGray(dest); dest = edge(dest, factor); dest = blur(dest, factor); normalize(dest); dest.invertPixels(false); return(dest); } void OImageEffect::hull(const int x_offset, const int y_offset, const int polarity, const int columns, const int rows, unsigned int *f, unsigned int *g) { int x, y; unsigned int *p, *q, *r, *s; unsigned int v; if(f == NULL || g == NULL) return; p=f+(columns+2); q=g+(columns+2); r=p+(y_offset*(columns+2)+x_offset); for (y=0; y < rows; y++){ p++; q++; r++; if(polarity > 0) for (x=0; x < columns; x++){ v=(*p); if (*r > v) v++; *q=v; p++; q++; r++; } else for(x=0; x < columns; x++){ v=(*p); if (v > (unsigned int) (*r+1)) v--; *q=v; p++; q++; r++; } p++; q++; r++; } p=f+(columns+2); q=g+(columns+2); r=q+(y_offset*(columns+2)+x_offset); s=q-(y_offset*(columns+2)+x_offset); for(y=0; y < rows; y++){ p++; q++; r++; s++; if(polarity > 0) for(x=0; x < (int) columns; x++){ v=(*q); if (((unsigned int) (*s+1) > v) && (*r > v)) v++; *p=v; p++; q++; r++; s++; } else for (x=0; x < columns; x++){ v=(*q); if (((unsigned int) (*s+1) < v) && (*r < v)) v--; *p=v; p++; q++; r++; s++; } p++; q++; r++; s++; } } QImage OImageEffect::despeckle(QImage &src) { int i, j, x, y; unsigned int *blue_channel, *red_channel, *green_channel, *buffer, *alpha_channel; int packets; static const int X[4]= {0, 1, 1,-1}, Y[4]= {1, 0, 1, 1}; unsigned int *destData; QImage dest(src.width(), src.height(), 32); packets = (src.width()+2)*(src.height()+2); red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); buffer = (unsigned int *)calloc(packets, sizeof(unsigned int)); if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || !buffer){ free(red_channel); free(green_channel); free(blue_channel); free(alpha_channel); free(buffer); return(src); } // copy image pixels to color component buffers j = src.width()+2; if(src.depth() > 8){ // DirectClass source image unsigned int *srcData; for(y=0; y < src.height(); ++y){ srcData = (unsigned int *)src.scanLine(y); ++j; for(x=0; x < src.width(); ++x){ red_channel[j] = qRed(srcData[x]); green_channel[j] = qGreen(srcData[x]); blue_channel[j] = qBlue(srcData[x]); alpha_channel[j] = qAlpha(srcData[x]); ++j; } ++j; } } else{ // PsudeoClass source image unsigned char *srcData; unsigned int *cTable = src.colorTable(); unsigned int pixel; for(y=0; y < src.height(); ++y){ srcData = (unsigned char *)src.scanLine(y); ++j; for(x=0; x < src.width(); ++x){ pixel = *(cTable+srcData[x]); red_channel[j] = qRed(pixel); green_channel[j] = qGreen(pixel); blue_channel[j] = qBlue(pixel); diff --git a/library/global.cpp b/library/global.cpp index 7bdd0b1..1895006 100644 --- a/library/global.cpp +++ b/library/global.cpp @@ -159,702 +159,706 @@ static QString dictDir() and hideInputMethod() hides the input method. \section1 Document related The findDocuments() function creates a set of \link doclnk.html DocLnk\endlink objects in a particular folder. \section1 Filesystem related Global provides an applicationFileName() function that returns the full path of an application-specific file. The execute() function runs an application. \section1 Word list related A list of words relevant to the current locale is maintained by the system. The list is held in a \link qdawg.html DAWG\endlink (implemented by the QDawg class). This list is used, for example, by the pickboard input method. The global QDawg is returned by fixedDawg(); this cannot be updated. An updatable copy of the global QDawg is returned by addedDawg(). Applications may have their own word lists stored in \l{QDawg}s which are returned by dawg(). Use addWords() to add words to the updateable copy of the global QDawg or to named application \l{QDawg}s. \section1 Quoting The shellQuote() function quotes a string suitable for passing to a shell. The stringQuote() function backslash escapes '\' and '"' characters. \section1 Hardware The implementation of the writeHWClock() function depends on the AlarmServer implementation. If the AlarmServer is using atd the clock will be synced to hardware. If opie-alarm is used the hardware clock will be synced before suspending the device. opie-alarm is used by iPAQ and Zaurii implementation \ingroup qtopiaemb */ /*! \internal */ Global::Global() { } /*! Returns the unchangeable QDawg that contains general words for the current locale. \sa addedDawg() */ const QDawg& Global::fixedDawg() { if ( !fixed_dawg ) { if ( !docDirCreated ) createDocDir(); fixed_dawg = new QDawg; QString dawgfilename = dictDir() + "/dawg"; QString words_lang; QStringList langs = Global::languageList(); for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { QString lang = *it; words_lang = dictDir() + "/words." + lang; QString dawgfilename_lang = dawgfilename + "." + lang; if ( QFile::exists(dawgfilename_lang) || QFile::exists(words_lang) ) { dawgfilename = dawgfilename_lang; break; } } QFile dawgfile(dawgfilename); if ( !dawgfile.exists() ) { QString fn = dictDir() + "/words"; if ( QFile::exists(words_lang) ) fn = words_lang; QFile in(fn); if ( in.open(IO_ReadOnly) ) { fixed_dawg->createFromWords(&in); if (dawgfile.open(IO_WriteOnly)) fixed_dawg->write(&dawgfile); dawgfile.close(); } } else fixed_dawg->readFile(dawgfilename); } return *fixed_dawg; } /*! Returns the changeable QDawg that contains general words for the current locale. \sa fixedDawg() */ const QDawg& Global::addedDawg() { return dawg("local"); } /*! Returns the QDawg with the given \a name. This is an application-specific word list. \a name should not contain "/". */ const QDawg& Global::dawg(const QString& name) { createDocDir(); if ( !named_dawg ) named_dawg = new QDict<QDawg>; QDawg* r = named_dawg->find(name); if ( !r ) { r = new QDawg; named_dawg->insert(name,r); QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; QFile dawgfile(dawgfilename); if ( dawgfile.open(IO_ReadOnly) ) r->readFile(dawgfilename); } return *r; } /*! \overload Adds \a wordlist to the addedDawg(). Note that the addition of words persists between program executions (they are saved in the dictionary files), so you should confirm the words with the user before adding them. */ void Global::addWords(const QStringList& wordlist) { addWords("local",wordlist); } /*! \overload Adds \a wordlist to the addedDawg(). Note that the addition of words persists between program executions (they are saved in the dictionary files), so you should confirm the words with the user before adding them. */ void Global::addWords(const QString& dictname, const QStringList& wordlist) { QDawg& d = (QDawg&)dawg(dictname); QStringList all = d.allWords() + wordlist; d.createFromWords(all); QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; QFile dawgfile(dawgfilename); if ( dawgfile.open(IO_WriteOnly) ) { d.write(&dawgfile); dawgfile.close(); } // #### Re-read the dawg here if we use mmap(). // #### Signal other processes to re-read. } /*! Returns the full path for the application called \a appname, with the given \a filename. Returns QString::null if there was a problem creating the directory tree for \a appname. If \a filename contains "/", it is the caller's responsibility to ensure that those directories exist. */ QString Global::applicationFileName(const QString& appname, const QString& filename) { QDir d; QString r = getenv("HOME"); r += "/Applications/"; if ( !QFile::exists( r ) ) if ( d.mkdir(r) == false ) return QString::null; r += appname; if ( !QFile::exists( r ) ) if ( d.mkdir(r) == false ) return QString::null; r += "/"; r += filename; return r; } /*! \internal */ void Global::createDocDir() { if ( !docDirCreated ) { docDirCreated = TRUE; mkdir( QPEApplication::documentDir().latin1(), 0755 ); } } /*! Displays a status \a message to the user. This usually appears in the taskbar for a short amount of time, then disappears. */ void Global::statusMessage(const QString& message) { #if !defined(QT_NO_COP) QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); e << message; #endif } /*! \internal */ void Global::applyStyle() { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/System", "applyStyle()" ); #else ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version #endif } /*! \internal */ QWidget *Global::shutdown( bool ) { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/System", "shutdown()" ); #endif return 0; } /*! \internal */ QWidget *Global::restart( bool ) { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/System", "restart()" ); #endif return 0; } /*! Explicitly show the current input method. Input methods are indicated in the taskbar by a small icon. If the input method is activated (shown) then it takes up some proportion of the bottom of the screen, to allow the user to interact (input characters) with it. \sa hideInputMethod() */ void Global::showInputMethod() { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); #endif } /*! Explicitly hide the current input method. The current input method is still indicated in the taskbar, but no longer takes up screen space, and can no longer be interacted with. \sa showInputMethod() */ void Global::hideInputMethod() { #if !defined(QT_NO_COP) QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); #endif } /*! \internal */ bool Global::isBuiltinCommand( const QString &name ) { if(!builtin) return FALSE; // yes, it can happen for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == name ) { return TRUE; } } return FALSE; } Global::Command* Global::builtin=0; QGuardedPtr<QWidget> *Global::running=0; /*! \class Global::Command \brief The Global::Command class is internal. \internal */ /*! \internal */ void Global::setBuiltinCommands( Command* list ) { if ( running ) delete [] running; builtin = list; int count = 0; if (!builtin) return; while ( builtin[count].file ) count++; running = new QGuardedPtr<QWidget> [ count ]; } /*! \internal */ void Global::setDocument( QWidget* receiver, const QString& document ) { Emitter emitter(receiver,document); } /*! \internal */ bool Global::terminateBuiltin( const QString& n ) { if (!builtin) return FALSE; for (int i = 0; builtin[i].file; i++) { if ( builtin[i].file == n ) { delete running[i]; return TRUE; } } return FALSE; } /*! \internal */ void Global::terminate( const AppLnk* app ) { //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this #ifndef QT_NO_COP QCString channel = "QPE/Application/" + app->exec().utf8(); if ( QCopChannel::isRegistered(channel) ) { QCopEnvelope e(channel, "quit()"); } #endif } /*! Low-level function to run command \a c. \warning Do not use this function. Use execute instead. \sa execute() */ void Global::invoke(const QString &c) { // Convert the command line in to a list of arguments QStringList list = QStringList::split(QRegExp(" *"),c); #if !defined(QT_NO_COP) QString ap=list[0]; // see if the application is already running // XXX should lock file /tmp/qcop-msg-ap if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { // If the channel is already register, the app is already running, so show it. - { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } + { + QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); + } //QCopEnvelope e("QPE/System", "notBusy(QString)" ); //e << ap; return; } // XXX should unlock file /tmp/qcop-msg-ap //see if it is being started if ( StartingAppList::isStarting( ap ) ) { // FIXME take it out for now, since it leads to a much to short showing of wait if // some entry is clicked. // Real cause is that ::execute is called twice for document tab. But it would need some larger changes // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there // had the idea that an apploader belongs to the launcher ... //QCopEnvelope e("QPE/System", "notBusy(QString)" ); //e << ap; return; } #endif #ifdef QT_NO_QWS_MULTIPROCESS QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); #else QStrList slist; unsigned int j; for ( j = 0; j < list.count(); j++ ) slist.append( list[j].utf8() ); const char **args = new const char *[slist.count() + 1]; for ( j = 0; j < slist.count(); j++ ) args[j] = slist.at(j); + args[j] = NULL; #if !defined(QT_NO_COP) // an attempt to show a wait... // more logic should be used, but this will be fine for the moment... QCopEnvelope ( "QPE/System", "busy()" ); #endif #ifdef HAVE_QUICKEXEC #ifdef Q_OS_MACX QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; #else QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; #endif qDebug("libfile = %s", libexe.latin1() ); if ( QFile::exists( libexe ) ) { qDebug("calling quickexec %s", libexe.latin1() ); quickexecv( libexe.utf8().data(), (const char **)args ); } else #endif { bool success = false; int pfd [2]; if ( ::pipe ( pfd ) < 0 ) pfd [0] = pfd [1] = -1; pid_t pid = ::fork ( ); if ( pid == 0 ) { // child for ( int fd = 3; fd < 100; fd++ ) { if ( fd != pfd [1] ) ::close ( fd ); } ::setpgid ( ::getpid ( ), ::getppid ( )); // Closing of fd[1] indicates that the execvp succeeded! if ( pfd [1] >= 0 ) ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); // Try bindir first, so that foo/bar works too ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); ::execvp ( args [0], (char * const *) args ); char resultByte = 1; if ( pfd [1] >= 0 ) ::write ( pfd [1], &resultByte, 1 ); ::_exit ( -1 ); } else if ( pid > 0 ) { success = true; if ( pfd [1] >= 0 ) ::close ( pfd [1] ); if ( pfd [0] >= 0 ) { while ( true ) { char resultByte; int n = ::read ( pfd [0], &resultByte, 1 ); if ( n == 1 ) { success = false; break; } if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) continue; break; // success } ::close ( pfd [0] ); } } if ( success ) StartingAppList::add( list[0] ); else QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); } + delete [] args; #endif //QT_NO_QWS_MULTIPROCESS } /*! Executes the application identfied by \a c, passing \a document if it isn't null. Note that a better approach might be to send a QCop message to the application's QPE/Application/\e{appname} channel. */ void Global::execute( const QString &c, const QString& document ) { // ask the server to do the work #if !defined(QT_NO_COP) if ( document.isNull() ) { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << c; } else { QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); e << c << document; } #endif return; } /*! Returns the string \a s with the characters '\', '"', and '$' quoted by a preceeding '\'. \sa stringQuote() */ QString Global::shellQuote(const QString& s) { QString r="\""; for (int i=0; i<(int)s.length(); i++) { char c = s[i].latin1(); switch (c) { case '\\': case '"': case '$': r+="\\"; } r += s[i]; } r += "\""; return r; } /*! Returns the string \a s with the characters '\' and '"' quoted by a preceeding '\'. \sa shellQuote() */ QString Global::stringQuote(const QString& s) { QString r="\""; for (int i=0; i<(int)s.length(); i++) { char c = s[i].latin1(); switch (c) { case '\\': case '"': r+="\\"; } r += s[i]; } r += "\""; return r; } /*! Finds all documents on the system's document directories which match the filter \a mimefilter, and appends the resulting DocLnk objects to \a folder. */ void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) { QString homedocs = QString(getenv("HOME")) + "/Documents"; DocLnkSet d(homedocs,mimefilter); folder->appendFrom(d); /** let's do intellegint way of searching these files * a) the user don't want to check mediums global * b) the user wants to check but use the global options for it * c) the user wants to check it but not this medium * d) the user wants to check and this medium as well * * In all cases we need to apply a different mimefilter to * the medium. * a) mimefilter.isEmpty() we need to apply the responding filter * either the global or the one on the medium * * b) mimefilter is set to an application we need to find out if the * mimetypes are included in the mime mask of the medium */ StorageInfo storage; const QList<FileSystem> &fs = storage.fileSystems(); QListIterator<FileSystem> it ( fs ); for ( ; it.current(); ++it ) { if ( (*it)->isRemovable() ) { // let's find out if we should search on it // this is a candidate look at the cf and see if we should search on it QString path = (*it)->path(); Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); conf.setGroup("main"); if (!conf.readBoolEntry("check",true)) { continue; } conf.setGroup("subdirs"); if (conf.readBoolEntry("wholemedia",true)) { DocLnkSet ide( path,mimefilter); folder->appendFrom(ide); } else { QStringList subDirs = conf.readListEntry("subdirs",':'); if (subDirs.isEmpty()) { subDirs.append("Documents"); } for (unsigned c = 0; c < subDirs.count();++c) { DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); folder->appendFrom(ide); } } } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { QString path = (*it)->path() + "/Documents"; DocLnkSet ide( path, mimefilter ); folder->appendFrom(ide); } } } QStringList Global::languageList() { QString lang = getenv("LANG"); QStringList langs; langs.append(lang); int i = lang.find("."); if ( i > 0 ) lang = lang.left( i ); i = lang.find( "_" ); if ( i > 0 ) langs.append(lang.left(i)); return langs; } QStringList Global::helpPath() { QString qpeDir = QPEApplication::qpeDir(); QStringList path; QStringList langs = Global::languageList(); for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { QString lang = *it; if ( !lang.isEmpty() ) path += qpeDir + "/help/" + lang + "/html"; } path += qpeDir + "/pics"; path += qpeDir + "/help/html"; /* we even put english into the en dir so try it as fallback as well for opie */ path += qpeDir + "/help/en/html"; path += qpeDir + "/docs"; return path; } /*! \internal Truncate file to size specified \a f must be an open file \a size must be a positive value */ bool Global::truncateFile(QFile &f, int size){ if (!f.isOpen()) return FALSE; return ::ftruncate(f.handle(), size) != -1; } // #if defined(Q_OS_UNIX) && defined(Q_WS_QWS) // extern int qws_display_id; // #endif /*! /internal Returns the default system path for storing temporary files. Note: This does not it ensure that the provided directory exists */ QString Global::tempDir() { QString result; #ifdef Q_OS_UNIX #ifdef Q_WS_QWS result = QString("/tmp/qtopia-%1/").arg(QString::number(qws_display_id)); #else result="/tmp/"; #endif #else if (getenv("TEMP")) result = getenv("TEMP"); else result = getenv("TMP"); if (result[(int)result.length() - 1] != QDir::separator()) result.append(QDir::separator()); #endif return result; } //#endif #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 @@ #include <qmessagebox.h> #include "Bkmks.h" #include "StyleConsts.h" #include "Markups.h" #include "my_list.h" #include "version.h" #include "names.h" const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) : m_name(0), m_namelen(0), m_anno(0), m_annolen(0), m_position(0) { init(_nm, _nmlen, _anno, _annolen, _p); } Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) { init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p); } Bkmk::Bkmk(const Bkmk& rhs) : m_name(0), m_namelen(0), m_anno(0), m_annolen(0), m_position(0) { init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(), sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value()); } Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) { if (_anno == NULL) { tchar t = 0; init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); } else { init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); } } Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) { if (_anno == NULL) { tchar t = 0; init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); } else { init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); } m_position2 = _p2; m_red = m_green = m_blue = 127; } void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) { m_namelen = _nmlen; if (m_namelen > 0) { m_name = new unsigned char[m_namelen]; memcpy(m_name, _nm, m_namelen); } else { m_name = NULL; } m_annolen = _annolen; if (m_annolen > 0) { m_anno = new unsigned char[m_annolen]; memcpy(m_anno, _anno, m_annolen); } else { m_anno = NULL; } m_position = _p; m_position2 = _p; m_red = m_green = m_blue = 255; m_level = 0; } Bkmk::~Bkmk() { if (m_name != NULL) delete [] m_name; m_name = NULL; if (m_anno != NULL) delete [] m_anno; m_anno = NULL; } Bkmk& Bkmk::operator=(const Bkmk& rhs) { if (m_name != NULL) { delete [] m_name; m_name = NULL; } if (m_anno != NULL) { delete [] m_anno; m_anno = NULL; } if (rhs.m_name != NULL) { m_namelen = rhs.m_namelen; m_name = new unsigned char[m_namelen]; memcpy(m_name, rhs.m_name, m_namelen); } else m_name = NULL; if (rhs.m_anno != NULL) { m_annolen = rhs.m_annolen; m_anno = new unsigned char[m_annolen]; memcpy(m_anno, rhs.m_anno, m_annolen); } else m_anno = NULL; m_position = rhs.m_position; m_position2 = rhs.m_position2; m_red = rhs.m_red; m_green = rhs.m_green; m_blue = rhs.m_blue; m_level = rhs.m_level; return *this; } bool Bkmk::operator==(const Bkmk& rhs) { 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); } void Bkmk::setAnno(unsigned char* t, unsigned short len) { if (m_anno != NULL) { delete [] m_anno; m_anno = NULL; } if (t != NULL) { m_annolen = len; m_anno = new unsigned char[m_annolen]; memcpy(m_anno, t, m_annolen); } else { m_annolen = sizeof(tchar); m_anno = new unsigned char[m_annolen]; *((tchar*)m_anno) = 0; } } void Bkmk::setAnno(tchar* t) { if (m_anno != NULL) { delete [] m_anno; m_anno = NULL; } if (t != NULL) { unsigned short len = ustrlen(t)+1; m_annolen = sizeof(tchar)*len; m_anno = new unsigned char[m_annolen]; memcpy(m_anno, t, m_annolen); } else { m_annolen = sizeof(tchar); m_anno = new unsigned char[m_annolen]; *((tchar*)m_anno) = 0; } } BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) : wt(w), isUpgraded(false), m_extras(_x) { if (w) { f = fopen(fnm, "wb"); } else { f = fopen(fnm, "rb"); } } BkmkFile::~BkmkFile() { if (f != NULL) fclose(f); } void BkmkFile::write(const Bkmk& b) { if (f != NULL) { fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f); fwrite(b.m_name,1,b.m_namelen,f); fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f); fwrite(b.m_anno,1,b.m_annolen,f); fwrite(&b.m_position,sizeof(b.m_position),1,f); if (m_extras) { fwrite(&b.m_position2,sizeof(b.m_position2),1,f); fwrite(&b.m_red,sizeof(b.m_red),1,f); fwrite(&b.m_green,sizeof(b.m_green),1,f); fwrite(&b.m_blue,sizeof(b.m_blue),1,f); fwrite(&b.m_level,sizeof(b.m_level),1,f); } } } void BkmkFile::write(CList<Bkmk>& bl) { if (f != NULL) { fwrite(&magic, sizeof(magic), 1, f); for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++) { write(*i); } } } CList<Bkmk>* BkmkFile::readall() { CList<Bkmk>* bl = NULL; if (f != NULL) { unsigned long newmagic; fread(&newmagic, sizeof(newmagic), 1, f); if ((newmagic & 0xffffff00) != (magic & 0xffffff00)) { if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0) { fseek(f,0,SEEK_SET); bl = readall00(&read05); } else { fseek(f,0,SEEK_SET); bl = readall00(&read03); } isUpgraded = true; } else { switch(newmagic & 0xff) { case 7: isUpgraded = false; bl = readall00(read07); // qDebug("Correct version!"); break; case 6: isUpgraded = true; bl = readall00(read06); // qDebug("Correct version!"); break; case 5: isUpgraded = true; bl = readall00(read05); // qDebug("Known version!"); break; default: // qDebug("Unknown version!"); isUpgraded = true; bl = readall00(read05); } } } return bl; } CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) { CList<Bkmk>* bl = new CList<Bkmk>; while (1) { Bkmk* b = (*readfn)(this, f); if (b == NULL) break; bl->push_back(*b); delete b; } return bl; } Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) { Bkmk* b = NULL; if (f != NULL) { unsigned short ln; if (fread(&ln,sizeof(ln),1,f) == 1) { tchar* name = new tchar[ln+1]; fread(name,sizeof(tchar),ln,f); name[ln] = 0; ln = 0; tchar* anno = new tchar[ln+1]; anno[ln] = 0; unsigned int pos; fread(&pos,sizeof(pos),1,f); b = new Bkmk(name,anno,pos); delete [] anno; } } return b; } Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) { Bkmk* b = NULL; if (f != NULL) { unsigned short ln; if (fread(&ln,sizeof(ln),1,f) == 1) { tchar* nm = new tchar[ln+1]; fread(nm,sizeof(tchar),ln,f); nm[ln] = 0; fread(&ln,sizeof(ln),1,f); tchar* anno = new tchar[ln+1]; if (ln > 0) fread(anno,sizeof(tchar),ln,f); anno[ln] = 0; unsigned int pos; fread(&pos,sizeof(pos),1,f); b = new Bkmk(nm,anno,pos); + delete [] anno; } } return b; } Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) { Bkmk* b = NULL; if (f != NULL) { unsigned short ln; if (fread(&ln,sizeof(ln),1,f) == 1) { b = new Bkmk; b->m_namelen = ln; b->m_name = new unsigned char[b->m_namelen]; fread(b->m_name,1,b->m_namelen,f); fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); if (b->m_annolen > 0) { b->m_anno = new unsigned char[b->m_annolen]; fread(b->m_anno,1,b->m_annolen,f); } fread(&(b->m_position),sizeof(b->m_position),1,f); b->m_position2 = b->m_position+b->m_namelen-1; b->m_red = b->m_green = b->m_blue = 127; b->m_level = 0; } } return b; } Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) { Bkmk* b = NULL; if (f != NULL) { unsigned short ln; if (fread(&ln,sizeof(ln),1,f) == 1) { b = new Bkmk; b->m_namelen = ln; b->m_name = new unsigned char[b->m_namelen]; fread(b->m_name,1,b->m_namelen,f); fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); if (b->m_annolen > 0) { b->m_anno = new unsigned char[b->m_annolen]; fread(b->m_anno,1,b->m_annolen,f); } fread(&(b->m_position),sizeof(b->m_position),1,f); if (_this->m_extras) { fread(&(b->m_position2),sizeof(b->m_position2),1,f); fread(&(b->m_red),sizeof(b->m_red),1,f); fread(&(b->m_green),sizeof(b->m_green),1,f); fread(&(b->m_blue),sizeof(b->m_blue),1,f); fread(&(b->m_level),sizeof(b->m_level),1,f); } else { b->m_position2 = b->m_position; b->m_red = b->m_green = b->m_blue = 255; b->m_level = 0; } } } return b; } 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 @@ /* =. This file is part of the Opie Project .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Excel.h" /* STD */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <sys/types.h> #include <strings.h> static xfrecord formatter[] = { { 0xe , DATEFORMAT, "%m/%d/%y"}, { 0xf , DATEFORMAT, "%d-%b-%y"}, { 0x10, DATEFORMAT, "%d-%b"}, { 0x11, DATEFORMAT, "%b-%y"}, { 0x12, DATEFORMAT, "%I:%M %p"}, { 0x13, DATEFORMAT, "%I:%M:%S %p"}, { 0x14, DATEFORMAT, "%H:%M"}, { 0x15, DATEFORMAT, "%H:%M:%S"}, { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"}, { 0x2d, DATEFORMAT, "%M:%S"}, { 0x2e, DATEFORMAT, "%H:%M:%S"}, { 0x2f, DATEFORMAT, "%M:%S"}, { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"}, { 0x1 , NUMBERFORMAT, "%.0f"}, { 0x2 , NUMBERFORMAT, "%.2f"}, { 0x3 , NUMBERFORMAT, "#,##%.0f"}, { 0x4 , NUMBERFORMAT, "#,##%.2f"}, { 0x5 , NUMBERFORMAT, "$#,##%.0f"}, { 0x6 , NUMBERFORMAT, "$#,##%.0f"}, { 0x7 , NUMBERFORMAT, "$#,##%.2f"}, { 0x8 , NUMBERFORMAT, "$#,##%.2f"}, { 0x9 , NUMBERFORMAT, "%.0f%%"}, { 0xa , NUMBERFORMAT, "%.2f%%"}, { 0xb , NUMBERFORMAT, "%e"}, { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"}, { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"}, { 0x30, NUMBERFORMAT, "##0.0E0"}, { 0, 0, ""} }; int ExcelBook::Integer2Byte(int b1, int b2) { int i1 = b1 & 0xff; int i2 = b2 & 0xff; int val = i2 << 8 | i1; return val; }; int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) { int i1 = Integer2Byte(b1, b2); int i2 = Integer2Byte(b3, b4); int val = i2 << 16 | i1; return val; }; int ExcelBook::Integer2ByteFile(FILE *f) { int i1, i2; i1 = fgetc(f); i2 = fgetc(f); return Integer2Byte(i1,i2); }; float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) { int i; float f; unsigned char *ieee; ieee = (unsigned char *) &f; for (i = 0; i < 4; i++) ieee[i] = 0; ieee[0] = ((int)b4) & 0xff; ieee[1] = ((int)b3) & 0xff; ieee[2] = ((int)b2) & 0xff; ieee[3] = ((int)b1) & 0xff; return f; }; double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) { long int rk; double value; rk=Integer4Byte(b1,b2,b3,b4); //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4); if ( (rk & 0x02) != 0) { long int intval = rk >> 2; //drops the 2 bits printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2); value = (double) intval; printf("Double4Byte: VALUEINT=%f\r\n",value); if ( (rk & 0x01) != 0) { value /= 100.0; }; return value; } else { union { double d; unsigned long int b[2]; } dbl_byte; unsigned long int valbits = (rk & 0xfffffffc); #if defined(__arm__) && !defined(__vfp__) dbl_byte.b[0]=valbits; dbl_byte.b[1]=0; #else dbl_byte.b[0]=0; dbl_byte.b[1]=valbits; #endif printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]); value=dbl_byte.d; printf("Double4Byte: VALUE=%f\r\n",value); if ( (rk & 0x01) != 0) { value /= 100.0; }; return value; }; }; void ExcelBook::DetectEndian(void) { int end; long i = 0x44332211; unsigned char* a = (unsigned char*) &i; end = (*a != 0x11); if (end == 1) { endian = BIG_ENDIAN; printf("BIGENDIAN!\r\n"); } else { endian = LITTLE_ENDIAN; printf("LITTLEENDIAN!\r\n"); } }; double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) { int i; double d; unsigned char *ieee; ieee = (unsigned char *)&d; for (i = 0; i < 8; i++) ieee[i] = 0; if (endian == BIG_ENDIAN) { ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff; ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff; ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff; ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff; } else { ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff; ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff; ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff; ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff; } return d; }; bool ExcelBook::OpenFile(char *Filename) { printf("Opening excel file!\r\n"); File= fopen(Filename, "r"); Position=0; // first byte index in file XFRecords.resize(0); SharedStrings.resize(0); Names.resize(0); Sheets.resize(0); if(File==NULL) return false; printf("Opened excel file!\r\n"); return true; }; bool ExcelBook::CloseFile(void) { int w1; for(w1=0;w1<(int)XFRecords.count();w1++) { if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;}; }; for(w1=0;w1<(int)SharedStrings.count();w1++) { if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;}; }; for(w1=0;w1<(int)Names.count();w1++) { if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;}; }; for(w1=0;w1<(int)Sheets.count();w1++) { if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;}; }; XFRecords.resize(0); SharedStrings.resize(0); Names.resize(0); Sheets.resize(0); fclose(File); printf("closed excel file!\r\n"); if(File==NULL) return true; return false; }; void ExcelBook::SeekPosition(int pos) { if(!feof(File)) { Position=pos; //printf("SeekPosition:Pos:%d\r\n",Position); fseek(File,pos,SEEK_SET); }; }; void ExcelBook::SeekSkip(int pos) { if(!feof(File)) { Position=Position+pos; //printf("SeekSkip:Pos:%d\r\n",Position); fseek(File, Position, SEEK_SET); }; }; int ExcelBook::FileEOF(void) { if(File!=NULL) return(feof(File)); else return 0; //EOF is defined in stdlib as -1 }; int ExcelBook::Get2Bytes(void) { int i1,i2; i1=0; i2=0; if (!feof(File)) { i1=fgetc(File); Position++; }; if (!feof(File)) { i2=fgetc(File); Position++; }; return Integer2Byte(i1,i2); }; char* ExcelBook::Read(int pos, int length) { int i; char *data; data= new char[length]; SeekPosition(pos); for(i=0; i<length; i++) { if(!feof(File)) data[i]=fgetc(File); }; Position= Position+length; return data; }; QString ExcelBook::ReadUnicodeChar(int pos, int length) { int i; QString data; int i1=' ',i2=' ',ii; SeekPosition(pos); for(i=0; i<length; i++) { if(!feof(File)) i1=fgetc(File); if(!feof(File)) i2=fgetc(File); ii=Integer2Byte(i1,i2); data.append(ii); Position+=2; }; return data; }; QString* ExcelBook::GetString(int num) { if(num>=0 && num<(int)SharedStrings.count()) { return SharedStrings[num]; }; return new QString(""); }; int ExcelBook::SeekBOF(void) { int opcode,version,streamtype,length,ret=0; char *data; while(!feof(File)) { opcode=Get2Bytes(); if(opcode==XL_BOF) { length=Get2Bytes(); data=Read(Position,length); version=Integer2Byte(data[0], data[1]); streamtype=Integer2Byte(data[2], data[3]); printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version); delete [] data; data=NULL; if (version==BIFF8) ret=8; else if(version==BIFF7) ret=7; printf("SEEKBOF:versionBIFF%d\r\n",ret); if(streamtype==WBKGLOBAL) return ret *2; else if(streamtype==WRKSHEET) return ret *1; return 1; }; }; return 0; }; ExcelBREC* ExcelBook::GetBREC(void) { ExcelBREC* rec; rec= new ExcelBREC; if(FileEOF()) return NULL; rec->data=NULL; rec->code=Get2Bytes(); rec->length=Get2Bytes(); rec->position=Position; SeekSkip(rec->length); return rec; }; ExcelBREC* ExcelBook::PeekBREC(void) { int oldpos; ExcelBREC* NextRec; oldpos=Position; NextRec=GetBREC(); SeekPosition(oldpos); return NextRec; }; char* ExcelBook::GetDataOfBREC(ExcelBREC* record) { if(record->data==NULL) { - ConvertCharToArray(record,Read(record->position,record->length),record->length); + char* readData = Read(record->position,record->length); + ConvertCharToArray(record,readData,record->length); + delete [] readData; }; return record->data;//new? }; void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) { record->data=new char[length]; for(int w1=0;w1<=length-1;w1++) record->data[w1]=chars[w1]; }; bool ExcelSheet::InitCells() { int r; Cells.resize(rows * cols + cols+1); if(Cells.count()==0) return false; for(r=0;r < Cells.count();r++) { Cells[r]=NULL; }; return true; }; void ExcelSheet::Set(int row, int col, ExcelCell* cell) { if(cell!=NULL&&(row*cols+col)<Cells.count()) { Cells[row*cols+col]=cell; }; }; ExcelCell* ExcelSheet::Get(int row, int col) { ExcelCell* cell; cell=Cells[row*cols+col]; if(cell==NULL) return NULL; return cell; }; int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) { char* data=NULL; switch (record->code) { case XL_DIMENSION: data = GetDataOfBREC(record); if (record->length == 10) { sheet->rows = Integer2Byte(data[2], data[3]); sheet->cols = Integer2Byte(data[6], data[7]); } else { sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]); sheet->cols = Integer2Byte(data[10], data[11]); } sheet->InitCells(); break; case XL_LABELSST: HandleLabelSST(sheet, record); break; case XL_RK: case XL_RK2: HandleRK(sheet, record); break; case XL_MULRK: HandleMulrk(sheet, record); break; case XL_ROW: break; case XL_NUMBER: HandleNumber(sheet, record); break; case XL_BOOLERR: break; case XL_CONTINUE: break; case XL_FORMULA: case XL_FORMULA2: HandleFormula(sheet, record); break; case XL_LABEL: break; case XL_NAME: HandleName(sheet, record); break; case XL_BOF: break; case XL_EOF: return 0; default: break; }; return 1; }; int ExcelBook::ReadSheet(ExcelSheet* sheet) { ExcelBREC* record; int oldpos; oldpos = Position; SeekPosition(sheet->position); record = GetBREC(); while (record!=NULL) { if (!SheetHandleRecord(sheet, record)) break; record=GetBREC(); }; SeekPosition(oldpos); return 1; }; ExcelSheet* ExcelBook::GetSheet(void) { ExcelSheet* sh=NULL; int type; type=SeekBOF(); Version=type; sh=new ExcelSheet; if(type) { sh->type=type; sh->position=Position; sh->name=QString(""); }; if(type==8||type==7) { ReadSheet(sh); }; return sh; }; void ExcelBook::ParseSheets(void) { int BOFs; ExcelBREC* r; BOFs=1; r=GetBREC(); while(BOFs) { r=GetBREC(); switch(r->code) { case XL_SST: HandleSST(r); break; case XL_TXO: break; case XL_NAME: break; case XL_ROW: break; case XL_FORMAT: HandleFormat(r); break; case XL_XF: HandleXF(r); break; case XL_BOUNDSHEET: HandleBoundSheet(r); break; case XL_EXTSST: break; case XL_CONTINUE: break; case XL_EOF: BOFs--; break; default: break; }; }; }; void ExcelBook::GetSheets(void) { ExcelSheet* sheet; Sheets.resize(0); sheet=GetSheet(); while (sheet->Cells.count()!= 0 ) { Sheets.resize(Sheets.count()+1); Sheets[Sheets.count()-1]=sheet; sheet->name=*Names[Sheets.count()-1]; sheet=GetSheet(); }; }; bool ExcelBook::ParseBook(char *file) { dateformat=QString(""); DetectEndian(); if ( !OpenFile( file ) ) return false; SeekBOF(); ParseSheets(); GetSheets(); return true; }; QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) { int i; QString outstr=""; for (i = 0; i < chars; i++) { outstr.append(inbytes[i+pos]); }; return outstr; }; QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) { QString outstr=""; int i; int rc; for (i=0; i<chars*2; i++) { rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]); outstr.append(QChar(rc)); i++; }; return outstr; }; void ExcelBook::HandleBoundSheet(ExcelBREC* rec) { char* data; int type; int visibility; int length; int pos; QString name; pos = 8; data = GetDataOfBREC(rec); type = data[4]; visibility = data[5]; length = data[6]; if(data[7]==0) { //ascii name=GetASCII(data,pos,length); } else { name=GetUnicode(data,pos,length); }; Names.resize(Names.count()+1); Names[Names.count()-1]=new QString(name); }; void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) { char* data; QString name; int length; int pos; pos = 15; data = GetDataOfBREC(rec); length = data[3]; name = GetASCII(data,pos,length); }; ExcelFormat* ExcelBook::GetFormatting(int xf) { int i; ExcelFormat* rec; rec=new ExcelFormat(); for (i = 0; formatter[i].code != 0; i++) { if (xf == formatter[i].code) break; }; if (formatter[i].format ==NULL) return NULL; rec->code = xf; rec->type = formatter[i].type; rec->format = formatter[i].format; return rec; }; void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) { QString str=QString(""); char* data; int chars, pos, options, i; int richstring, fareaststring, runlength=0; int richruns=0,fareastsize=0; int totalstrings; int uniquestrings; data = GetDataOfBREC(rec); totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]); uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]); pos = 8; for (i = 0; i < uniquestrings; i++) { richruns=0; fareastsize=0; chars = Integer2Byte(data[pos], data[pos+1]); pos += 2; options = data[pos]; pos++; fareaststring = ((options & 0x04) != 0); richstring = ((options & 0x08) != 0); if(richstring) { richruns= Integer2Byte(data[pos],data[pos+1]); pos+=2; }; if(fareaststring) { fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]); pos+=4; }; if ((options & 0x01) == 0) //8 bit chars { /* ascii */ str = GetASCII(bytes,pos,chars); pos=pos+chars; if(str[0]=='=') str[0]=' '; }else //16 bit chars { /* unicode */ str = GetUnicode(bytes,pos,chars); pos=pos+chars*2; }; // HERE TO PUT richformat handling if (richstring) { pos += 4 * richruns; }; if (fareaststring) { pos += fareastsize; }; //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode()); SharedStrings.resize(SharedStrings.count()+1); SharedStrings[SharedStrings.count()-1]=new QString(str); } }; char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) { int i, pos; int length; char* data; char* bytes; length = rec->length; for (i = 0; i < (int) cont->rec.count(); i++) { length += cont->rec[i]->length; } bytes = GetDataOfBREC(rec); pos = rec->length; for (i = 0; i < (int) cont->rec.count(); i++) { data = GetDataOfBREC(cont->rec[i]); *bytes += pos; bytes = data; pos += cont->rec[i]->length; } 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 @@ -1391,1224 +1391,1225 @@ void ZSafe::readAllEntries() QString name; QString user; QString password; QString comment; // separete the entries char *i = strtok (buffer, "|"); QString category(&i[1]); category.truncate(category.length() -1); int idx=0; while (i = strtok (NULL, "|")) { switch (idx) { case 0: name = &i[1]; name.truncate(name.length() -1); // name break; case 1: // user user = &i[1]; user.truncate(user.length() -1); break; case 2: // password password = &i[1]; password.truncate(password.length() -1); break; case 3: // comment comment = &i[1]; comment.truncate(comment.length() -1); break; } idx++; } Category *cat= categories.find (category); if (cat) { // use the existend item QListViewItem *catItem = cat->getListItem(); if (catItem) { QListViewItem * item = new ShadedListItem( 0, catItem ); item->setText( 0, tr( name ) ); item->setText( 1, tr( user ) ); item->setText( 2, tr( password ) ); item->setText( 3, tr( comment ) ); catItem->setOpen( TRUE ); } } else { QListViewItem *catI = new ShadedListItem( 1, ListView ); // create and insert a new item QListViewItem * item = new ShadedListItem( 0, catI ); item->setText( 0, tr( name ) ); item->setText( 1, tr( user ) ); item->setText( 2, tr( password ) ); item->setText( 3, tr( comment ) ); catI->setOpen( TRUE ); Category *c1 = new Category(); c1->setCategoryName(category); QString icon; QString fullIconPath; QPixmap *pix; // #ifndef Q_WS_WIN icon = conf->readEntry(APP_KEY+category); // #endif bool isIconAv = false; if (!icon.isEmpty() && !icon.isNull()) { // build the full path fullIconPath = iconPath + icon; pix = new QPixmap (fullIconPath); if (!pix->isNull()) { QImage img = pix->convertToImage(); pix->convertFromImage(img.smoothScale(14,14)); c1->setIconName (icon); c1->setIcon (*pix); isIconAv = true; } } if (!isIconAv) { c1->setIcon (*getPredefinedIcon(category)); } c1->setListItem (catI); c1->initListItem(); categories.insert (c1->getCategoryName(), c1); } } f.close(); } #endif // UNUSED void ZSafe::resume(int) { // hide the main window if ( !showpwd ) { infoForm->hide(); // open zsafe again m_password = ""; selectedItem = NULL; // clear the password list QListViewItem *i; // step through all categories for (i = ListView->firstChild(); i != NULL; i = i->nextSibling()) { // step through all subitems QListViewItem *si; for (si = i->firstChild(); si != NULL; ) { QListViewItem *_si = si; si = si->nextSibling(); i->takeItem(_si); // remove from view list if (_si) delete _si; } } // ask for password and read again openDocument(filename); } } //--------------------------------------------- bool ZSafe::openDocument(const char* _filename, const char* ) { QString name= _filename; qWarning("openDocument "+name); int retval; char* entry[FIELD_SIZE]; // #ifndef Q_WS_WIN int validationFlag = conf->readNumEntry(APP_KEY+"valzsafe", 1); // #else // int validationFlag = 1; // #endif int pwdOk = 0; int numberOfTries = 3; for (int i=0; i < numberOfTries; i++) { QFile f(_filename); if (f.exists()) { // ask with a dialog for the password if (m_password.isEmpty()) getDocPassword(tr("Enter Password")); if (m_password.isEmpty() && validationFlag == 0) { QMessageBox::critical( 0, tr("ZSafe"), tr("Wrong password.\n\nZSafe will now exit.") ); exitZs (1); } retval = loadInit(_filename, m_password); if (retval != PWERR_GOOD) { return false; } } else { this->setCaption(tr("ZSafe")); filename = ""; switch( QMessageBox::warning( this, tr("ZSafe"), tr("<P>You must create a new document first. Ok to create?</P>"), tr("&Yes"), tr("&No."), 0 ) ) { case 1: // No return false; break; case 0: // Yes newDocument(); return false; break; } } // load the validation entry if (validationFlag == 0) { pwdOk = 1; break; } retval = loadEntry(entry); if (retval == 1 && !strcmp (entry[0], "ZSAFECATEGORY") && !strcmp (entry[1], "name") && !strcmp (entry[2], "username") && !strcmp (entry[3], "password") && !strcmp (entry[4], "comment") ) { for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); pwdOk = 1; break; } else // for (int count = 0; count < FIELD_SIZE; count++) free(entry[count]); fclose (fd); m_password = ""; if (i < numberOfTries - 1) { switch( QMessageBox::warning( this, tr("ZSafe"), tr("Wrong password.\nEnter again?"), tr("&Yes"), tr("&No."), 0 ) ) { case 1: // No exitZs (1); break; case 0: // Yes continue; } } } if (pwdOk == 0) { // unset the document entry conf->writeEntry(APP_KEY+"document", "INVALIDPWD"); if (conf) delete conf; exitZs (1); } retval = loadEntry(entry); int numberOfEntries=0; while (retval == 1) { QString category( QString::fromUtf8(entry[0]) ); QString name( QString::fromUtf8(entry[1]) ); QString user( QString::fromUtf8(entry[2]) ); QString password( QString::fromUtf8(entry[3]) ); QString comment( QString::fromUtf8(entry[4]) ); QString field5( QString::fromUtf8(entry[5]) ); QString field6( QString::fromUtf8(entry[6]) ); // add the subitems to the categories Category *cat= categories.find (category); if (cat) { // use the existend item QListViewItem *catItem = cat->getListItem(); if (catItem) { QListViewItem * item = new ShadedListItem( 0, catItem ); item->setText( 0, tr( name ) ); item->setText( 1, tr( user ) ); item->setText( 2, tr( password ) ); item->setText( 3, tr( comment ) ); item->setText( 4, tr( field5 ) ); item->setText( 5, tr( field6 ) ); if (expandTree) catItem->setOpen( TRUE ); numberOfEntries++; } } else { QListViewItem *catI = new ShadedListItem( 1, ListView ); // create and insert a new item QListViewItem * item = new ShadedListItem( 0, catI ); item->setText( 0, tr( name ) ); item->setText( 1, tr( user ) ); item->setText( 2, tr( password ) ); item->setText( 3, tr( comment ) ); item->setText( 4, tr( field5 ) ); item->setText( 5, tr( field6 ) ); if (expandTree) catI->setOpen( TRUE ); Category *c1 = new Category(); c1->setCategoryName(category); QString icon; QString fullIconPath; QPixmap *pix; // #ifndef Q_WS_WIN icon = conf->readEntry(APP_KEY+category); // #endif bool isIconAv = false; if (!icon.isEmpty() && !icon.isNull()) { // build the full path fullIconPath = iconPath + icon; pix = new QPixmap (fullIconPath); if (!pix->isNull()) { QImage img = pix->convertToImage(); pix->convertFromImage(img.smoothScale(14,14)); c1->setIconName (icon); c1->setIcon (*pix); isIconAv = true; } } if (!isIconAv) { c1->setIcon (*getPredefinedIcon(category)); } c1->setListItem (catI); c1->initListItem(); categories.insert (c1->getCategoryName(), c1); numberOfEntries++; } for (int count = 0; count < FIELD_SIZE; count++) { free(entry[count]); } retval = loadEntry(entry); if (retval == 2) { // m_parent->slotStatusHelpMsg("Last entry loaded"); } } // end while if (numberOfEntries == 0) { switch( QMessageBox::warning( this, tr("ZSafe"), tr("Empty document or\nwrong password.\nContinue?"), tr("&No"), tr("&Yes."), 0 ) ) { case 0: // No retval = loadFinalize(); exitZs (1); break; case 1: // Yes break; } } retval = loadFinalize(); return true; } int ZSafe::loadInit(const char* _filename, const char *password) { unsigned int j = 0; unsigned int keylength=0; int count=0, count2=0, count3=0; unsigned char charbuf[8]; unsigned short ciphertext[4]; char key[128]; Krc2* krc2 = new Krc2(); fd = fopen (_filename, "rb"); QFileInfo f (_filename); load_buffer_length = f.size(); load_buffer_length = ((load_buffer_length / 1024)+1) * 1024 * 2; - if (fd == NULL) + if (fd == NULL) { + delete krc2; return PWERR_OPEN; + } buffer = (char *)malloc(load_buffer_length); for (j = 0; password[j] != '\0'; j++) { key[j] = password[j]; } keylength = j; krc2->rc2_expandkey (key, keylength, 128); #ifndef Q_WS_WIN size = read(fileno (fd), (unsigned char *) (charbuf + count), 8); #else size = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); #endif - if (size < 8) + if (size < 8) { + delete krc2; return PWERR_DATA; + } for (count = 0; count < 4; count++) { count2 = count << 1; iv[count] = charbuf[count2] << 8; iv[count] += charbuf[count2 + 1]; } size = 0; bufferIndex = 0; #ifndef Q_WS_WIN while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) { while (count < 8) { count2 = read (fileno (fd), (unsigned char *) (charbuf + count), 8); #else while ((count = fread ((unsigned char *) (charbuf), sizeof(unsigned char), 8, fd)) > 0) { while (count < 8) { count2 = fread ((unsigned char *) (charbuf + count), sizeof(unsigned char), 8, fd); #endif if (count2 == 0) { + delete krc2; return PWERR_DATA; } count += count2; } /* while (count < 8) */ size += 8; for (count2 = 0; count2 < 8; count2 += 2) { count3 = count2 >> 1; ciphertext[count3] = charbuf[count2] << 8; ciphertext[count3] += charbuf[count2 + 1]; plaintext[count3] = ciphertext[count3] ^ iv[count3]; iv[count3] = plaintext[count3]; } /* for (count2) */ krc2->rc2_decrypt (plaintext); memcpy ((unsigned char *) (buffer + bufferIndex), plaintext, 8); bufferIndex += 8; buffer[bufferIndex + 1] = '\0'; } /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */ + delete krc2; size -= buffer[size - 1]; lastcount = 0; /* This will point to the starting index */ bufferIndex = 0; return PWERR_GOOD; } int ZSafe::loadEntry(char *entry[FIELD_SIZE]) { /* Strip off PKCS 5 padding * Should check to make sure it's good here */ int count, count1=0; for (count = lastcount; count < size; count++) { if ((unsigned char) (buffer[count]) == 255) { if (buffer[bufferIndex] == '\0') { bufferIndex++; } entry[count1] = (char *) malloc (count - bufferIndex + 1); memcpy (entry[count1], (unsigned char *) (buffer + bufferIndex), count - bufferIndex); entry[count1][count - bufferIndex] = '\0'; count++; bufferIndex = count; count1++; if (count1 == FIELD_SIZE) { lastcount = count; return 1; } } /* if ((unsigned char) (buffer[count]) == 255) */ } /* for (count = 0; count < size; count++) */ return 2; } int ZSafe::loadFinalize(void) { fclose (fd); if (buffer) free(buffer); return PWERR_GOOD; } bool ZSafe::saveDocument(const char* _filename, bool withPwd, const char* ) { if (filename.isEmpty()) { QMessageBox::critical( 0, tr("ZSafe"), tr("No document defined.\nYou have to create a new document")); return false; } // if (m_password.isEmpty()) // withPwd = true; // the document must be saved with a valid password if (withPwd) { bool pwdOk = FALSE; while (!pwdOk) { getDocPassword(tr("Enter Password")); if (m_password.isEmpty()) { QMessageBox::critical( 0, tr("ZSafe"), tr("Password is empty.\nPlease enter again.")); continue; } QString firstPasswd = m_password; getDocPassword(tr("Reenter Password")); if (m_password.isEmpty()) { QMessageBox::critical( 0, tr("ZSafe"), tr("Password is empty.\nPlease enter again.")); continue; } if (firstPasswd != m_password) { QMessageBox::critical( 0, tr("ZSafe"), tr("Passwords must be identical.\nPlease enter again.")); continue; } pwdOk = TRUE; modified = false; } } else if (modified) { QString fns(_filename); fns = fns.right (fns.length() - fns.findRev ('/') - 1); switch( QMessageBox::information( this, tr("ZSafe"), tr("Do you want to save ") + fns + tr("\nbefore continuing?"), tr("&Save"), tr("&Don't Save"), 0 // Enter == button 0 ) ) { // Escape == button 2 case 0: // Save clicked, Alt-S or Enter pressed. modified = false; break; case 1: // Don't Save clicked or Alt-D pressed modified = false; return true; } } modified = false; if (m_password.isEmpty()) return false; int retval = saveInit(_filename, m_password); // int retval = saveInit(_filename, "test"); if (retval != PWERR_GOOD) { return false; } char* entry[FIELD_SIZE]; // save the validation entry { int i=0; entry[i] = (char*)malloc(strlen("ZSAFECATEGORY")+1); strcpy(entry[i++], "ZSAFECATEGORY"); entry[i] = (char*)malloc(strlen("name")+1); strcpy(entry[i++], "name"); entry[i] = (char*)malloc(strlen("username")+1); strcpy(entry[i++], "username"); entry[i] = (char*)malloc(strlen("password")+1); strcpy(entry[i++], "password"); entry[i] = (char*)malloc(strlen("comment")+1); strcpy(entry[i++], "comment"); entry[i] = (char*)malloc(strlen("field5")+1); strcpy(entry[i++], "field5"); entry[i] = (char*)malloc(strlen("field6")+1); strcpy(entry[i++], "field6"); retval = saveEntry(entry); for (int z=0; z<i; z++) free(entry[z]); if (retval == PWERR_DATA) { #ifndef NO_OPIE owarn << "1: Error writing file, contents not saved" << oendl; #else qWarning("1: Error writing file, contents not saved"); #endif saveFinalize(); return false; } // #ifndef Q_WS_WIN conf->writeEntry(APP_KEY+"valzsafe", 1); // #endif saveConf(); } QListViewItem *i; // step through all categories for (i = ListView->firstChild(); i != NULL; i = i->nextSibling()) { // step through all subitems QListViewItem *si; for (si = i->firstChild(); si != NULL; si = si->nextSibling()) { int j=0; entry[j] = (char*)malloc(strlen(i->text(0).utf8())+1); strcpy(entry[j++], i->text(0).utf8()); entry[j] = (char*)malloc(strlen(si->text(0).utf8())+1); strcpy(entry[j++], si->text(0).utf8()); entry[j] = (char*)malloc(strlen(si->text(1).utf8())+1); strcpy(entry[j++], si->text(1).utf8()); entry[j] = (char*)malloc(strlen(si->text(2).utf8())+1); strcpy(entry[j++], si->text(2).utf8()); entry[j] = (char*)malloc(strlen(si->text(3).utf8())+1); strcpy(entry[j++], si->text(3).utf8()); entry[j] = (char*)malloc(strlen(si->text(4).utf8())+1); strcpy(entry[j++], si->text(4).utf8()); entry[j] = (char*)malloc(strlen(si->text(5).utf8())+1); strcpy(entry[j++], si->text(5).utf8()); retval = saveEntry(entry); for (int z=0; z<j; z++) { free(entry[z]); } if (retval == PWERR_DATA) { #ifndef NO_OPIE owarn << "1: Error writing file, contents not saved" << oendl; #else qWarning("1: Error writing file, contents not saved"); #endif saveFinalize(); return false; } } } if (saveFinalize() == PWERR_DATA) { #ifndef NO_OPIE owarn << "2: Error writing file, contents not saved" << oendl; #else qWarning("2: Error writing file, contents not saved"); #endif return false; } else { #ifndef DESKTOP Global::statusMessage (tr("Password file saved.")); #endif modified = false; return true; } } PasswordForm *newPwdDialog; bool newPwdDialogResult = false; void ZSafe::setPasswordDialogDone() { newPwdDialogResult = true; newPwdDialog->close(); } void ZSafe::getDocPassword(QString title) { // open the 'Password' dialog PasswordForm *dialog = new PasswordForm(this, title, TRUE); newPwdDialog = dialog; newPwdDialogResult = false; // QPixmap image0 = Opie::Core::OResource::loadPixmap( "zsafe/zsafe", Opie::Core::OResource::SmallIcon ); // dialog->setIcon( image0); connect( dialog->PasswordField, SIGNAL( returnPressed() ), this, SLOT( setPasswordDialogDone() ) ); // CS: !!! // int pos = filename.findRev ('/'); QString ti = filename.right (filename.length() - filename.findRev ('/') - 1); dialog->setCaption(ti); // dialog->setCaption(title); dialog->PasswordField->setFocus(); QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); QString password; if (result == QDialog::Accepted || newPwdDialogResult) { m_password = dialog->PasswordField->text(); } else { exitZs (1); } } int ZSafe::saveInit(const char *_filename, const char *password) { char key[128]; unsigned int j = 0; unsigned int keylength; // int val; int count2; Krc2* krc2 = new Krc2(); - /* first we should check the permissions of the filename */ -/* - if (QFile::exists(_filename)) { - val = checkFile(_filename); - if (val != PWERR_GOOD) - return val; - } else - { - val = creat (_filename, (S_IRUSR | S_IWUSR)); - if (val == -1) - return PWERR_OPEN; - else - close(val); - } -*/ QFileInfo f (_filename); save_buffer_length = f.size(); save_buffer_length = ((save_buffer_length / 1024)+1) * 1024; fd = fopen (_filename, "wb"); - if (fd == NULL) + if (fd == NULL) { + delete krc2; return PWERR_OPEN; + } buffer = (char*)malloc(save_buffer_length); /* make the key ready */ for (j = 0; password[j] != '\0'; j++) { key[j] = password[j]; } keylength = j; krc2->rc2_expandkey (key, keylength, 128); + delete krc2; /* First, we make the IV */ for (count2 = 0; count2 < 4; count2++) { iv[count2] = rand (); putc ((unsigned char) (iv[count2] >> 8), fd); putc ((unsigned char) (iv[count2] & 0xff), fd); } bufferIndex = 0; return PWERR_GOOD; } int ZSafe::saveEntry(char *entry[FIELD_SIZE]) { char *text1; int count2, count3; unsigned short ciphertext[4]; Krc2* krc2 = new Krc2(); buffer = (char*)memset(buffer, '\0', save_buffer_length); for (count2 = 0; count2 < FIELD_SIZE; count2++) { text1 = entry[count2]; if (strlen (text1) == 0) { strncat(buffer, " ", strlen(" ")); } else { strncat(buffer, text1, strlen(text1)); } /* Use 255 as the marker. \n is too tough to test for */ buffer[strlen (buffer)] = 255; } /*for (count2 = 0; count2 < 5; count2++)*/ count2 = 0; /* I'm using CBC mode and encrypting the data straight from top down. * At the bottom, encrypted, I will append an MD5 hash of the file, eventually. * PKCS 5 padding (explained at the code section */ while (count2 < (int)strlen (buffer)) { #ifndef WORDS_BIGENDIAN plaintext[bufferIndex] = buffer[count2 + 1] << 8; plaintext[bufferIndex] += buffer[count2] & 0xff; #endif #ifdef WORDS_BIGENDIAN plaintext[bufferIndex] = buffer[count2] << 8; plaintext[bufferIndex] += buffer[count2 + 1] & 0xff; #endif bufferIndex++; if (bufferIndex == 4) { krc2->rc2_encrypt (plaintext); for (count3 = 0; count3 < 4; count3++) { ciphertext[count3] = iv[count3] ^ plaintext[count3]; /* Now store the ciphertext as the iv */ iv[count3] = plaintext[count3]; /* reset the buffer index */ bufferIndex = 0; - if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) return PWERR_DATA; - if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) return PWERR_DATA; + if (putc ((unsigned char) (ciphertext[count3] >> 8), fd) == EOF) { + delete krc2; + return PWERR_DATA; + } + if (putc ((unsigned char) (ciphertext[count3] & 0xff), fd) == EOF) { + delete krc2; + return PWERR_DATA; + } } /*for (count3 = 0; count3 < 5; count3++)*/ } /*if (bufferIndex == 5)*/ /* increment a short, not a byte */ count2 += 2; } /*while (count2 < strlen (buffer))*/ - int ret = PWERR_GOOD; - return ret; + delete krc2; + return PWERR_GOOD; } int ZSafe::saveFinalize(void) { int count1, retval = PWERR_GOOD; unsigned short ciphertext[4]; Krc2* krc2 = new Krc2(); /* Tack on the PKCS 5 padding * How it works is we fill up the last n bytes with the value n * * So, if we have, say, 13 bytes, 8 of which are used, we have 5 left * over, leaving us 3 short, so we fill it in with 3's. * * If we come out even, we fill it with 8 8s * * um, except that in this instance we are using 4 shorts instead of 8 bytes. * so, half everything */ for (count1 = bufferIndex; count1 < 4; count1++) { plaintext[count1] = (4 - bufferIndex); } krc2->rc2_encrypt (plaintext); for (count1 = 0; count1 < 4; count1++) { ciphertext[count1] = iv[count1] ^ plaintext[count1]; if (putc ((unsigned char) (ciphertext[count1] >> 8), fd) == EOF) retval = PWERR_DATA; if (putc ((unsigned char) (ciphertext[count1] & 0xff), fd) == EOF) retval = PWERR_DATA; } fclose (fd); free(buffer); + delete krc2; return retval; } void ZSafe::quitMe () { if (modified) { switch( QMessageBox::information( this, tr("ZSafe"), tr("Do you want to save\nbefore exiting?"), tr("&Save"), tr("S&ave with\nnew\npassword"), tr("&Don't Save"), 0 // Enter == button 0 ) ) { // Escape == button 2 case 0: // Save clicked, Alt-S or Enter pressed. // save modified = false; saveDocument(filename, FALSE); exitZs (1); break; case 1: // // Save with new password modified = false; saveDocument(filename, TRUE); exitZs (1); break; case 2: // Don't Save clicked or Alt-D pressed // don't save but exitZs exitZs (1); break; } } exitZs (1); } void ZSafe::categoryFieldActivated( const QString& category) { if (categoryDialog) setCategoryDialogFields(categoryDialog, category); } void ZSafe::addCategory() { if (filename.isEmpty()) { QMessageBox::critical( 0, tr("ZSafe"), tr("No document defined.\nYou have to create a new document")); return; } else { // open the 'Category' dialog bool initIcons = false; // open the 'Category' dialog CategoryDialog *dialog; if (categoryDialog) { dialog = categoryDialog; } else { categoryDialog = new CategoryDialog(this, tr("Category"), TRUE); dialog = categoryDialog; connect( dialog->CategoryField, SIGNAL( activated(const QString&)), this, SLOT( categoryFieldActivated(const QString&) ) ); initIcons = true; } // read all categories from the config file and store // into a list QFile f (cfgFile); QStringList list; if ( f.open(IO_ReadOnly) ) { // file opened successfully QTextStream t( &f ); // use a text stream QString s; while ( !t.eof() ) { // until end of file... s = t.readLine(); // line of text excluding '\n' list.append(s); } f.close(); } QStringList::Iterator it = list.begin(); QString categ; QString firstCategory; dialog->CategoryField->clear(); // remove all items while( it != list.end() ) { QString *cat = new QString (*it); if (cat->contains("-field1", FALSE)) { int pos = cat->find ("-field1"); cat->truncate(pos); categ = *cat; if (!categ.isEmpty()) { dialog->CategoryField->insertItem (categ, -1); if (firstCategory.isEmpty()) firstCategory = categ; } } ++it; } if (firstCategory.isEmpty()) setCategoryDialogFields(dialog); else setCategoryDialogFields(dialog, firstCategory); // CategoryDialog *dialog = new CategoryDialog(this, "Category", TRUE); if (initIcons) { Wait waitDialog(this, tr("Wait dialog")); waitDialog.waitLabel->setText(tr("Gathering icons...")); waitDialog.show(); qApp->processEvents(); QDir d(QPEApplication::qpeDir() + "pics/"); d.setFilter( QDir::Files); const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it( *list ); // create list iterator QFileInfo *fi; // pointer for traversing dialog->IconField->insertItem("predefined"); while ( (fi=it.current()) ) { // for each file... QString fileName = fi->fileName(); if(fileName.right(4) == ".png"){ fileName = fileName.mid(0,fileName.length()-4); QPixmap imageOfFile(Opie::Core::OResource::loadPixmap(fileName,Opie::Core::OResource::SmallIcon)); dialog->IconField->insertItem(imageOfFile,fileName); } ++it; } waitDialog.hide(); } QDialog::DialogCode result = (QDialog::DialogCode) dialog->exec(); QString category; QString icon; QString fullIconPath; QPixmap *pix; if (result == QDialog::Accepted) { modified = true; category = dialog->CategoryField->currentText(); icon = dialog->IconField->currentText()+".png"; QListViewItem *li = new ShadedListItem( 1, ListView ); Category *c1 = new Category(); c1->setCategoryName(category); // if (!icon.isEmpty() && !icon.isNull()) if (icon != "predefined.png") { // build the full path fullIconPath = iconPath + icon; pix = new QPixmap (fullIconPath); // pix->resize(14, 14); if (!pix->isNull()) { // save the full pixmap name into the config file // #ifndef Q_WS_WIN conf->writeEntry(APP_KEY+category, icon); // #endif saveConf(); QImage img = pix->convertToImage(); pix->convertFromImage(img.smoothScale(14,14)); c1->setIcon (*pix); c1->setIconName(icon); } else { QPixmap folder( ( const char** ) general_data ); c1->setIcon (folder); } } else { c1->setIcon (*getPredefinedIcon(category)); } c1->setListItem (li); c1->initListItem(); categories.insert (c1->getCategoryName(), c1); saveCategoryDialogFields(dialog); } else { // delete dialog; dialog->hide(); return; } } } void ZSafe::delCategory() { if (!selectedItem) return; if (isCategory(selectedItem)) { switch( QMessageBox::information( this, tr("ZSafe"), tr("Do you want to delete?"), tr("&Delete"), tr("D&on't Delete"), 0 // Enter == button 0 ) ) { // Escape == button 2 case 0: // Delete clicked, Alt-S or Enter pressed. // Delete from the category list modified = true; categories.remove (selectedItem->text(0)); // #ifndef Q_WS_WIN conf->removeEntry (selectedItem->text(0)); // #endif saveConf(); // Delete the selected item and all subitems // step through all subitems QListViewItem *si; for (si = selectedItem->firstChild(); si != NULL; ) { QListViewItem *_si = si; si = si->nextSibling(); selectedItem->takeItem(_si); // remove from view list if (_si) delete _si; } ListView->takeItem(selectedItem); delete selectedItem; selectedItem = NULL; break; case 1: // Don't delete break; } } } void ZSafe::setCategoryDialogFields(CategoryDialog *dialog) { if (!dialog) return; QString icon; if (selectedItem) { dialog->Field1->setText(getFieldLabel (selectedItem, "1", tr("Name"))); dialog->Field2->setText(getFieldLabel (selectedItem, "2", tr("Username"))); dialog->Field3->setText(getFieldLabel (selectedItem, "3", tr("Password"))); dialog->Field4->setText(getFieldLabel (selectedItem, "4", tr("Comment"))); dialog->Field5->setText(getFieldLabel (selectedItem, "5", tr("Field 4"))); dialog->Field6->setText(getFieldLabel (selectedItem, "6", tr("Field 5"))); Category *cat= categories.find (selectedItem->text(0)); if (cat) { icon = cat->getIconName(); } else icon = conf->readEntry(APP_KEY+selectedItem->text(0)); } else { dialog->Field1->setText(tr("Name")); dialog->Field2->setText(tr("Username")); dialog->Field3->setText(tr("Password")); dialog->Field4->setText(tr("Comment")); dialog->Field5->setText(tr("Field 4")); dialog->Field6->setText(tr("Field 5")); } QDir d(QPEApplication::qpeDir() + "pics/"); d.setFilter( QDir::Files); const QFileInfoList *list = d.entryInfoList(); int i=0; QFileInfoListIterator it( *list ); // create list iterator QFileInfo *fi; // pointer for traversing if (icon.isEmpty() || icon.isNull()) { dialog->IconField->setCurrentItem(0); } else { while ( (fi=it.current()) ) { // for each file... QString fileName = fi->fileName(); if(fileName.right(4) == ".png") { fileName = fileName.mid(0,fileName.length()-4); if(fileName+".png"==icon) { dialog->IconField->setCurrentItem(i+1); break; } ++i; } ++it; } } } void ZSafe::setCategoryDialogFields(CategoryDialog *dialog, QString category) { if (!dialog) return; dialog->Field1->setText(getFieldLabel (category, "1", tr("Name"))); dialog->Field2->setText(getFieldLabel (category, "2", tr("Username"))); dialog->Field3->setText(getFieldLabel (category, "3", tr("Password"))); dialog->Field4->setText(getFieldLabel (category, "4", tr("Comment"))); dialog->Field5->setText(getFieldLabel (category, "5", tr("Field 4"))); dialog->Field6->setText(getFieldLabel (category, "6", tr("Field 5"))); QString icon; Category *cat= categories.find (category); if (cat) { icon = cat->getIconName(); } else icon = conf->readEntry(APP_KEY+category); QDir d(QPEApplication::qpeDir() + "pics/"); d.setFilter( QDir::Files); const QFileInfoList *list = d.entryInfoList(); int i=0; QFileInfoListIterator it( *list ); // create list iterator QFileInfo *fi; // pointer for traversing if (icon.isEmpty() || icon.isNull()) { dialog->IconField->setCurrentItem(0); } else { while ( (fi=it.current()) ) { // for each file... QString fileName = fi->fileName(); if(fileName.right(4) == ".png") { fileName = fileName.mid(0,fileName.length()-4); if(fileName+".png"==icon) { dialog->IconField->setCurrentItem(i+1); break; } ++i; } ++it; } } } void ZSafe::saveCategoryDialogFields(CategoryDialog *dialog) { QString app_key = APP_KEY; conf->setGroup( "fieldDefs" ); QString category = dialog->CategoryField->currentText(); // #ifndef Q_WS_WIN conf->writeEntry(app_key+category+"-field1", dialog->Field1->text()); conf->writeEntry(app_key+category+"-field2", dialog->Field2->text()); conf->writeEntry(app_key+category+"-field3", dialog->Field3->text()); conf->writeEntry(app_key+category+"-field4", dialog->Field4->text()); conf->writeEntry(app_key+category+"-field5", dialog->Field5->text()); conf->writeEntry(app_key+category+"-field6", dialog->Field6->text()); // #endif saveConf(); conf->setGroup ("zsafe"); } void ZSafe::editCategory() { 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 @@ /* * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ /* * vncauth.c - Functions for VNC password management and authentication. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <time.h> #include "vncauth.h" #include "d3des.h" /* * We use a fixed key to store passwords, since we assume that our local * file system is secure but nonetheless don't want to store passwords * as plaintext. */ unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; /* * Encrypt a password and store it in a file. Returns 0 if successful, * 1 if the file could not be written. */ int vncEncryptAndStorePasswd(char *passwd, char *fname) { FILE *fp; uint i; unsigned char encryptedPasswd[8]; if ((fp = fopen(fname,"w")) == NULL) return 1; chmod(fname, S_IRUSR|S_IWUSR); /* pad password with nulls */ for (i = 0; i < 8; i++) { if (i < strlen(passwd)) { encryptedPasswd[i] = passwd[i]; } else { encryptedPasswd[i] = 0; } } /* Do encryption in-place - this way we overwrite our copy of the plaintext password */ deskey(fixedkey, EN0); des(encryptedPasswd, encryptedPasswd); for (i = 0; i < 8; i++) { putc(encryptedPasswd[i], fp); } fclose(fp); return 0; } /* * Decrypt a password from a file. Returns a pointer to a newly allocated * string containing the password or a null pointer if the password could * not be retrieved for some reason. */ char * vncDecryptPasswdFromFile(char *fname) { FILE *fp; int i, ch; unsigned char *passwd = (unsigned char *)malloc(9); - if ((fp = fopen(fname,"r")) == NULL) return NULL; + if ((fp = fopen(fname,"r")) == NULL) { + free(passwd); + return NULL; + } for (i = 0; i < 8; i++) { ch = getc(fp); if (ch == EOF) { fclose(fp); + free(passwd); return NULL; } passwd[i] = ch; } deskey(fixedkey, DE1); des(passwd, passwd); passwd[8] = 0; return (char *)passwd; } /* * Generate CHALLENGESIZE random bytes for use in challenge-response * authentication. */ void vncRandomBytes(unsigned char *bytes) { int i; unsigned int seed = (unsigned int) time(0); srandom(seed); for (i = 0; i < CHALLENGESIZE; i++) { bytes[i] = (unsigned char)(random() & 255); } } /* * Encrypt CHALLENGESIZE bytes in memory using a password. */ void vncEncryptBytes(unsigned char *bytes, char *passwd) { unsigned char key[8]; int i; /* key is simply password padded with nulls */ for (i = 0; i < 8; i++) { if (i < strlen(passwd)) { key[i] = passwd[i]; } else { key[i] = 0; } } deskey(key, EN0); for (i = 0; i < CHALLENGESIZE; i += 8) { des(bytes+i, bytes+i); } } 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) printf("<<<<<<<<<<<<<<<<%d\n",ACCEPT_TIMEOUT); i = nControl->handle; if (i < nData->handle) i = nData->handle; i = select(i+1, &mask, NULL, NULL, &tv); if (i == -1) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); net_close(nData->handle); nData->handle = 0; rv = 0; } else if (i == 0) { strcpy(nControl->response, "timed out waiting for connection"); net_close(nData->handle); nData->handle = 0; rv = 0; } else { if (FD_ISSET(nData->handle, &mask)) { l = sizeof(addr); sData = accept(nData->handle, &addr, &l); i = errno; net_close(nData->handle); if (sData > 0) { rv = 1; nData->handle = sData; } else { strncpy(nControl->response, strerror(i), sizeof(nControl->response)); nData->handle = 0; rv = 0; } } else if (FD_ISSET(nControl->handle, &mask)) { net_close(nData->handle); nData->handle = 0; readresp('2', nControl); rv = 0; } } return rv; } /* * FtpAccess - return a handle for a data stream * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, netbuf **nData) { char buf[256]; int dir; if ((path == NULL) && ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) { sprintf(nControl->response, "Missing path argument for file transfer\n"); return 0; } sprintf(buf, "TYPE %c", mode); if (!FtpSendCmd(buf, '2', nControl)) return 0; switch (typ) { case FTPLIB_DIR: strcpy(buf,"NLST"); dir = FTPLIB_READ; break; case FTPLIB_DIR_VERBOSE: strcpy(buf,"LIST"); dir = FTPLIB_READ; break; case FTPLIB_FILE_READ: strcpy(buf,"RETR"); dir = FTPLIB_READ; break; case FTPLIB_FILE_WRITE: strcpy(buf,"STOR"); dir = FTPLIB_WRITE; break; default: sprintf(nControl->response, "Invalid open type %d\n", typ); return 0; } if (path != NULL) { int i = strlen(buf); buf[i++] = ' '; if ((strlen(path) + i) >= sizeof(buf)) return 0; strcpy(&buf[i],path); } if (FtpOpenPort(nControl, nData, mode, dir) == -1) return 0; if (!FtpSendCmd(buf, '1', nControl)) { FtpClose(*nData); *nData = NULL; return 0; } (*nData)->ctrl = nControl; nControl->data = *nData; if (nControl->cmode == FTPLIB_PORT) { if (!FtpAcceptConnection(*nData,nControl)) { FtpClose(*nData); *nData = NULL; nControl->data = NULL; return 0; } } return 1; } /* * FtpRead - read from a data connection */ GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) { int i; if (nData->dir != FTPLIB_READ) return 0; if (nData->buf) i = readline(buf, max, nData); else { i = socket_wait(nData); if (i != 1) return 0; i = net_read(nData->handle, buf, max); } if (i == -1) return 0; nData->xfered += i; if (nData->idlecb && nData->cbbytes) { nData->xfered1 += i; if (nData->xfered1 > nData->cbbytes) { if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) return 0; nData->xfered1 = 0; } } return i; } /* * FtpWrite - write to a data connection */ GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) { int i; if (nData->dir != FTPLIB_WRITE) return 0; if (nData->buf) i = writeline(buf, len, nData); else { if (socket_wait(nData) < 0) fprintf(stderr, "FtpWrite: socket_wait failed with %s\n", nData->ctrl->response); i = net_write(nData->handle, buf, len); } if (i == -1) return 0; nData->xfered += i; if (nData->idlecb && nData->cbbytes) { nData->xfered1 += i; if (nData->xfered1 > nData->cbbytes) { nData->idlecb(nData, nData->xfered, nData->idlearg); nData->xfered1 = 0; } } return i; } /* * FtpClose - close a data connection */ GLOBALDEF int FtpClose(netbuf *nData) { netbuf *ctrl; switch (nData->dir) { case FTPLIB_WRITE: /* potential problem - if buffer flush fails, how to notify user? */ if (nData->buf != NULL) writeline(NULL, 0, nData); case FTPLIB_READ: if (nData->buf) free(nData->buf); shutdown(nData->handle,2); net_close(nData->handle); ctrl = nData->ctrl; free(nData); if (ctrl) { ctrl->data = NULL; return(readresp('2', ctrl)); } return 1; case FTPLIB_CONTROL: if (nData->data) { nData->ctrl = NULL; FtpClose(nData); } net_close(nData->handle); free(nData); return 0; } return 1; } /* * FtpSite - send a SITE command * * return 1 if command successful, 0 otherwise */ GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) { char buf[256]; if ((strlen(cmd) + 7) > sizeof(buf)) return 0; sprintf(buf,"SITE %s",cmd); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1; } /* * FtpSysType - send a SYST command * * Fills in the user buffer with the remote system type. If more * information from the response is required, the user can parse * it out of the response buffer returned by FtpLastResponse(). * * return 1 if command successful, 0 otherwise */ GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) { int l = max; char *b = buf; char *s; if (!FtpSendCmd("SYST",'2',nControl)) return 0; s = &nControl->response[4]; while ((--l) && (*s != ' ')) *b++ = *s++; *b++ = '\0'; return 1; } /* * FtpMkdir - create a directory at server * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) { char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"MKD %s",path); if (!FtpSendCmd(buf,'2', nControl)) return 0; return 1; } /* * FtpChdir - change path at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) { char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"CWD %s",path); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1; } /* * FtpCDUp - move to parent directory at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpCDUp(netbuf *nControl) { if (!FtpSendCmd("CDUP",'2',nControl)) return 0; return 1; } /* * FtpRmdir - remove directory at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) { char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"RMD %s",path); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1; } /* * FtpPwd - get working directory at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) { int l = max; char *b = path; char *s; if (!FtpSendCmd("PWD",'2',nControl)) return 0; s = strchr(nControl->response, '"'); if (s == NULL) return 0; s++; while ((--l) && (*s) && (*s != '"')) *b++ = *s++; *b++ = '\0'; return 1; } /* * FtpXfer - issue a command and transfer data * * return 1 if successful, 0 otherwise */ static int FtpXfer(const char *localfile, const char *path, netbuf *nControl, int typ, int mode) { int l,c; char *dbuf; FILE *local = NULL; netbuf *nData; int rv=1; if (localfile != NULL) { char ac[4] = "w"; if (typ == FTPLIB_FILE_WRITE) ac[0] = 'r'; if (mode == FTPLIB_IMAGE) ac[1] = 'b'; local = fopen(localfile, ac); if (local == NULL) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); return 0; } } if (local == NULL) local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; if (!FtpAccess(path, typ, mode, nControl, &nData)) + { + if (localfile != NULL) + fclose(local); return 0; + } dbuf = malloc(FTPLIB_BUFSIZ); if (typ == FTPLIB_FILE_WRITE) { while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) if ((c = FtpWrite(dbuf, l, nData)) < l) { printf("short write: passed %d, wrote %d\n", l, c); rv = 0; break; } } else { while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) if (fwrite(dbuf, 1, l, local) <= 0) { perror("localfile write"); rv = 0; break; } } free(dbuf); fflush(local); if (localfile != NULL) fclose(local); FtpClose(nData); return rv; } /* * FtpNlst - issue an NLST command and write response to output * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpNlst(const char *outputfile, const char *path, netbuf *nControl) { return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII); } /* * FtpDir - issue a LIST command and write response to output * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) { return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII); } /* * FtpSize - determine the size of a remote file * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) { char cmd[256]; int resp,sz,rv=1; if ((strlen(path) + 7) > sizeof(cmd)) return 0; sprintf(cmd, "TYPE %c", mode); if (!FtpSendCmd(cmd, '2', nControl)) return 0; sprintf(cmd,"SIZE %s",path); if (!FtpSendCmd(cmd,'2',nControl)) rv = 0; else { if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) *size = sz; else rv = 0; } return rv; } /* * FtpModDate - determine the modification date of a remote file * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) { char buf[256]; int rv = 1; if ((strlen(path) + 7) > sizeof(buf)) return 0; sprintf(buf,"MDTM %s",path); if (!FtpSendCmd(buf,'2',nControl)) rv = 0; else strncpy(dt, &nControl->response[4], max); return rv; } /* * FtpGet - issue a GET command and write received data to output * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpGet(const char *outputfile, const char *path, char mode, netbuf *nControl) { return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode); } /* * FtpPut - issue a PUT command and send data from input * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, netbuf *nControl) { return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode); } /* * FtpRename - rename a file at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) { char cmd[256]; if (((strlen(src) + 7) > sizeof(cmd)) || ((strlen(dst) + 7) > sizeof(cmd))) return 0; sprintf(cmd,"RNFR %s",src); if (!FtpSendCmd(cmd,'3',nControl)) return 0; sprintf(cmd,"RNTO %s",dst); if (!FtpSendCmd(cmd,'2',nControl)) return 0; return 1; } /* * FtpDelete - delete a file at remote * * return 1 if successful, 0 otherwise */ GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) { char cmd[256]; if ((strlen(fnm) + 7) > sizeof(cmd)) return 0; sprintf(cmd,"DELE %s",fnm); if (!FtpSendCmd(cmd,'2', nControl)) return 0; return 1; } /* * FtpQuit - disconnect from remote * * return 1 if successful, 0 otherwise */ GLOBALDEF void FtpQuit(netbuf *nControl) { if (nControl->dir != FTPLIB_CONTROL) return; if (FtpSendCmd("QUIT",'2',nControl) == 1) { if (ftplib_debug > 2) fprintf(stderr, "FtpQuit: FtpSendCmd(QUIT) failed\n"); } net_close(nControl->handle); free(nControl->buf); free(nControl); } 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 @@ /* libstocks - Library to get current stock quotes from Yahoo Finance * * Copyright (C) 2000 Eric Laeuffer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #define __CSV_C__ #ifndef __UNIX__ #define __UNIX__ #endif #include <string.h> #include <stdlib.h> #include <stdio.h> #ifdef __WINDOWS__ #include <mbstring.h> #endif #include "csv.h" #include "stocks.h" #include "lists.h" #define DATE_LENGTH 7 /*YYMMDD*/ const char *months[12]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; /*****************************************************************************/ /* Replacement of the strtok function. This one forgets "delim" when it is */ /* between two commas. */ /* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */ /*****************************************************************************/ char *csv_strtok(char *s, char *delim) { static char *next=NULL; char *temp, *first; int comma=0; if (s!=NULL) first=s; else first=next; temp=first; if (*temp=='\0') return NULL; while (*temp!='\0' && ((*temp!=*delim) || comma)) { if (*temp=='"') comma ^= 1; temp++; } if (*temp=='\0') next=temp; else { *temp='\0'; next=temp+1; } return first; } /*****************************************************************************/ /* Parses the csv file and return a list of stocks structure. */ /* *csv points on the csv file in memory */ /* count defines the country, because csv depends on the country */ /*****************************************************************************/ stock *parse_csv_file(char *csv) { char *line; char *end_line; char *ptr; char *date; char *time; char *name; char *symbol; stock *StockPtr=NULL; stock *LastStockPtr=NULL; /* Used to return the pointer to the list */ stock *FirstStockPtr=NULL; /* used to see if symbol is valid */ int valid; char *test; line = csv; end_line = csv; while ((end_line = strstr(line, "\n"))) { *end_line = 0; /* Check if symbol valid */ /* if 1 "N/A" then ok because Indices have N/A for volume */ /* if 4 "N/A" then ok because Mutual funds have */ /* if 5 "N/A" then ok because currencies have */ /* So if >5 then stock not valid */ test = line; valid = 0; while ( (test = strstr(test, "N/A")) ) { valid ++; test = test +3; } if (valid < 6) { /* This Symbol is valid */ StockPtr = malloc_stock(); ptr = csv_strtok(line, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } symbol = (char *)malloc(strlen(ptr)+1); if (symbol==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy((char *)(symbol), ptr); StockPtr->Symbol = symbol; ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } name = (char *)malloc(strlen(ptr)+1); if (name==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy((char *)(name), ptr); StockPtr->Name = name; ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->CurrentPrice)); ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } date = (char *)malloc(strlen(ptr)+1); if (date==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy((char *)(date), ptr); StockPtr->Date = date; ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } time = (char *)malloc(strlen(ptr)+1); if (time==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy((char *)(time), ptr); StockPtr->Time = time; ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->Variation)); StockPtr->Pourcentage = 100 * StockPtr->Variation / (StockPtr->CurrentPrice - StockPtr->Variation); StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation; ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->OpenPrice)); ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->MaxPrice)); ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->MinPrice)); ptr = csv_strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } StockPtr->Volume = atoi(ptr); if( !FirstStockPtr ) { FirstStockPtr = StockPtr; StockPtr->PreviousStock = 0; } StockPtr->NextStock = 0; if (LastStockPtr) { LastStockPtr->NextStock = StockPtr; StockPtr->PreviousStock = LastStockPtr; } LastStockPtr = StockPtr; } else { /* this symbol is not valid */ /* Set the stock struct just with Symbol, all other are NULL */ /* This can be used to see if the symbol has been reached are not */ StockPtr = malloc_stock(); ptr = csv_strtok(line, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + return 0; + } symbol = (char *)malloc(strlen(ptr)+1); if (symbol==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy((char *)(symbol), ptr); StockPtr->Symbol = symbol; if( !FirstStockPtr ) { FirstStockPtr = StockPtr; StockPtr->PreviousStock = 0; } StockPtr->NextStock = 0; if (LastStockPtr) { LastStockPtr->NextStock = StockPtr; StockPtr->PreviousStock = LastStockPtr; } LastStockPtr = StockPtr; } end_line++; line = end_line; } return (FirstStockPtr); } /*****************************************************************************/ /* Parses the history quotes file and return a stock structure list. */ /*****************************************************************************/ stock *parse_csv_history_file(char *csv_file) { char *line; char *end_line; char *ptr; int day; char smonth[10]; int month; int year; char *date; int i; int test; stock *StockPtr=NULL; stock *LastStockPtr=NULL; /* Used to return the pointer to the list */ stock *FirstStockPtr=NULL; line = csv_file; end_line = csv_file; /* do not use the first line */ if (!(end_line = strstr(line, "\n"))) return 0; *end_line = 0; end_line++; line = end_line; while ((end_line = strstr(line, "\n"))) { *end_line = 0; StockPtr = malloc_stock(); /* Date */ ptr = strtok(line, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + free_stock(FirstStockPtr); + free_stock(LastStockPtr); + return 0; + } sscanf(ptr,"%d-%3s-%d",&day,smonth,&year); i=0; #ifdef __UNIX__ while((test=strcasecmp(months[i], smonth))) i++; #elif __WINDOWS__ while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++; #endif month = i+1; date = (char *)malloc(DATE_LENGTH); if (date==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } sprintf(date,"%.2d%.2d%.2d", year, month, day); StockPtr->Date = date; /* Open */ ptr = strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + free_stock(FirstStockPtr); + free_stock(LastStockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->OpenPrice)); /* High */ ptr = strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + free_stock(FirstStockPtr); + free_stock(LastStockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->MaxPrice)); /* Low */ ptr = strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + free_stock(FirstStockPtr); + free_stock(LastStockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->MinPrice)); /* Close */ ptr = strtok(NULL, ","); - if (!ptr) return 0; + if (!ptr) + { + free_stock(StockPtr); + free_stock(FirstStockPtr); + free_stock(LastStockPtr); + return 0; + } sscanf(ptr,"%f",&(StockPtr->LastPrice)); /* Volume */ ptr = strtok(NULL, ","); if (!ptr) /* It seems to be an indice */ /* No volume for indices */ StockPtr->Volume = 0; else StockPtr->Volume = atoi(ptr); if( !FirstStockPtr ) { FirstStockPtr = StockPtr; StockPtr->PreviousStock = 0; } StockPtr->NextStock = 0; if (LastStockPtr) { LastStockPtr->NextStock = StockPtr; StockPtr->PreviousStock = LastStockPtr; } LastStockPtr = StockPtr; end_line++; line = end_line; } return (FirstStockPtr); } 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 @@ /* libstocks - Library to get current stock quotes from Yahoo Finance * * Copyright (C) 2000 Eric Laeuffer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #define __CURRENCY_C__ #include <stdio.h> #include <string.h> #include <malloc.h> #include <stdlib.h> #include "stocks.h" /*****************************************************************************/ /* returns the currency exchange rate of "from" currency into */ /* "into" currency. */ /*****************************************************************************/ libstocks_return_code get_currency_exchange(char *from, char *into, float *exchange) { char *symbol; stock *data; libstocks_return_code error; if((symbol = (char *)malloc(strlen(from)+strlen(into)+3))==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy(symbol, from); strcat(symbol, into); strcat(symbol, "=X"); error = get_stocks(symbol, &data); + free(symbol); if (error) { *exchange = 0; return(error); } free_stocks(data); *exchange = data->CurrentPrice; return(error); } 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 @@ /* libstocks - Library to get current stock quotes from Yahoo Finance * * Copyright (C) 2000 Eric Laeuffer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __LISTS_H__ #define __LISTS_H__ #ifndef __LISTS_C__ #define PUBEXT_LISTS extern #else #define PUBEXT_LISTS #endif #include "stocks.h" PUBEXT_LISTS stock *malloc_stock(void); +PUBEXT_LISTS void free_stock(stock*); #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 @@ /* libstocks - Library to get current stock quotes from Yahoo Finance * * Copyright (C) 2000 Eric Laeuffer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #define __STOCKS_C__ #include <stdio.h> #include <string.h> #include <malloc.h> #include <stdlib.h> #ifdef __WINDOWS__ #include <mbstring.h> #endif #include "http.h" #include "csv.h" #include "stocks.h" /* s = symbol n = name l1 = last trade d1 = date t1 = time c1 = variation o = open h = higher price g = lower price v = volume */ const char yahoo_us_stocks_server[]="finance.yahoo.com"; const char yahoo_eu_stocks_server[]="finance.yahoo.com"; //const char yahoo_eu_stocks_server[]="fr.finance.yahoo.com"; const char yahoo_url_beg[]="/d/quotes.csv?s="; const char yahoo_url_end[]="&f=snl1d1t1c1ohgv&e=.csv"; typedef enum { YAHOO_EUROPE, YAHOO_US } yahoo_source; #define YAHOO_US_EXT_NB 11 const char *yahoo_us_ext[YAHOO_US_EXT_NB] = { ".US", /* United States */ ".TO", /* Canada */ ".M", /* Canada */ ".V", /* Canada */ ".AL", /* Canada */ ".MX", /* Mexico */ ".SA", /* Brasil */ ".BA", /* Argentina */ ".CR", /* Venezuela */ ".SN", /* Chili */ ".AX" /* Australia */ }; /*****************************************************************************/ /* Finds, according to the symbol extension, the http source of the quotes. */ /* Actually just finance.yahoo.com and fr.finance.yahoo.com are supported. */ /* The function returns the country source (US or EUROPE). */ /*****************************************************************************/ yahoo_source find_yahoo_source(char *symbol) { char *ptr; int i; int test; ptr = strrchr(symbol, '.'); /* If no extension we suppose it is a US stock */ if (!ptr) return YAHOO_US; /* extension is found */ /* Test if it is canadian stock */ for (i=0; i<YAHOO_US_EXT_NB; i++) { #ifdef __UNIX__ test = strcasecmp(yahoo_us_ext[i], ptr); #elif __WINDOWS__ test = _mbsnbicmp(yahoo_us_ext[i], ptr, strlen(yahoo_us_ext[i])); #endif if (!test) return YAHOO_US; } /* We suppose now it is a European stock */ return YAHOO_EUROPE; } /*****************************************************************************/ /* Gets quotes csv file, parses the file and create the quotes list */ /* *stocks points to the stocks to fetch */ /* *stock_datas points to the beginning of the list */ /* count allows to connect to all country servers */ /*****************************************************************************/ libstocks_return_code download_stocks(char *stocks, stock **stock_datas, yahoo_source source) { char *stocks_server=NULL; char *url_beg=NULL; char *url_end=NULL; char *url; char *data; libstocks_return_code error; #ifdef DEBUG printf("*download_stocks\n"); #endif switch (source) { case YAHOO_US: stocks_server = (char *)yahoo_us_stocks_server; break; case YAHOO_EUROPE: stocks_server = (char *)yahoo_eu_stocks_server; break; default: stocks_server = (char *)yahoo_us_stocks_server; break; } url_beg = (char *)yahoo_url_beg; url_end = (char *)yahoo_url_end; url = (char *)malloc(strlen(url_beg) +strlen(url_end) +strlen(stocks)+1); if (url==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy(url, url_beg); strcat(url, stocks); strcat(url, url_end); error=http_get(url, stocks_server, &data); free(url); if (error) return error; *stock_datas = parse_csv_file(data); free(data); if (!(*stock_datas)) return ERRPCSV; return 0; } /*****************************************************************************/ /* Gets quotes from yahoo */ /* Choses to fetch European or US depending on the symbol extension */ /* and merges the two lists to one */ /* *stocks points to the stocks to fetch */ /* *stock_datas points to the beginning of the list */ /*****************************************************************************/ libstocks_return_code get_stocks(const char *stocks, stock **stock_datas) { char *tok_ptr; char *eu_quotes=NULL; char *eu_quotes_temp=NULL; int lgr_eu_quotes=0; char *us_quotes=NULL; char *us_quotes_temp=NULL; int lgr_us_quotes=0; char *symbol; yahoo_source source; int lgr_symbol=0; libstocks_return_code error; stock *stocks_tmp=NULL; stock *stocks_tmp2=NULL; stock *stocks_getted=NULL; stock *last_stock=NULL; #ifdef DEBUG printf("*get_stocks\n"); #endif /* to preserve stocks */ tok_ptr = malloc(strlen(stocks)+1); if(tok_ptr==NULL) { fprintf(stderr,"Memory allocating error (%s line %d)\n" ,__FILE__, __LINE__); exit(1); } strcpy(tok_ptr, stocks); while( (symbol = strtok(tok_ptr, "+"))!=0) { /* clear tok_ptr for next strtok */ tok_ptr = NULL; /* look for "." in the symbol */ source = find_yahoo_source(symbol); switch (source) { case YAHOO_US: - if (us_quotes) { lgr_us_quotes = strlen(us_quotes); lgr_symbol = strlen(symbol); us_quotes_temp = malloc(lgr_us_quotes + lgr_symbol +2); if(us_quotes_temp==NULL) { - fprintf(stderr,"Memory allocating error (%s line %d)\n" - ,__FILE__, __LINE__); + fprintf(stderr,"Memory allocating error (%s line %d)\n", + __FILE__, __LINE__); exit(1); } strcpy(us_quotes_temp, us_quotes); strcat(us_quotes_temp,"+"); strcat(us_quotes_temp,symbol); free(us_quotes); us_quotes = us_quotes_temp; } else { us_quotes = malloc(strlen(symbol)+1); if(us_quotes==NULL) { - fprintf(stderr,"Memory allocating error (%s line %d)\n" - ,__FILE__, __LINE__); + fprintf(stderr,"Memory allocating error (%s line %d)\n", + __FILE__, __LINE__); exit(1); } strcpy(us_quotes, symbol); } break; case YAHOO_EUROPE: - if (eu_quotes) { lgr_eu_quotes = strlen(eu_quotes); lgr_symbol = strlen(symbol); eu_quotes_temp = malloc(lgr_eu_quotes + lgr_symbol +2); if(eu_quotes_temp==NULL) { - fprintf(stderr,"Memory allocating error (%s line %d)\n" - ,__FILE__, __LINE__); + fprintf(stderr,"Memory allocating error (%s line %d)\n", + __FILE__, __LINE__); exit(1); } strcpy(eu_quotes_temp, eu_quotes); strcat(eu_quotes_temp, "+"); strcat(eu_quotes_temp, symbol); free(eu_quotes); eu_quotes = eu_quotes_temp; } else { eu_quotes = malloc(strlen(symbol)+1); if(eu_quotes==NULL) { - fprintf(stderr,"Memory allocating error (%s line %d)\n" - ,__FILE__, __LINE__); + fprintf(stderr,"Memory allocating error (%s line %d)\n", + __FILE__, __LINE__); exit(1); } strcpy(eu_quotes, symbol); } break; } } free(tok_ptr); if (us_quotes) { /* Gets us quotes */ error = download_stocks(us_quotes, &stocks_tmp, YAHOO_US); + free(us_quotes); if (error) return error; } if (eu_quotes) { /* Gets european quotes */ error = download_stocks(eu_quotes, &stocks_getted, YAHOO_EUROPE); + free(eu_quotes); if (error) return error; /* concats lists if needed */ if (stocks_tmp) { stocks_tmp2 = stocks_tmp; while(stocks_tmp2 != NULL) { last_stock = stocks_tmp2; stocks_tmp2 = next_stock(stocks_tmp2); } last_stock->NextStock = stocks_getted; stocks_getted->PreviousStock = last_stock; } - else (stocks_tmp = stocks_getted); + else + (stocks_tmp = stocks_getted); } *stock_datas = stocks_tmp; return(0); } 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 @@ /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- * * librsync -- library for network deltas * $Id$ * * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* | Let's climb to the TOP of that | MOUNTAIN and think about STRIP | MINING!! */ /* * delta.c -- Generate in streaming mode an rsync delta given a set of * signatures, and a new file. * * The size of blocks for signature generation is determined by the * block size in the incoming signature. * * To calculate a signature, we need to be able to see at least one * block of the new file at a time. Once we have that, we calculate * its weak signature, and see if there is any block in the signature * hash table that has the same weak sum. If there is one, then we * also compute the strong sum of the new block, and cross check that. * If they're the same, then we can assume we have a match. * * The final block of the file has to be handled a little differently, * because it may be a short match. Short blocks in the signature * don't include their length -- we just allow for the final short * block of the file to match any block in the signature, and if they * have the same checksum we assume they must have the same length. * Therefore, when we emit a COPY command, we have to send it with a * length that is the same as the block matched, and not the block * length from the signature. */ /* * Profiling results as of v1.26, 2001-03-18: * * If everything matches, then we spend almost all our time in * rs_mdfour64 and rs_weak_sum, which is unavoidable and therefore a * good profile. * * If nothing matches, it is not so good. */ #include <config_rsync.h> #include <assert.h> #include <stdlib.h> #include <stdio.h> #include "rsync.h" #include "emit.h" #include "stream.h" #include "util.h" #include "sumset.h" #include "job.h" #include "trace.h" #include "checksum.h" #include "search.h" #include "types.h" /** * Turn this on to make all rolling checksums be checked from scratch. */ int rs_roll_paranoia = 0; static rs_result rs_delta_scan(rs_job_t *, rs_long_t avail_len, void *); static rs_result rs_delta_s_deferred_copy(rs_job_t *job); static rs_result rs_delta_s_end(rs_job_t *job) { rs_emit_end_cmd(job); return RS_DONE; } /** * \brief Get a block of data if possible, and see if it matches. * * On each call, we try to process all of the input data available on * the scoop and input buffer. */ static rs_result rs_delta_s_scan(rs_job_t *job) { size_t this_len, avail_len; int is_ending; void *inptr; rs_result result; rs_job_check(job); avail_len = rs_scoop_total_avail(job); this_len = job->block_len; is_ending = job->stream->eof_in; /* Now, we have avail_len bytes, and we need to scan through them * looking for a match. We'll always end up emitting exactly one * command, either a literal or a copy, and after discovering that * we will skip over the appropriate number of bytes. */ if (avail_len == 0) { if (is_ending) { /* no more delta to do */ job->statefn = rs_delta_s_end; } return RS_BLOCKED; } /* must read at least one block, or give up */ if ((avail_len < job->block_len) && !is_ending) { /* we know we won't get it, but we have to try for a whole * block anyhow so that it gets into the scoop. */ rs_scoop_input(job, job->block_len); return RS_BLOCKED; } result = rs_scoop_readahead(job, avail_len, &inptr); if (result != RS_DONE) return result; return rs_delta_scan(job, avail_len, inptr); } /** * Scan for a matching block in the next \p avail_len bytes of input. * * If nonmatching data is found, then a LITERAL command will be put in * the tube immediately. If matching data is found, then its position * will be saved in the job, and the job state set up to write out a * COPY command after handling the literal. */ static rs_result rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p) { rs_long_t match_where; int search_pos, end_pos; unsigned char *inptr = (unsigned char *) p; uint32_t s1 = job->weak_sig & 0xFFFF; uint32_t s2 = job->weak_sig >> 16; /* So, we have avail_len bytes of data, and we want to look * through it for a match at some point. It's OK if it's not at * the start of the available input data. If we're approaching * the end and can't get a match, then we just block and get more * later. */ /* FIXME: Perhaps we should be working in signed chars for the * rolling sum? */ if (job->stream->eof_in) end_pos = avail_len - 1; else end_pos = avail_len - job->block_len; for (search_pos = 0; search_pos <= end_pos; search_pos++) { size_t this_len = job->block_len; if (search_pos + this_len > avail_len) { this_len = avail_len - search_pos; rs_trace("block reduced to %d", this_len); } else if (job->have_weak_sig) { unsigned char a = inptr[search_pos + this_len - 1]; /* roll in the newly added byte, if any */ s1 += a + RS_CHAR_OFFSET; s2 += s1; job->weak_sig = (s1 & 0xffff) | (s2 << 16); } if (!job->have_weak_sig) { rs_trace("calculate weak sum from scratch"); job->weak_sig = rs_calc_weak_sum(inptr + search_pos, this_len); s1 = job->weak_sig & 0xFFFF; s2 = job->weak_sig >> 16; job->have_weak_sig = 1; } if (rs_roll_paranoia) { rs_weak_sum_t verify = rs_calc_weak_sum(inptr + search_pos, this_len); if (verify != job->weak_sig) { rs_fatal("mismatch between rolled sum %#x and check %#x", job->weak_sig, verify); } } if (rs_search_for_block(job->weak_sig, inptr + search_pos, this_len, job->signature, &job->stats, &match_where)) { /* So, we got a match. Cool. However, there may be * leading unmatched data that we need to flush. Thus we * set our statefn to be rs_delta_s_deferred_copy so that * we can write out the command later. */ rs_trace("matched %.0f bytes at %.0f!", (double) this_len, (double) match_where); job->basis_pos = match_where; job->basis_len = this_len; job->statefn = rs_delta_s_deferred_copy; job->have_weak_sig = 0; break; } else { /* advance by one; roll out the byte we just moved over. */ unsigned char a = inptr[search_pos]; unsigned char shift = a + RS_CHAR_OFFSET; s1 -= shift; s2 -= this_len * shift; job->weak_sig = (s1 & 0xffff) | (s2 << 16); } } if (search_pos > 0) { /* We may or may not have found a block, but we know we found * some literal data at the start of the buffer. Therefore, * we have to flush that out before we can continue on and * emit the copy command or keep searching. */ /* FIXME: At the moment, if you call with very short buffers, * then you will get a series of very short LITERAL commands. * Perhaps this is what you deserve, or perhaps we should try * to get more readahead and avoid that. */ /* There's some literal data at the start of this window which * we know is not in any block. */ rs_trace("got %d bytes of literal data", search_pos); rs_emit_literal_cmd(job, search_pos); rs_tube_copy(job, search_pos); } return RS_RUNNING; } static rs_result rs_delta_s_deferred_copy(rs_job_t *job) { if (!job->basis_len) { rs_log(RS_LOG_ERR, "somehow got zero basis_len"); return RS_INTERNAL_ERROR; } rs_emit_copy_cmd(job, job->basis_pos, job->basis_len); rs_scoop_advance(job, job->basis_len); job->statefn = rs_delta_s_scan; return RS_RUNNING; } /** * \brief State function that does a slack delta containing only * literal data to recreate the input. */ static rs_result rs_delta_s_slack(rs_job_t *job) { rs_buffers_t * const stream = job->stream; size_t avail = stream->avail_in; if (avail) { rs_trace("emit slack delta for %.0f available bytes", (double) avail); rs_emit_literal_cmd(job, avail); rs_tube_copy(job, avail); return RS_RUNNING; } else { if (rs_job_input_is_ending(job)) { job->statefn = rs_delta_s_end; return RS_RUNNING; } else { return RS_BLOCKED; } } } /** * State function for writing out the header of the encoding job. */ static rs_result rs_delta_s_header(rs_job_t *job) { rs_emit_delta_header(job); if (job->block_len) { if (!job->signature) { rs_error("no signature is loaded into the job"); return RS_PARAM_ERROR; } job->statefn = rs_delta_s_scan; } else { rs_trace("block length is zero for this delta; " "therefore using slack deltas"); job->statefn = rs_delta_s_slack; } return RS_RUNNING; } /** * Prepare to compute a streaming delta. */ rs_job_t *rs_delta_begin(rs_signature_t *sig) { rs_job_t *job; job = rs_job_new("delta", rs_delta_s_header); job->signature = sig; if ((job->block_len = sig->block_len) < 0) { rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature", job->block_len); + rs_job_free(job); return NULL; } job->strong_sum_len = sig->strong_sum_len; if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) { rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature", job->strong_sum_len); + rs_job_free(job); return NULL; } return job; } |