bool matchcharset(uchar *pat,uchar *chrs,uchar *codepage) { uchar buf[20],buf2[20]; if(strchr(pat,',')) { /* Match chrs and codepage */ mystrncpy(buf,pat,20); if(strchr(buf,',')) *strchr(buf,',')=0; mystrncpy(buf2,strchr(pat,',')+1,20); if(matchpattern(buf,chrs) && matchpattern(buf2,codepage)) return(TRUE); return(FALSE); } else { /* Match chrs only */ return matchpattern(pat,chrs); } }
/* walk -- walk through a tree, evaluating nodes */ extern List *walk(Tree *tree0, Binding *binding0, int flags) { Tree *volatile tree = tree0; Binding *volatile binding = binding0; SIGCHK(); top: if (tree == NULL) return true; switch (tree->kind) { case nConcat: case nList: case nQword: case nVar: case nVarsub: case nWord: case nThunk: case nLambda: case nCall: case nPrim: { List *list; Ref(Binding *, bp, binding); list = glom(tree, binding, TRUE); binding = bp; RefEnd(bp); return eval(list, binding, flags); } case nAssign: return assign(tree->u[0].p, tree->u[1].p, binding); case nLet: case nClosure: Ref(Tree *, body, tree->u[1].p); binding = letbindings(tree->u[0].p, binding, binding, flags); tree = body; RefEnd(body); goto top; case nLocal: return local(tree->u[0].p, tree->u[1].p, binding, flags); case nFor: return forloop(tree->u[0].p, tree->u[1].p, binding, flags); case nMatch: return matchpattern(tree->u[0].p, tree->u[1].p, binding); case nExtract: return extractpattern(tree->u[0].p, tree->u[1].p, binding); default: panic("walk: bad node kind %d", tree->kind); } NOTREACHED; }
struct xlat *findpostxlat(struct var *var,uchar *ichrs,uchar *destpat) { uchar chrs[20]; struct xlat *xlat; struct xlatalias *xlatalias; mystrncpy(chrs,ichrs,20); /* Set charset if missing */ if(chrs[0] == 0 && var->defaultpostchrs[0] != 0) mystrncpy(chrs,var->defaultpostchrs,20); /* Replace if an alias */ for(xlatalias=var->firstpostalias;xlatalias;xlatalias=xlatalias->next) if(matchpattern(xlatalias->pattern,chrs)) break; if(xlatalias) mystrncpy(chrs,xlatalias->replace,20); /* Find in list */ if(destpat) { for(xlat=var->firstpostxlat;xlat;xlat=xlat->next) if(matchpattern(xlat->fromchrs,chrs) && matchpattern(destpat,xlat->tochrs)) break; } else { for(xlat=var->firstpostxlat;xlat;xlat=xlat->next) if(matchpattern(xlat->fromchrs,chrs)) break; } return(xlat); }
bool checkallow(struct var *var,uchar *ip) { FILE *fp; uchar s[1000],cfgip[100],cfgreadgroups[50],cfgpostgroups[50]; int res1,res2,res3; ulong pos,line; if(!(fp=fopen(cfg_allowfile,"r"))) { os_logwrite("(%s) Can't read allow file %s",var->clientid,cfg_allowfile); return(FALSE); } line=0; while(fgets(s,999,fp)) { line++; strip(s); pos=0; if(s[0]!=0 && s[0]!='#') { res1=getcfgword(s,&pos,cfgip,100); res2=getcfgword(s,&pos,cfgreadgroups,50); res3=getcfgword(s,&pos,cfgpostgroups,50); if(res1) { if(matchpattern(cfgip,ip)) { if(res2) strcpy(var->readgroups,cfgreadgroups); if(res3) strcpy(var->postgroups,cfgpostgroups); fclose(fp); return(TRUE); } } else { os_logwrite("(%s) Syntax error on line %lu in %s, skipping line",var->clientid,line,cfg_allowfile); } } } fclose(fp); return(FALSE); }
struct xlat *findreadxlat(struct var *var,struct group *group,uchar *ichrs,uchar *icodepage,uchar *destpat) { uchar chrs[20],codepage[20]; struct xlat *xlat; struct xlatalias *xlatalias; mystrncpy(chrs,ichrs,20); mystrncpy(codepage,icodepage,20); /* Do override */ if(group->defaultchrs[0] == '!') setchrscodepage(chrs,codepage,&group->defaultchrs[1]); else if(var->defaultreadchrs[0] == '!') setchrscodepage(chrs,codepage,&var->defaultreadchrs[1]); /* Set charset if missing */ if(chrs[0] == 0 && group->defaultchrs[0] != 0 && group->defaultchrs[0] != '!') setchrscodepage(chrs,codepage,group->defaultchrs); if(chrs[0] == 0 && var->defaultreadchrs[0] != 0 && var->defaultreadchrs[0] != '!') setchrscodepage(chrs,codepage,var->defaultreadchrs); /* Replace if an alias */ for(xlatalias=var->firstreadalias;xlatalias;xlatalias=xlatalias->next) if(matchcharset(xlatalias->pattern,chrs,codepage)) break; if(xlatalias) setchrscodepage(chrs,codepage,xlatalias->replace); /* Find in list */ if(destpat) { for(xlat=var->firstreadxlat;xlat;xlat=xlat->next) if(matchcharset(xlat->fromchrs,chrs,codepage) && matchpattern(destpat,xlat->tochrs)) break; } else { for(xlat=var->firstreadxlat;xlat;xlat=xlat->next) if(matchcharset(xlat->fromchrs,chrs,codepage)) break; } return(xlat); }
/* ==================== Curl_FindPackURL finds the URL where to find a given package. For this, it reads a file "curl_urls.txt" of the following format: data*.pk3 - revdm*.pk3 http://revdm/downloads/are/here/ * http://any/other/stuff/is/here/ The URLs should end in /. If not, downloads will still work, but the cached files can't be just put into the data directory with the same download configuration (you might want to do this if you want to tag downloaded files from your server, but you should not). "-" means "don't download". If no single pattern matched, the cvar sv_curl_defaulturl is used as download location instead. Note: pak1.pak and data*.pk3 are excluded from autodownload at another point in this file for obvious reasons. ==================== */ static const char *Curl_FindPackURL(const char *filename) { static char foundurl[1024]; fs_offset_t filesize; char *buf = (char *) FS_LoadFile("curl_urls.txt", tempmempool, true, &filesize); if(buf && filesize) { // read lines of format "pattern url" char *p = buf; char *pattern = NULL, *patternend = NULL, *url = NULL, *urlend = NULL; qboolean eof = false; pattern = p; while(!eof) { switch(*p) { case 0: eof = true; // fallthrough case '\n': case '\r': if(pattern && url && patternend) { if(!urlend) urlend = p; *patternend = 0; *urlend = 0; if(matchpattern(filename, pattern, true)) { strlcpy(foundurl, url, sizeof(foundurl)); Z_Free(buf); return foundurl; } } pattern = NULL; patternend = NULL; url = NULL; urlend = NULL; break; case ' ': case '\t': if(pattern && !patternend) patternend = p; else if(url && !urlend) urlend = p; break; default: if(!pattern) pattern = p; else if(pattern && patternend && !url) url = p; break; } ++p; } } if(buf) Z_Free(buf); return sv_curl_defaulturl.string; }
// reads all pak files from a dir void InitDirectory(const char* directory, ArchiveModules& archiveModules) { int j; g_numForbiddenDirs = 0; StringTokeniser st(GlobalRadiant().getGameDescriptionKeyValue("forbidden_paths"), " "); for(j = 0; j < VFS_MAXDIRS; ++j) { const char *t = st.getToken(); if(string_empty(t)) break; strncpy(g_strForbiddenDirs[g_numForbiddenDirs], t, PATH_MAX); g_strForbiddenDirs[g_numForbiddenDirs][PATH_MAX] = '\0'; ++g_numForbiddenDirs; } for(j = 0; j < g_numForbiddenDirs; ++j) { char* dbuf = g_strdup(directory); if(*dbuf && dbuf[strlen(dbuf)-1] == '/') dbuf[strlen(dbuf)-1] = 0; const char *p = strrchr(dbuf, '/'); p = (p ? (p+1) : dbuf); if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) { g_free(dbuf); break; } g_free(dbuf); } if(j < g_numForbiddenDirs) { printf("Directory %s matched by forbidden dirs, removed\n", directory); return; } if (g_numDirs == VFS_MAXDIRS) return; strncpy(g_strDirs[g_numDirs], directory, PATH_MAX); g_strDirs[g_numDirs][PATH_MAX] = '\0'; FixDOSName (g_strDirs[g_numDirs]); AddSlash (g_strDirs[g_numDirs]); const char* path = g_strDirs[g_numDirs]; g_numDirs++; { archive_entry_t entry; entry.name = path; entry.archive = OpenArchive(path); entry.is_pakfile = false; g_archives.push_back(entry); } if (g_bUsePak) { GDir* dir = g_dir_open (path, 0, 0); if (dir != 0) { globalOutputStream() << "vfs directory: " << path << "\n"; const char* ignore_prefix = ""; const char* override_prefix = ""; { // See if we are in "sp" or "mp" mapping mode const char* gamemode = gamemode_get(); if (strcmp (gamemode, "sp") == 0) { ignore_prefix = "mp_"; override_prefix = "sp_"; } else if (strcmp (gamemode, "mp") == 0) { ignore_prefix = "sp_"; override_prefix = "mp_"; } } Archives archives; Archives archivesOverride; for(;;) { const char* name = g_dir_read_name(dir); if(name == 0) break; for(j = 0; j < g_numForbiddenDirs; ++j) { const char *p = strrchr(name, '/'); p = (p ? (p+1) : name); if(matchpattern(p, g_strForbiddenDirs[j], TRUE)) break; } if(j < g_numForbiddenDirs) continue; const char *ext = strrchr (name, '.'); if(ext && !string_compare_nocase_upper(ext, ".pk3dir")) { if (g_numDirs == VFS_MAXDIRS) continue; snprintf(g_strDirs[g_numDirs], PATH_MAX, "%s%s/", path, name); g_strDirs[g_numDirs][PATH_MAX] = '\0'; FixDOSName (g_strDirs[g_numDirs]); AddSlash (g_strDirs[g_numDirs]); g_numDirs++; { archive_entry_t entry; entry.name = g_strDirs[g_numDirs-1]; entry.archive = OpenArchive(g_strDirs[g_numDirs-1]); entry.is_pakfile = false; g_archives.push_back(entry); } } if ((ext == 0) || *(++ext) == '\0' || GetArchiveTable(archiveModules, ext) == 0) continue; // using the same kludge as in engine to ensure consistency if(!string_empty(ignore_prefix) && strncmp(name, ignore_prefix, strlen(ignore_prefix)) == 0) { continue; } if(!string_empty(override_prefix) && strncmp(name, override_prefix, strlen(override_prefix)) == 0) { archivesOverride.insert(name); continue; } archives.insert(name); } g_dir_close (dir); // add the entries to the vfs for(Archives::iterator i = archivesOverride.begin(); i != archivesOverride.end(); ++i) { char filename[PATH_MAX]; strcpy(filename, path); strcat(filename, (*i).c_str()); InitPakFile(archiveModules, filename); } for(Archives::iterator i = archives.begin(); i != archives.end(); ++i) { char filename[PATH_MAX]; strcpy(filename, path); strcat(filename, (*i).c_str()); InitPakFile(archiveModules, filename); } } else { globalErrorStream() << "vfs directory not found: " << path << "\n"; } } }