static char rcsid[] = "@(#)$Id: sb_file.c,v 1.12 2006/04/09 07:37:07 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.12 $ $State: Exp $ * * Author: Kari Hurtta (was hurtta+elm@ozone.FMI.FI) *****************************************************************************/ #include "headers.h" #include "s_me.h" #include "sb_imp.h" #include #ifndef ANSI_C extern int errno; #endif DEBUG_VAR(Debug,__FILE__,"charset"); static unsigned char *s2us P_((char *str)); static unsigned char *s2us(str) char *str; { return (unsigned char *)str; } static char *us2s P_((unsigned char *str)); static char *us2s(str) unsigned char *str; { return (char *)str; } static int sb_init_file P_((struct stringbuffer *buffer)); static int sb_init_file(buffer) struct stringbuffer *buffer; { static int count = 0; int i; char *tmp; tmp = give_dt_estr_as_str(&temp_dir_e,"tmpdir"); if (!tmp) tmp = "/tmp/"; buffer->p->a.file.offset_count = 0; buffer->p->a.file.offsets = NULL; buffer->p->a.file.filename = NULL; buffer->p->a.file.fh = NULL; for (i = 0; i < 10; i++) { count++; buffer->p->a.file.filename = elm_message(FRM("%selmsb-%d-%d"), tmp, getpid (), count); buffer->p->a.file.fh = safeopen_rdwr(buffer->p->a.file.filename); if (!buffer->p->a.file.fh) { int err = errno; DPRINT(Debug,25,(&Debug, "stringbuffer: safeopen_rdwr: %s: %s (errno %d)\n", buffer->p->a.file.filename, error_description(err),err)); free(buffer->p->a.file.filename); buffer->p->a.file.filename = NULL; } else break; } if (!buffer->p->a.file.fh) return 0; unlink (buffer->p->a.file.filename); DPRINT(Debug,1,(&Debug, "stringbuffer: using temp file (%s)\n", buffer->p->a.file.filename)); return 1; } static void sb_free_file P_((struct stringbuffer *buffer)); static void sb_free_file(buffer) struct stringbuffer *buffer; { if (buffer->p->a.file.fh) { fclose(buffer->p->a.file.fh); buffer->p->a.file.fh = NULL; } if (buffer->p->a.file.filename) { free(buffer->p->a.file.filename); buffer->p->a.file.filename = NULL; } if (buffer->p->a.file.offsets) { free(buffer->p->a.file.offsets); buffer->p->a.file.offsets = NULL; } buffer->p->a.file.offset_count = 0; } static void sb_add_line_to_file P_((struct stringbuffer *buffer, const struct string *string)); static void sb_add_line_to_file(buffer,string) struct stringbuffer *buffer; CONST struct string *string; { int ptr = buffer->p->a.file.offset_count; if (fseek(buffer->p->a.file.fh,0,SEEK_END) != 0) { int err = errno; DPRINT(Debug,1,(&Debug, "stringbuffer: fseek (flush) failure: %s: %s (errno %d)\n", buffer->p->a.file.filename, error_description(err),err)); return; } buffer->p->a.file.offsets = safe_realloc(buffer->p->a.file.offsets, (buffer->p->a.file.offset_count +1) * sizeof (long)); buffer->p->a.file.offsets[ptr] = ftell(buffer->p->a.file.fh); buffer->p->a.file.offset_count++; if (string->string_type-> MIME_name) { char * s = us2s(stream_from_string(string,0,NULL)); int l1 = strlen(s); int l2 = strlen(string->string_type->MIME_name); fprintf(buffer->p->a.file.fh,"%d:%d:",l2,l1); /* Include ending \0 to string */ fwrite(string->string_type-> MIME_name,1,l2+1, buffer->p->a.file.fh); /* Include ending \0 to string */ fwrite(s,1,l1+1,buffer->p->a.file.fh); free(s); } else { /* No charset name available ... */ struct string *str = convert_string(system_charset,string,0); char * s = us2s(stream_from_string(str,0,NULL)); int l1 = strlen(s); fprintf(buffer->p->a.file.fh,":%d:",l1); fputc('\0',buffer->p->a.file.fh); /* Terminaing \0 of null charset */ /* Include ending \0 to string */ fwrite(s,1,l1+1,buffer->p->a.file.fh); free(s); free_string(&str); } } static int sb_linecount_file P_((const struct stringbuffer *ptr)); static int sb_linecount_file(ptr) CONST struct stringbuffer *ptr; { return ptr->p->a.file.offset_count; } static struct string *sb_get_line_from_file P_((const struct stringbuffer *buffer, int ptr)); static struct string *sb_get_line_from_file(buffer,ptr) CONST struct stringbuffer *buffer; int ptr; { int setlen = 0; int strlen = 0; char * bigs = NULL; charset_t sn = system_charset; struct string * res = NULL; int c; if (ptr < 0 || ptr >= buffer->p->a.file.offset_count) panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Bad index",0); if (0 != fseek(buffer->p->a.file.fh,buffer->p->a.file.offsets[ptr], SEEK_SET)) { int err = errno; DPRINT(Debug,1,(&Debug, "stringbuffer: fseek (flush) failure: %s: %s (errno %d)\n", buffer->p->a.file.filename, error_description(err),err)); panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Failed to flush or seek file",0); } c = fgetc(buffer->p->a.file.fh); while (c >= '0' && c <= '9') { setlen = setlen * 10 + c - '0'; c = fgetc(buffer->p->a.file.fh); } if (':' != c) { panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Bad data read from file",0); } c = fgetc(buffer->p->a.file.fh); while (c >= '0' && c <= '9') { strlen = strlen * 10 + c - '0'; c = fgetc(buffer->p->a.file.fh); } if (':' != c) { panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Bad data read from file",0); } bigs = safe_malloc(setlen+1+strlen+1); if (fread(bigs,1,setlen+1+strlen+1,buffer->p->a.file.fh) != setlen+1+strlen+1) { panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Read error or short data read from file",0); } if (bigs[setlen] != '\0' || bigs[setlen+1+strlen] != '\0') { panic("STRINGBUFFER PANIC",__FILE__,__LINE__,"sb_get_line_from_file", "Bad data read from file",0); } if (setlen != 0) { sn = MIME_name_to_charset(bigs,0); if (!sn) { DPRINT(Debug,1,(&Debug, "stringbuffer: Charset '%s' is not knows (impossible?)\n", bigs)); panic("STRINGBUFFER PANIC",__FILE__,__LINE__, "sb_get_line_from_file", "Bad charset read from file",0); } } res = new_string2(sn,s2us(&(bigs[setlen+1]))); free(bigs); return res; } struct sb_type sb_in_file = { sb_init_file, sb_free_file, sb_add_line_to_file, sb_linecount_file, sb_get_line_from_file }; /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */