/* 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 "mphlr.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_SIZE*2) 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; }