/* Coded by Loïc Jeannin - loic@conectiva.com.br - tahorg - gcu(c) 5/2002 this piece of *sigh* code is freely distribuable under the terms of the GPL. Conectiva Corporation (c) */ #include "drbd_objects.h" using namespace std; class parser { ifstream in; char buf[MAX_LINE_SIZE]; resource *first; // first of the list of the resource resource **current; // current resource being editing int deep; // represent the deep in the blocks public: int noError; // syntax error in the file 0->yes, 1->no char value[MAX_LINE_SIZE]; // buffer for the reading the values parser() { in.open(CONF_FILE); first=NULL; deep=0; noError=1; } parser(char *f) { in.open(f); first=NULL; deep=0; noError=1; } ~parser() { free(first); in.close(); } void test() /* obvious */ { char *tmp; while(in.getline(buf,MAX_LINE_SIZE)) { tmp=buf; cout << buf << endl; eliminateComment(tmp); cout << "ligne: " << tmp << endl; } } resource *read() /* read the file and create the list of resource * object, calling the getResource*/ { char *tmp; char *r = "resource"; /* initialise the list of resource * objects */ current=&first; /* get the first line of the file */ in.getline(buf,MAX_LINE_SIZE); tmp=buf; /* during the entire process tmp represent the current * position in the file * do-while because we have to considere the first word too */ do { if(strncmp(tmp,r,8)==0) { //noError++; /* creating the linked list of * resource objects */ *current=getResource(&tmp); current=&(*current)->next; if(!noError) return(NULL); } /* /\* else if (*tmp!=' ' || *tmp!='\t') *\/ */ /* /\* { *\/ */ /* /\* noError=13; *\/ */ /* /\* return(NULL); *\/ */ /* /\* } *\/ */ } while((tmp=nextWord(tmp))!=0); return first; } private: resource *getResource(char **temp) { char *tmp; tmp=*temp; resource *R = new resource(); /* getting the name of the resource */ tmp=nextWord(tmp); if(*value!='{') { R->setName(value); /* looking for the open brace */ tmp=nextWord(tmp); if(*value!='{') { noError=4; return(NULL); } } else { R->setName("noName"); } /* checking the components of the resource */ while(1) { tmp=nextWord(tmp); switch(*tmp) { case 'p': // protocole tmp=getVariable(tmp); R->setProtocol(*value); // } break; case 'f': // fsckcmd tmp=getVariable(tmp); R->setFsckcmd(value); break; case 'i': // inittimeout tmp=getVariable(tmp); R->setInittimeout(atoi(value)); break; case 'd': // disk block getDisk(tmp,R); break; case 'o': // one of the two on blocks getBlock(tmp,R); break; case 'n': // net block getNet(tmp,R); break; case '}': *temp=tmp; return(R); break; default: noError=5; return(NULL); } } } void getDisk(char *tmp,resource * O) { /* looking for the open brace */ if(*(tmp=nextWord(tmp))!='{') { noError=0; return; } deep++; /* looking for the disk components */ while(*(tmp=nextWord(tmp))!='}') { /* two possibilities do-panic or disk size * the we test the second byte */ switch(*(tmp+1)) // <- this is ugly, I know { case 'o': //do-panic O->o_disk.setDoPanic(1); break; case 'i': //disk-size tmp=getVariable(tmp); O->o_disk.setSize(atoi(value)); break; default : noError=6; return; break; } } deep--; } void getNet(char *tmp,resource *O) { /* looking for the open brace */ if(*(tmp=nextWord(tmp))!='{') { noError=7; return; } deep++; /* looking for the net components */ while(*(tmp=nextWord(tmp))!='}') { switch(*tmp) { case 's': // sync-rate || skip-sync (ugly test) tmp=getVariable(tmp); if(*(tmp+1)=='y') // sync rate O->o_net.setSyncRate(atoi(value)); else // skip-sync O->o_net.setSyncRate(atoi(value)); break; case 't': //tl-size || timeout (... yes, too) tmp=getVariable(tmp); if(*(tmp+1)=='l') // tl-size O->o_net.setTlSize(atoi(value)); else // timeout O->o_net.setTimeout(atoi(value)); break; case 'c': //connect-int tmp=getVariable(tmp); O->o_net.setConnectInt(atoi(value)); break; case 'p': //ping-int tmp=getVariable(tmp); O->o_net.setPingInt(atoi(value)); break; case '}': return; break; default : noError=8; return; break; } } deep--; } void getBlock(char *tmp, resource *O) { on_block *b_current; /* checking the block to edit*/ if(O->n_block==0) b_current=&(O->o_block_1); else b_current=&(O->o_block_2); /* getting the name of the block */ tmp=nextWord(tmp); if(*value!='{') { b_current->setName(value); /* opening the block */ tmp=nextWord(tmp); if(*value!='{') { noError=10; return; } } else { b_current->setName("noName"); } /* looking for the components */ while(*(tmp=nextWord(tmp))!='}') { switch(*(tmp+1)) // yes, yes ... I know { case 'e': // device tmp=getVariable(tmp); b_current->setDevice(value); break; case 'i': // disk tmp=getVariable(tmp); b_current->setDisk(value); break; case 'd': // address tmp=getVariable(tmp); b_current->setAddress(value); break; case 'o': // port tmp=getVariable(tmp); b_current->setPort(atoi(value)); break; default : noError=11; return; break; } } O->n_block++; } char * getVariable(char *tmp) { char *t3; while(*tmp!='=') tmp++; /* yet we copy the value */ tmp++; t3=value; while(*tmp!='\0' && *tmp!=';') { *t3=*tmp; tmp++;t3++; } *t3='\0'; if(*tmp==';') *tmp=' '; return(tmp); } void eliminateComment(char *temp) /* obvious */ { while(*temp!='\0' && *temp!='#') { temp++; } *temp='\0'; } char *nextWord(char *t) /* pass the "word" (groupe of caracters except tab * and '\0', go to the start of the next one, and * copy it into value[] */ { char *t2; char *t3; /* if we are in a word, go to the end of it */ while(*t!='\t' && *t!=' ' && *t!='\0') t++; /* go throut the "spaces" caractere until it reaches * the beginning a of word */ while(*t=='\t' || *t==' ' || *t=='\0') { /* if we are in the end of the line * go to the next one */ if(*t=='\0') { if(!in.getline(buf,MAX_LINE_SIZE)) return(NULL); t=buf; eliminateComment(t); } else t++; } /* yet we copy the value */ t2=t; t3=value; while(*t2!='\t' && *t2!=' ' && *t2!='\0') { *t3=*t2; t2++;t3++; } *t3='\0'; return(t); } };