#pragma implementation #include #include #include #include "internal.h" #include "keyword.h" #include "viewsub.h" PUBLIC VIEWITEMS* VIEWITEMS_S::getitem(int no) const { return (VIEWITEMS*)ARRAY::getitem(no); } PUBLIC VIEWITEM *VIEWITEMS_S::locate (const char *key) { VIEWITEM *ret = NULL; for (int i=0; ret == NULL && ilocate (key); } return ret; } /* Locate all configuration lines with the keyword key tb will receive all the values. */ PUBLIC int VIEWITEMS_S::locate_all (const char *key, SSTRING_IDXS &tb) { int ret = 0; int lenkey = strlen(key); reset_iter(); VIEWITEM *it; while ((it=getnext())!=NULL){ const char *s = it->line.get(); s = str_skip(s); if (strncmp(s,key,lenkey) && isspace(s[lenkey])){ s = str_skip(s+lenkey); char word[200]; str_copyword(word,s,sizeof(word)-1); tb.add (new SSTRING_IDX(word,ret)); ret++; } } return ret; } /* Reset the iterator for the getnext() function */ PUBLIC void VIEWITEMS_S::reset_iter() { nofile = 0; positer = 0; } PUBLIC VIEWITEM *VIEWITEMS_S::getnext() { VIEWITEM *ret = NULL; VIEWITEMS *its = getitem(nofile); if (its != NULL){ if (positer == its->getnb()){ positer=0; nofile++; ret = getnext(); }else{ ret = its->getitem(positer); positer++; } } return ret; } PUBLIC int VIEWITEMS_S::write (CONFIG_FILE &conf) const { int ret = getitem(0)->write (conf,NULL); for (int i=1; iget(); CONFIG_FILE f_path (path,help_nil,CONFIGF_OPTIONAL); VIEWITEMS *items = getitem(i); ret |= items->write (f_path,NULL); } return ret; } /* Return the value of a "keyword value" line */ const char *viewsub_getval (VIEWITEM *it, SSTRING &buf) { const char *s = it->line.get(); s = str_skip(s); s = str_skipword(s); s = str_skip(s); if (s[0] == '"'){ char tmp[strlen(s)+1]; str_copyquote (tmp,s); buf.setfrom (tmp); s = buf.get(); } return s; } PUBLIC int VIEWITEMS_S::read ( CONFIG_FILE &conf, bool extract) // Extract the include file from the archive { int ret = -1; remove_all(); includes.remove_all(); VIEWITEMS *its = new VIEWITEMS; its->setcasevar (true); add (its); if (its->read (conf) != -1){ int no = 0; const char *serverroot = "/"; VIEWITEM *sroot = its->locate (K_SERVERROOT); SSTRING bufroot; if (sroot != NULL){ serverroot = viewsub_getval(sroot,bufroot); } while (no < getnb()){ VIEWITEMS *items = getitem(no++); VIEWITEMS incls; int nb = items->locate (K_INCLUDE,incls); for (int i=0; iread (f_path); } globfree (&pg); } } } ret = 0; } return ret; } /* Find all sections of a given type. Return the number of section found */ PUBLIC int VIEWITEMS_S::locatesection ( const char *keyword, // virtualhost, directory, file, ... SSTRING_IDXS &tb) // Will contain all section names { int ret = 0; int lenkey = strlen(keyword); reset_iter(); VIEWITEM *it; while ((it=getnext())!=NULL){ const char *s = it->line.get(); s = str_skip(s); if (s[0] == '<'){ s = str_skip(s+1); if (strncmp(s,keyword,lenkey)==0 && isspace(s[lenkey])){ s = str_skip(s+lenkey); char tmp[strlen(s)+1]; strcpy (tmp,s); char *pt = strchr(tmp,'>'); if (pt != NULL) *pt = '\0'; strip_end (tmp); tb.add (new SSTRING_IDX(tmp,ret)); ret++; } } } return ret; } PUBLIC VIEWITEMS_SUB::VIEWITEMS_SUB(VIEWITEMS_S &_itemss) : itemss (_itemss) { } PUBLIC VIRTUAL VIEWITEMS_SUB::~VIEWITEMS_SUB() { } PUBLIC void VIEWITEMS_SUB::remove_del (VIEWITEM *it) { // Not sure from which VIEWITEMS this VIEWITEM belongs // We try them all. for (int i=0; iremove_del (it); } } PUBLIC VIEWITEMS_RANGE::VIEWITEMS_RANGE(VIEWITEMS_S &_itemss) : VIEWITEMS_SUB (_itemss) { resetview(); } PUBLIC void VIEWITEMS_RANGE::resetview() { items = NULL; start = -1; end = -1; } PUBLIC void VIEWITEMS_RANGE::delall() { if (items != NULL){ for (int i=start; i<=end; i++) items->remove_del (start); } } /* Locate a cpnfiguration line starting with key within the sub range. Return NULL if not found. */ PUBLIC VIEWITEM *VIEWITEMS_RANGE::locate (const char *key) const { return items->locate (key,start,end); } /* Add an item at the end of the range */ PUBLIC void VIEWITEMS_RANGE::add (VIEWITEM *it) { items->insert (end,it); end++; } PUBLIC VIEW_SECTION::VIEW_SECTION(const char *keyword, VIEWITEMS_S &_itemss) : VIEWITEMS_RANGE(_itemss) { key.setfrom (keyword); } /* Delimit the section within a ... Assume that a section cannot span multiple files. */ PRIVATE int VIEW_SECTION::setview (const char *value, int index) { const char *keyword = key.get(); resetview(); int ret = -1; int lenkey = strlen(keyword); int lenval = value != NULL ? strlen(value) : 0; itemss.reset_iter(); VIEWITEM *it; while ((it=itemss.getnext())!=NULL){ const char *s = it->line.get(); s = str_skip(s); if (s[0] == '<'){ s = str_skip(s+1); if (strncmp(s,keyword,lenkey)==0 && isspace(s[lenkey])){ if (index == 0){ ret = 0; }else if (value != NULL){ s = str_skip(s+lenkey); if (strncmp(s,value,lenval)==0 && (isspace(s[lenval]) || s[lenval] == '>')){ ret = 0; } } if (ret == 0){ items = itemss.getitem(itemss.nofile); start = itemss.positer-1; }else{ index--; } }else if (s[0] == '/' && start != -1){ s++; if (strncmp(s,keyword,lenkey)==0 && (isspace(s[lenkey]) || s[lenkey] == '>')){ end = itemss.positer-1; break; } } } } // fprintf (stderr,"setview :%s: :%s: %d %d\n",keyword,value,start,end); return ret; } /* Delimit the section within a ... Assume that a section cannot span multiple files. Use the value to locate the section. */ PUBLIC int VIEW_SECTION::setview (const char *value) { return setview (value,-1); } /* Delimit the section within a ... Assume that a section cannot span multiple files. Use the index to locate the section. You generally use this version (of setview) when there are multiple instance of a pair. */ PUBLIC int VIEW_SECTION::setview (int index) { return setview (NULL,index); } PUBLIC void VIEW_SECTION::updatehead(const char *val) { VIEWITEM *it = NULL; if (items == NULL){ // Ok, the section did not exist, we create it // We place it at the end of the main file items = itemss.getitem(0); it = new VIEWITEM(""); start = items->getnb(); items->add (it); VIEWITEM *end_it = new VIEWITEM(""); end_it->line.setfromf ("",key.get()); end = items->getnb(); items->add (end_it); }else{ it = items->getitem(start); } it->line.setfromf("<%s %s>",key.get(),val); } PUBLIC int VIEW_SECTION::locate_all (const char *key, VIEWITEMS &its) const { int ret = 0; its.neverdelete(); int lenkey = strlen(key); int item_counter = start + 1; VIEWITEM *it; int secnest = 0; // Nesting in various ... sections if ((end - start) < 2) return 0; while (((it=items->getitem(item_counter))!=NULL) && (item_counter < end)){ const char *s = it->line.get(); s = str_skip(s); if (s[0] == '<'){ if (s[1] == '/'){ secnest--; }else{ secnest++; } }else if (secnest == 0){ if (strncmp(s,key,lenkey)==0 && isspace(s[lenkey])){ its.add (it); ret++; } } item_counter++; } return ret; } PUBLIC int VIEW_SECTION::locate_all (const char *key, SSTRING_IDXS &tb) const { VIEWITEMS its; int ret = locate_all (key,its); for (int i=0; i... sections while ((it=itemss.getnext())!=NULL){ const char *s = it->line.get(); s = str_skip(s); if (s[0] == '<'){ if (s[1] == '/'){ secnest--; }else{ secnest++; } }else if (secnest == 0){ if (strncmp(s,key,lenkey)==0 && isspace(s[lenkey])){ its.add (it); ret++; } } } return ret; } PUBLIC int VIEW_MAIN::locate_all (const char *key, SSTRING_IDXS &tb) const { VIEWITEMS its; int ret = locate_all (key,its); for (int i=0; i 0) ret = its.getitem(0); return ret; } PUBLIC void VIEW_MAIN::add (VIEWITEM *it) { VIEWITEMS *first = itemss.getitem(0); if (first != NULL) first->insert(0,it); } PUBLIC VIEW_AREA::VIEW_AREA(const char *_keyword, VIEWITEMS_SUB &_sub) : sub(_sub) { keyword.setfrom (_keyword); insert_pos = 0; #if 0 for (int i=0; i