diff --git a/Android.mk b/Android.mk index 5c98cf75..f79981cb 100644 --- a/Android.mk +++ b/Android.mk @@ -43,9 +43,7 @@ LOCAL_SRC_FILES:= \ serval-dna/commandline.c \ serval-dna/dataformats.c \ serval-dna/dna.c \ - serval-dna/export.c \ serval-dna/gateway.c \ - serval-dna/hlrdata.c \ serval-dna/overlay.c \ serval-dna/overlay_broadcast.c \ serval-dna/packetformats.c \ diff --git a/Makefile.in b/Makefile.in index 39619b72..387cc199 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,5 +1,5 @@ SRCS= dna.c server.c client.c peers.c ciphers.c responses.c packetformats.c dataformats.c \ - hlrdata.c srandomdev.c simulate.c batman.c export.c gateway.c \ + srandomdev.c simulate.c batman.c gateway.c \ overlay.c overlay_buffer.c overlay_interface.c overlay_payload.c overlay_route.c \ overlay_packetformats.c overlay_abbreviations.c overlay_advertise.c overlay_mdp.c \ rhizome.c rhizome_http.c rhizome_bundle.c rhizome_database.c rhizome_crypto.c \ @@ -8,7 +8,7 @@ SRCS= dna.c server.c client.c peers.c ciphers.c responses.c packetformats.c data trans_cache.c keyring.c OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \ - hlrdata.o srandomdev.o simulate.o batman.o export.o gateway.o \ + srandomdev.o simulate.o batman.o gateway.o \ overlay.o overlay_buffer.o overlay_interface.o overlay_payload.o overlay_route.o \ overlay_packetformats.o overlay_abbreviations.o overlay_advertise.o overlay_mdp.o \ rhizome.o rhizome_http.o rhizome_bundle.o rhizome_database.o rhizome_crypto.o \ diff --git a/export.c b/export.c deleted file mode 100644 index 9fc978cb..00000000 --- a/export.c +++ /dev/null @@ -1,274 +0,0 @@ -/* -Serval Distributed Numbering Architecture (DNA) -Copyright (C) 2010 Paul Gardner-Stephen - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -/* - Export the contents of an binary formatted HLR into plain text. - -*/ - -#include "serval.h" - -int nyblValue(int c) -{ - if (c>='0'&&c<='9') return c-'0'; - if (c>='A'&&c<='F') return c-'A'+10; - if (c>='a'&&c<='f') return c-'a'+10; - exit(setReason("Illegal character `%c' in hexadecimal value.",c)); -} - -int importHlr(char *textfile) -{ - int j; - FILE *i; - unsigned char line[1024]; - char sid[128]; - int state=0; - int hofs=-1; - int varinst; - int varid; - int varlen; - unsigned char data[65536]; - int dlen=0; - int linenum=0; - - if (!strcmp("-",textfile)) i=stdin; - else - if ((i=fopen(textfile,"r"))==NULL) exit(setReason("Could not open import file `%s'")); - - line[0]=0; fgets((char *)line,1024,i); - while(!feof(i)) - { - int l=strlen((char *)line); - linenum++; - - /* Strip CR/LFs */ - while(l>0&&(line[l-1]=='\n'||line[l-1]=='\r')) l--; line[l]=0; - - /* Sanity check line */ - for(j=0;j0x7f)&&line[j]!='\n')) { - exit(setReason("Illegal character 0x%02x encountered in line %d of HLR import file.",line[j],linenum)); - } - - if (line[0]!='#') - { - /* Deal with line */ - switch(state) - { - case 0: /* looking for a control line */ - if (!strncmp("sid=",(char *)line,4)) { - /* Read SID, and create HLR record for it if one doesn't already exist */ - if (l!=4+SID_STRLEN) - exit(setReason("Malformed sid= line encountered in line %d of HLR import file.",linenum)); - - /* Extract SID */ - for(j=0;j0xff) - exit(setReason("%s:%d var= line contains illegal variable ID. " - "Multi-value variables must be in the range 80-ff (hexadecimal)",textfile,linenum)); - if (varinst<0||varinst>0xff) - exit(setReason("%s:%d var= line contains illegal variable instance number. Must be in the range 00-ff (hexadecimal)", - textfile,linenum)); - if (varlen<1||varlen>65534) - exit(setReason("%s:%d var= line contains illegal length. Must be in the range 1-65534.",textfile,linenum)); - - /* Okay, we have a valid variable, lets switch to accumulating its value */ - dlen=0; - state=2; - } - else if (sscanf((char *)line,"var=%02x len=%d",&varid,&varlen)==2) { - if (varid>0x7f||varid<0) - exit(setReason("%s:%d var= line contains illegal variable ID. " - "Single-value variables must be in the range 00-7f (hexadecimal)",textfile,linenum)); - varinst=0; - if (varlen<1||varlen>65534) - exit(setReason("%s:%d var= line contains illegal length. Must be in the range 1-65534.",textfile,linenum)); - - /* Okay, we have a valid variable, lets switch to accumulating its value */ - dlen=0; - state=2; - } else { - exit(setReason("%s:%d Syntax error in HLR record.",textfile,linenum)); - } - break; - case 2: /* Reading a variable value */ - /* Read line of data */ - for(j=0;j=varlen) - exit(setReason("%s:%d Variable value data exceeds stated length.\nThis is what was left after I had taken all I needed: `%s'.",textfile,linenum,&line[j])); - switch(line[j]) - { - case '\\': - j++; - switch(line[j]) - { - case 'n': data[dlen++]='\n'; break; - case 'r': data[dlen++]='\r'; break; - case 'x': data[dlen++]=(hexvalue(line[j+1])<<4)+hexvalue(line[j+2]); j+=2; break; - default: - exit(setReason("%s:%d Illegal \\ sequence `\\%c' encountered in variable value. Only \\r, \\n and \\x are accepted.",textfile,linenum,line[j])); - } - break; - default: - data[dlen++]=line[j]; - } - j++; - } - - if (dlen==varlen) { - state=1; - if (hofs==-1) { - if (varid!=VAR_DIDS||varinst!=0) - { - /* This variable instance is not the first DID, but we still need to create the HLR record. - This is naughty. The first var= line after a sid= line MUST be var=80:00 to specify the first DID. */ - exit(setReason("%s:%d The first var= line after a sid= line MUST be var=80:00 to specify the first DID.",textfile,linenum)); - } - else - { - /* Okay, this is the first DID, so now we can create the HLR record. - But first, we need to unpack the DID into ascii */ - char did[SIDDIDFIELD_LEN+1]; - int zero=0; - extractDid(data,&zero,did); - printf("DID=%s\n",did); - if (createHlr((char *)did,sid)) - exit(setReason("%s:%d createHlr() failed.",textfile,linenum)); - hofs=0; - findHlr(hlr,&hofs,NULL,did); - if (hofs<0) - exit(setReason("%s:%d Could not find created HLR record.",textfile,linenum)); - } - } - - } - } - } - - line[0]=0; fgets((char *)line,1024,i); - } - - fclose(i); - - return 0; -} - -int exportHlr(unsigned char *hlr_file,char *text) -{ - FILE *o; - int ofs=0,i; - if (openHlrFile((char *)hlr_file,-1)) exit(setReason("Could not open HLR database")); - - if (!strcmp("-",text)) o=stdout; - else - if ((o=fopen(text,"w"))==NULL) exit(setReason("Could not create export file")); - - while(findHlr(hlr,&ofs,NULL,NULL)) - { - int hofs=ofs; - fprintf(o,"# HLR Record at 0x%08x\n",ofs); - - /* Output SID for this record */ - fprintf(o,"sid="); - for(i=0;i<32;i++) fprintf(o,"%02x",hlr[hofs+4+i]); - fprintf(o,"\n"); - - struct hlrentry_handle *h=openhlrentry(hlr,hofs); - - while(h) - { - int cols; - if (h->var_id==0&&h->value_len==0) break; - - fprintf(o,"var=%02x",h->var_id); - if (h->var_id&0x80) fprintf(o,":%02x",h->var_instance); - fprintf(o," len=%d",h->value_len); - for(i=0;vars[i].name;i++) if (vars[i].id==h->var_id) { fprintf(o," name=%s",vars[i].name); break; } - fprintf(o,"\n"); - - cols=0; - for (i=0;ivalue_len;i++) - { - if (h->value[i]>=' '&&h->value[i]<0x7f&&h->value[i]!='\\'&&(cols||h->value[i]!='#')) - { - fprintf(o,"%c",h->value[i]); - cols++; - } - else - { - switch(h->value[i]) { - case '\r': fprintf(o,"\\r"); cols+=2; break; - case '\n': fprintf(o,"\\n"); cols+=2; break; - default: - fprintf(o,"\\x%02x",(unsigned char)h->value[i]); cols+=4; - } - if (cols>75) { fprintf(o,"\n"); cols=0; } - } - } - if (cols) { fprintf(o,"\n"); cols=0; } - - h=hlrentrygetent(h); - } - - /* Mark the end of the record - (as much to make life easier for the import parser as anything) */ - fprintf(o,"eor\n"); - - /* Advance to next record and keep searching */ - if (nextHlr(hlr,&ofs)) break; - } - - return 0; -} diff --git a/hlrdata.c b/hlrdata.c deleted file mode 100644 index bfe6d530..00000000 --- a/hlrdata.c +++ /dev/null @@ -1,563 +0,0 @@ -/* -Serval Distributed Numbering Architecture (DNA) -Copyright (C) 2010 Paul Gardner-Stephen - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "serval.h" - -int hlrGetRecordLength(unsigned char *hlr,int hofs); - -int bcompare(unsigned char *a,unsigned char *b,size_t len) -{ - int i; - for(i=0;ib[i]) return 1; - return 0; -} - -int seedHlr() -{ - /* If HLR is empty, create a default entry */ - int offset=0; - if (!nextHlr(hlr,&offset)) { - /* There is an entry, so nothing to do */ - return 0; - } - - /* There wasn't an entry, so make one. - Pick a random SID (it will pick one for us). - For completeness we will pick a random DID, which also makes life easier for us anyway - by allowing the use of createHlr(). - */ - { - int i,ofs=0; - char sid[SID_STRLEN+1]; - char did[65]; - /* Make DID start with 2 through 9, as 1 is special in many number spaces. */ - did[0]='2'+random()%8; - /* Then add 10 more digits, which is what we do in the mobile phone software */ - for(i=1;i<11;i++) did[i]='0'+random()%10; did[11]=0; - if (createHlr(did,sid)) return WHY("Failed to seed HLR with home entry"); - if (hlrSetVariable(hlr,ofs,VAR_LOCATIONS,0,(unsigned char *)"4000@",5)) return WHY("Could not set location while seeding HLR"); - } - return 0; -} - -int nextHlr(unsigned char *hlr,int *ofs) -{ - int record_length; - - if (!ofs) return setReason("nextHlr passed NULL pointer."); - if (*ofs>=hlr_size) return -1; - - /* Get length of this record */ - record_length =hlr[(*ofs)+3]<<0; - record_length|=hlr[(*ofs)+2]<<8; - record_length|=hlr[(*ofs)+1]<<16; - record_length|=hlr[(*ofs)+0]<<24; - - if (record_length<1) return -1; - - (*ofs)+=record_length; - return 0; -} - -char *hlrSid(unsigned char *hlr, int ofs, char *sid) -{ - int o = ofs + 4; - extractSid(hlr, &o, sid); - return sid; -} - -int findHlr(unsigned char *hlr,int *ofs,char *sid,char *did) -{ - unsigned int record_length; - int match=0; - int records_searched=0; - int pid_len=0; - unsigned char packed_id[40]; - - if ((*ofs)>=hlr_size) return 0; - - if (debug&DEBUG_HLR) fprintf(stderr,"Searching for HLR record sid=[%s]/did=[%s]\n",sid?sid:"NULL",did?did:"NULL"); - - if (did&&did[0]) { - /* Make packed version of DID so that we can compare faster with the DIDs in the HLR */ - if (stowDid(packed_id,&pid_len,did)) return setReason("DID appears to be invalid"); - /* Find significant length of packed DID */ - for(pid_len=0;pid_lenvar_id,h->var_instance); - dump("variable value",h->value,h->value_len); - } - if (h->var_id==VAR_DIDS) { /* DID entry */ - if (debug&DEBUG_HLR) fprintf(stderr,"Checking DID against record DID\n"); - if (!bcompare(packed_id,h->value,pid_len)) { - if (debug&DEBUG_HLR) fprintf(stderr,"Found matching DID in HLR record #%d\n",records_searched); - match=1; - break; - } - } - else - { - if (debug&DEBUG_HLR) fprintf(stderr,"Skipping non-DID variable while searching for DID.\n"); - } - h=hlrentrygetent(h); - } - } - if ((!sid)&&(!did)) match=1; - - /* For each match ... */ - if (match) - { - if (debug&DEBUG_HLR) fprintf(stderr,"Returning HLR entry @ 0x%x\n",*ofs); - return 1; - } - - /* Consider next record */ - (*ofs)+=record_length; - - if ((*ofs)>=hlr_size) return 0; - } - - return 0; -} - -int createHlr(char *did,char *sid) { - int i; - int record_offset=0; - - if (debug&DEBUG_HLR) fprintf(stderr,"Asked to create a new HLR record\n"); - - /* Generate random SID */ - for (i = 1; i != SID_STRLEN; ++i) - sid[i] = hexdigit[random() & 0xf]; - sid[SID_STRLEN]=0; - /* But make sure first digit is non-zero as required by the overlay mesh */ - sid[0]=hexdigit[1+(random()&0xe)]; - if (debug&DEBUG_HLR) fprintf(stderr,"Creating new HLR entry with sid %s\n",sid); - - /* Find first free byte of HLR. - Keep calling findHlr() until we find the end. */ - while((i=hlrGetRecordLength(hlr,record_offset))>0) - { - record_offset+=i; - if (debug&DEBUG_HLR) fprintf(stderr,"Skipping %d bytes to 0x%x\n",i,record_offset); - } - if (i<0) return setReason("Corrupt HLR: Negative length field encountered."); - - if (record_offset>=hlr_size) - { - /* No space */ - return setReason("No space in HLR for a new record"); - } - else - { - /* We have found space, but is it enough? */ - int bytes=hlr_size-record_offset; - if (bytes<1024) return setReason("<1KB space in HLR"); - - if (debug&DEBUG_HLR) fprintf(stderr,"Creating new HLR entry @ 0x%x\n",record_offset); - - /* Write shiny fresh new record. - 32bit - record length - 32 bytes - SID - Total length = 4+32=36 bytes. - */ - if (stowSid(hlr,record_offset+4,sid)) return setReason("Could not store SID in new HLR entry"); - - /* Write length last of all to make entry valid */ - hlr[record_offset]=0; - hlr[record_offset+1]=0; - hlr[record_offset+2]=0; - hlr[record_offset+3]=36; - - /* Store the DID */ - { - unsigned char packeddid[DID_MAXSIZE]; - int pdidlen=0; - stowDid(packeddid,&pdidlen,did); - /* Work out reduced length of DID */ - for(pdidlen=1;pdidlen>8)&0xff; - hlr[hofs+1]=(length>>16)&0xff; - hlr[hofs+0]=(length>>24)&0xff; - return 0; -} - -/* - XXX We could return a fancy struct, and maybe we should. - But returning a long long and using the two 32bit halves is easy for now, and has a - certain efficiency to it. */ -struct hlrentry_handle *openhlrentry(unsigned char *hlr,int hofs) -{ - int record_length=hlrGetRecordLength(hlr,hofs); - - /* If record has zero length, then open fails */ - if (record_length<1) - { - if (debug&DEBUG_HLR) fprintf(stderr,"HLR record is zero length -- aborting.\n"); - return NULL; - } - - bzero(&hlr_handle,sizeof(hlr_handle)); - - hlr_handle.record_length=record_length; - hlr_handle.hlr=hlr; - hlr_handle.hlr_offset=hofs; - hlr_handle.var_id=-1; - hlr_handle.var_instance=-1; - hlr_handle.value=NULL; - hlr_handle.value_len=-1; - hlr_handle.entry_offset=0; - - /* Return offset of start of HLR entry and the offset of the first variable */ - return hlrentrygetent(&hlr_handle); -} - -struct hlrentry_handle *hlrentrygetent(struct hlrentry_handle *h) -{ - int ptr; - - if (!h) return NULL; - - if (h->entry_offset==0) - { - /* First entry */ - if (debug&DEBUG_HLR) fprintf(stderr,"Considering first entry of HLR record.\n"); - h->entry_offset=HLR_RECORD_LEN_SIZE+SID_SIZE; - } - else - { - /* subsequent entry */ - if (debug&DEBUG_HLR) fprintf(stderr,"Considering entry @ 0x%x\n",h->entry_offset); - h->entry_offset+=1+2+h->value_len+(h->var_id&0x80?1:0); - } - - /* XXX Check if end of record */ - if (h->entry_offset>=h->record_length) { - if (debug&DEBUG_HLR) fprintf(stderr,"Reached end of HLR record (%d>=%d).\n",h->entry_offset,h->record_length); - return NULL; - } - - /* XXX Extract variable */ - ptr=h->hlr_offset+h->entry_offset; - if (debug&DEBUG_HLR) fprintf(stderr,"Extracting HLR variable @ 0x%x\n",ptr); - h->var_id=hlr[ptr]; - h->value_len=(hlr[ptr+1]<<8)+hlr[ptr+2]; - ptr+=3; - if (h->var_id&0x80) h->var_instance=hlr[ptr++]; - h->value=&h->hlr[ptr]; - - return h; -} - -int hlrGetVariable(unsigned char *hlr,int hofs,int varid,int varinstance, - unsigned char *value,int *len) -{ - struct hlrentry_handle *h; - int hlr_offset=-1; - - h=openhlrentry(hlr,hofs); - - /* Find the place in the HLR record where this variable is */ - while(h) - { - if ((h->var_idvar_id==varid&&h->var_instanceentry_offset; - else - { - /* Value is here if anywhere */ - if (h->var_id>varid||h->var_instance>varinstance) - return setReason("No such variable instance"); - if (h->value_len>*len) return setReason("Value too long for buffer"); - bcopy(h->value,value,h->value_len); - *len=h->value_len; - return 0; - break; - } - h=hlrentrygetent(h); - } - - return setReason("No such variable instance"); -} - -int hlrSetVariable(unsigned char *hlr,int hofs,int varid,int varinstance, - unsigned char *value,int len) -{ - /* hlr & hofs identify the start of a HLR entry. */ - - struct hlrentry_handle *h; - int hlr_offset=-1; - int hlr_size=hlrGetRecordLength(hlr,hofs); - - if (debug&DEBUG_HLR) fprintf(stderr,"hlrSetVariable(varid=%02x, instance=%02x, len=%d)\n", - varid,varinstance,len); - - h=openhlrentry(hlr,hofs); - - /* Find the place in the HLR record where this variable should go */ - while(h) - { - if (debug&DEBUG_HLR) fprintf(stderr,"h->var_id=%02x, h->h->var_instance=%02x, h->entry_offset=%x\n", - h->var_id,h->var_instance,h->entry_offset); - if ((h->var_idvar_id&0x80)&&(h->var_id==varid&&h->var_instanceentry_offset; - if (debug&DEBUG_HLR) fprintf(stderr,"Found variable instance prior: hlr_offset=%d.\n",hlr_offset); - } - else - { - /* Value goes here */ - if (debug&DEBUG_HLR) fprintf(stderr,"Found variable instance to overwrite: hlr_offset=%d.\n",hlr_offset); - hlr_offset=h->entry_offset; - break; - } - h=hlrentrygetent(h); - } - - /* XXX Race condition: If power is lost half way through here, then it is possible for - the record to be left in an inconsistent state */ - - if (h&&hlr_offset>-1) - { - if (debug&DEBUG_HLR) printf("hlr_offset=%d\n",hlr_offset); - if (h&&h->var_id==varid&&((h->var_instance==varinstance)||(!(h->var_id&0x80)))) - { - int existing_size; - /* Replace existing value */ - if (debug&DEBUG_HLR) fprintf(stderr,"Replacing value in HLR:\n"); - existing_size=1+2+((h->var_id&0x80)?1:0)+h->value_len; - hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+((varid&0x80)?1:0)-existing_size); - } - else - { - /* Insert value here */ - if (debug&DEBUG_HLR) fprintf(stderr,"Inserting value in HLR\n"); - hlrMakeSpace(hlr,hofs,hlr_offset,1+2+len+((varid&0x80)?1:0)); - } - } - else - { - /* HLR record has no entries, or this entry needs to go at the end, - so insert value at end of the record */ - if (debug&DEBUG_HLR) fprintf(stderr,"Inserting value at end of HLR @ 0x%x\n",hlr_size); - hlrMakeSpace(hlr,hofs,hlr_size,1+2+len+((varid&0x80)?1:0)); - hlr_offset=hlr_size; - } - - return hlrStowValue(hlr,hofs,hlr_offset,varid,varinstance,value,len); -} - -int hlrStowValue(unsigned char *hlr,int hofs,int hlr_offset, - int varid,int varinstance,unsigned char *value,int len) -{ - int ptr=hofs+hlr_offset; - - hlr[ptr++]=varid; - hlr[ptr++]=(len>>8)&0xff; - hlr[ptr++]=len&0xff; - if (varid&0x80) hlr[ptr++]=varinstance; - bcopy(value,&hlr[ptr],len); - ptr+=len; - - return 0; -} - -int hlrMakeSpace(unsigned char *hlr,int hofs,int hlr_offset,int bytes) -{ - int length; - int shifted_bytes=hlr_size-(hofs+hlr_offset+bytes); - /* Don't read past end of file */ - if (bytes<0) shifted_bytes+=bytes; - - /* Deal with easy case first */ - if (!bytes) return 0; - - if (debug&DEBUG_HLR) { - fprintf(stderr,"hlrMakeSpace: Inserting %d bytes at offset %d with hofs=%d. shifted bytes=%d\n", - bytes,hlr_offset,hofs,shifted_bytes); - fflush(stderr); - } - - /* Shift rest of HLR up/down. - If down, back-fill bytes with zeros. */ - bcopy(&hlr[hofs+hlr_offset],&hlr[hofs+hlr_offset+bytes], - shifted_bytes); - if (bytes<0) bzero(&hlr[hlr_size+bytes],0-bytes); - - /* Update record length */ - length=hlrGetRecordLength(hlr,hofs); - length+=bytes; - hlrSetRecordLength(hlr,hofs,length); - if (debug&DEBUG_HLR) fprintf(stderr,"hlrMakeSpace: HLR entry now %d bytes long.\n",length); - - return 0; -} - -int hlrDump(unsigned char *hlr,int hofs) -{ - struct hlrentry_handle *h=openhlrentry(hlr,hofs); - - fprintf(stderr,"Dumping HLR entry @ 0x%x\n",hofs); - while(h) - { - fprintf(stderr," var=%02x",h->var_id); - if (h->var_id&0x80) fprintf(stderr,"/%02x",h->var_instance); - fprintf(stderr," len=%d\n",h->value_len); - h=hlrentrygetent(h); - } - - return 0; -} - -int openHlrFile(char *backing_file,int size) -{ - /* Get backing store */ - if (!backing_file) - { - if (size<0) exit(setReason("You must provide an HLR file or size")); - - /* transitory storage of HLR data, so just malloc() the memory */ - hlr=calloc(size,1); - if (!hlr) exit(setReason("Failed to calloc() HLR database.")); - if (debug&DEBUG_HLR) fprintf(stderr,"Allocated %d byte temporary HLR store\n",size); - } - else - { - unsigned char zero[8192]; - FILE *f=fopen(backing_file,"r+"); - if (!f) f=fopen(backing_file,"w+"); - if (!f) exit(setReason("Could not open backing file.")); - bzero(&zero[0],8192); - fseek(f,0,SEEK_END); - errno=0; - - /* Obtain size from existing backing file */ - if (size<0) size=ftell(f); - - while(ftell(f)