int TrueVar(char *var) { char buff[CF_EXPANDSIZE]; char varbuf[CF_MAXVARSIZE]; if (GetMacroValue(CONTEXTID,var)) { snprintf(varbuf,CF_MAXVARSIZE,"$(%s)",var); ExpandVarstring(varbuf,buff,NULL); if (strcmp(ToLowerStr(buff),"on") == 0) { return true; } if (strcmp(ToLowerStr(buff),"true") == 0) { return true; } } return false; }
CString CThread::ParseArchiverCmdLine() { WORD wPos = 0; WORD wResPos = 0; WORD wLen = m_sArchiverCmdLine.Length(); TCHAR res[MAX_PATH] = {0}; while (wPos < wLen) { if (m_sArchiverCmdLine[wPos] != TEXT('%')) { res[wResPos] = m_sArchiverCmdLine[wPos]; wPos++; wResPos++; } else if (m_sArchiverCmdLine[wPos] == TEXT('%') && wPos + 1 < wLen && m_sArchiverCmdLine[wPos + 1] == TEXT('%')) { // Двойной процент ('%%') считаем за один, не макрос res[wResPos] = TEXT('%'); wPos += 2; wResPos++; } else if (m_sArchiverCmdLine[wPos] == TEXT('%')) { CString sMacro; wPos++; WORD wMacroStart = wPos; while (wPos < wLen) { if (m_sArchiverCmdLine[wPos] != TEXT('%')) wPos++; else if (m_sArchiverCmdLine[wPos] == TEXT('%')) { sMacro = m_sArchiverCmdLine.SubStr(wMacroStart, wPos - wMacroStart).ToLowerNew(); CString sMacroValue; while (true) { if ((sMacro[0] >= TEXT('a') && sMacro[0] <= TEXT('z')) || (sMacro[0] >= TEXT('A') && sMacro[0] <= TEXT('Z'))) { break; } else { sMacroValue += sMacro[0]; sMacro.Delete(0, 1); } } if (sMacro == TEXT("compress")) { CString sCompress = FormatC(TEXT("compress%d"), m_TaskInfo.bArchCompress); sMacroValue += GetMacroValue(sCompress); lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else if (sMacro == TEXT("sfx") && m_TaskInfo.bArchSFX) { sMacroValue += GetMacroValue(TEXT("sfx")); lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else if (sMacro == TEXT("lock") && m_TaskInfo.bArchLock) { sMacroValue += GetMacroValue(TEXT("lock")); lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else if (sMacro == TEXT("taskcmd")) { sMacroValue += m_TaskInfo.sArchTaskCmd; lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else if (sMacro == TEXT("filelist")) { sMacroValue += TEXT("\""); sMacroValue += m_sFileList; sMacroValue += TEXT("\""); lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else if (sMacro == TEXT("archive")) { sMacroValue += TEXT("\""); sMacroValue += m_sDestFolder; sMacroValue += TEXT("\""); lstrcat(res, sMacroValue.C()); wResPos = lstrlen(res); wPos++; } else wPos++; break; } } } } return res; }
void CheckFriendConnections(int hours) /* Go through the database of recent connections and check for Long Time No See ...*/ { DBT key,value; DB *dbp; DBC *dbcp; DB_ENV *dbenv = NULL; int ret, secs = CF_TICKS_PER_HOUR*hours, criterion, overdue, regex=false; time_t now = time(NULL),lsea = -1, tthen, then = 0; char name[CF_BUFSIZE],hostname[CF_BUFSIZE],datebuf[CF_MAXVARSIZE]; char addr[CF_BUFSIZE],type[CF_BUFSIZE], *regexp; struct QPoint entry; double average = 0.0, var = 0.0, ticksperminute = 60.0; double ticksperhour = (double)CF_TICKS_PER_HOUR,ticksperday = (double)CF_TICKS_PER_DAY; regex_t rx,rxcache; regmatch_t pmatch; if (regexp = GetMacroValue(CONTEXTID,"IgnoreFriendRegex")) { Verbose("IgnoreFriendRegex %s\n\n",regexp); if ((ret = regcomp(&rx,regexp,REG_EXTENDED)) != 0) { regerror(ret,&rx,name,1023); snprintf(OUTPUT,CF_BUFSIZE,"Regular expression error %d for %s: %s\n",ret,regexp,name); CfLog(cfinform,OUTPUT,""); regex = false; } else { regex = true; } } Verbose("CheckFriendConnections(%d)\n",hours); snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE); if ((errno = db_create(&dbp,dbenv,0)) != 0) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } #ifdef CF_OLD_DB if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #else if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #endif { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } /* Acquire a cursor for the database. */ if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { CfLog(cferror,"Error reading from last-seen database",""); dbp->err(dbp, ret, "DB->cursor"); return; } /* Walk through the database and print out the key/data pairs. */ memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); while (dbcp->c_get(dbcp, &key, &value, DB_NEXT) == 0) { memset(&entry, 0, sizeof(entry)); strcpy(hostname,(char *)key.data); if (value.data != NULL) { memcpy(&entry,value.data,sizeof(entry)); then = (time_t)entry.q; average = (double)entry.expect; var = (double)entry.var; } else { continue; } /* Got data, now get expiry criterion */ if (secs == 0) { /* Twice the average delta is significant */ criterion = (now - then > (int)(average+2.0*sqrt(var)+0.5)); overdue = now - then - (int)(average); } else { criterion = (now - then > secs); overdue = (now - then - secs); } if (GetMacroValue(CONTEXTID,"LastSeenExpireAfter")) { lsea = atoi(GetMacroValue(CONTEXTID,"LastSeenExpireAfter")); lsea *= CF_TICKS_PER_DAY; } if (lsea < 0) { lsea = (time_t)CF_WEEK/7; } if (regex) { if (regexec(&rx,IPString2Hostname(hostname+1),1,&pmatch,0) == 0) { if ((pmatch.rm_so == 0) && (pmatch.rm_eo == strlen(hostname+1))) { Verbose("Not judging friend %s\n",hostname); criterion = false; lsea = CF_INFINITY; } } } tthen = (time_t)then; snprintf(datebuf,CF_BUFSIZE-1,"%s",ctime(&tthen)); datebuf[strlen(datebuf)-9] = '\0'; /* Chop off second and year */ snprintf(addr,15,"%s",hostname+1); switch(*hostname) { case '+': snprintf(type,CF_BUFSIZE,"last responded to hails"); break; case'-': snprintf(type,CF_BUFSIZE,"last hailed us"); break; } snprintf(OUTPUT,CF_BUFSIZE,"Host %s i.e. %s %s @ [%s] (overdue by %d mins)", IPString2Hostname(hostname+1), addr, type, datebuf, overdue/(int)ticksperminute); if (criterion) { CfLog(cferror,OUTPUT,""); } else { CfLog(cfverbose,OUTPUT,""); } snprintf(OUTPUT,CF_BUFSIZE,"i.e. (%.2f) hrs ago, Av %.2f +/- %.2f hrs\n", ((double)(now-then))/ticksperhour, average/ticksperhour, sqrt(var)/ticksperhour); if (criterion) { CfLog(cferror,OUTPUT,""); } else { CfLog(cfverbose,OUTPUT,""); } if ((now-then) > lsea) { snprintf(OUTPUT,CF_BUFSIZE,"Giving up on host %s -- too long since last seen",IPString2Hostname(hostname+1)); CfLog(cferror,OUTPUT,""); DeleteDB(dbp,hostname); } memset(&value,0,sizeof(value)); memset(&key,0,sizeof(key)); } dbcp->c_close(dbcp); dbp->close(dbp,0); }
void LastSeen(char *hostname,enum roles role) { DB *dbp,*dbpent; DB_ENV *dbenv = NULL, *dbenv2 = NULL; char name[CF_BUFSIZE],databuf[CF_BUFSIZE]; time_t now = time(NULL); struct QPoint q,newq; double lastseen,delta2; int lsea = -1; if (strlen(hostname) == 0) { snprintf(OUTPUT,CF_BUFSIZE,"LastSeen registry for empty hostname with role %d",role); CfLog(cflogonly,OUTPUT,""); return; } Debug("LastSeen(%s) reg\n",hostname); /* Tidy old versions - temporary */ snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_OLDLASTDB_FILE); unlink(name); if ((errno = db_create(&dbp,dbenv,0)) != 0) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't init last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE); #ifdef CF_OLD_DB if ((errno = (dbp->open)(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #else if ((errno = (dbp->open)(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #endif { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } /* Now open special file for peer entropy record - INRIA intermittency */ snprintf(name,CF_BUFSIZE-1,"%s/%s.%s",CFWORKDIR,CF_LASTDB_FILE,hostname); if ((errno = db_create(&dbpent,dbenv2,0)) != 0) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't init last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } #ifdef CF_OLD_DB if ((errno = (dbpent->open)(dbpent,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #else if ((errno = (dbpent->open)(dbpent,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #endif { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open last-seen database %s\n",name); CfLog(cferror,OUTPUT,"db_open"); return; } #ifdef HAVE_PTHREAD_H if (pthread_mutex_lock(&MUTEX_GETADDR) != 0) { CfLog(cferror,"pthread_mutex_lock failed","unlock"); exit(1); } #endif switch (role) { case cf_accept: snprintf(databuf,CF_BUFSIZE-1,"-%s",Hostname2IPString(hostname)); break; case cf_connect: snprintf(databuf,CF_BUFSIZE-1,"+%s",Hostname2IPString(hostname)); break; } #ifdef HAVE_PTHREAD_H if (pthread_mutex_unlock(&MUTEX_GETADDR) != 0) { CfLog(cferror,"pthread_mutex_unlock failed","unlock"); exit(1); } #endif if (GetMacroValue(CONTEXTID,"LastSeenExpireAfter")) { lsea = atoi(GetMacroValue(CONTEXTID,"LastSeenExpireAfter")); lsea *= CF_TICKS_PER_DAY; } if (lsea < 0) { lsea = CF_WEEK; } if (ReadDB(dbp,databuf,&q,sizeof(q))) { lastseen = (double)now - q.q; newq.q = (double)now; /* Last seen is now-then */ newq.expect = GAverage(lastseen,q.expect,0.3); delta2 = (lastseen - q.expect)*(lastseen - q.expect); newq.var = GAverage(delta2,q.var,0.3); } else { lastseen = 0.0; newq.q = (double)now; newq.expect = 0.0; newq.var = 0.0; } #ifdef HAVE_PTHREAD_H if (pthread_mutex_lock(&MUTEX_GETADDR) != 0) { CfLog(cferror,"pthread_mutex_lock failed","unlock"); exit(1); } #endif if (lastseen > (double)lsea) { Verbose("Last seen %s expired\n",databuf); DeleteDB(dbp,databuf); } else { WriteDB(dbp,databuf,&newq,sizeof(newq)); WriteDB(dbpent,GenTimeKey(now),&newq,sizeof(newq)); } #ifdef HAVE_PTHREAD_H if (pthread_mutex_unlock(&MUTEX_GETADDR) != 0) { CfLog(cferror,"pthread_mutex_unlock failed","unlock"); exit(1); } #endif dbp->close(dbp,0); dbpent->close(dbpent,0); }
void CheckFriendConnections(int hours) { DBT key,value; DB *dbp; DBC *dbcp; DB_ENV *dbenv = NULL; int ret, secs = 3600*hours, criterion; struct stat statbuf; time_t now = time(NULL),splaytime = 0; char name[CF_BUFSIZE]; static struct LastSeen entry; double average = 0; if (GetMacroValue(g_contextid,"SplayTime")) { splaytime = atoi(GetMacroValue(g_contextid,"SplayTime")); if (splaytime < 0) { splaytime = 0; } } Verbose("CheckFriendConnections(%d)\n",hours); snprintf(name,CF_BUFSIZE-1,"%s/%s",g_vlockdir,CF_LASTDB_FILE); if ((errno = db_create(&dbp,dbenv,0)) != 0) { snprintf(g_output, CF_BUFSIZE*2, "Couldn't open last-seen database %s\n", name); CfLog(cferror,g_output,"db_open"); return; } #ifdef CF_OLD_DB if ((errno = dbp->open(dbp,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #else if ((errno = dbp->open(dbp,NULL,name,NULL,DB_BTREE,DB_CREATE,0644)) != 0) #endif { snprintf(g_output, CF_BUFSIZE*2, "Couldn't open last-seen database %s\n", name); CfLog(cferror,g_output,"db_open"); dbp->close(dbp,0); return; } /* Acquire a cursor for the database. */ if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { CfLog(cferror,"Error reading from last-seen database",""); dbp->err(dbp, ret, "DB->cursor"); return; } /* Initialize the key/data return pair. */ memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); memset(&entry, 0, sizeof(entry)); /* Walk through the database and print out the key/data pairs. */ while (dbcp->c_get(dbcp, &key, &value, DB_NEXT) == 0) { time_t then; bcopy(value.data,&then,sizeof(then)); if (value.data != NULL) { bcopy(value.data,&entry,sizeof(entry)); then = entry.lastseen; average = entry.expect_lastseen; } else { continue; } if (secs == 0) { criterion = now > then + splaytime + (int)(average+0.5); } else { criterion = now > then + splaytime + secs; } if ((int)average > CF_WEEK) { criterion = false; } /* anomalous couplings do not count*/ if (average < 1800) { criterion = false; } snprintf(g_output, CF_BUFSIZE, "Host %s last at %s\ti.e. not seen for %.2fhours\n\t" "(Expected <delta_t> = %.2f secs (= %.2f hours))", (char *)key.data,ctime(&then), (now-then) / 3600.0,average, average / 3600.0); if (criterion) { CfLog(cferror,g_output,""); if (now > CF_WEEK + then + splaytime + 2*3600) { snprintf(g_output, CF_BUFSIZE*2, "INFO: Giving up on %s, last seen more than " "a week ago at %s.", key.data, ctime(&then)); CfLog(cferror,g_output,""); if ((errno = dbp->del(dbp,NULL,&key,0)) != 0) { CfLog(cferror,"","db_store"); } } } else { CfLog(cfinform,g_output,""); } } dbcp->c_close(dbcp); dbp->close(dbp,0); }
int CheckForModule(char *actiontxt,char *args) { struct stat statbuf; char line[CF_BUFSIZE],command[CF_EXPANDSIZE],name[CF_MAXVARSIZE],content[CF_BUFSIZE],ebuff[CF_EXPANDSIZE],*sp; FILE *pp; int print; if (NOMODULES) { return false; } if (*actiontxt == '/') { snprintf(OUTPUT,CF_BUFSIZE,"Absolute module path (%s) should be named relative to the authorized module directory",actiontxt); CfLog(cferror,OUTPUT,""); } if (GetMacroValue(CONTEXTID,"moduledirectory")) { ExpandVarstring("$(moduledirectory)",ebuff,NULL); } else { snprintf(ebuff,CF_BUFSIZE,"%s/modules",VLOCKDIR); } AddSlash(ebuff); strcat(ebuff,actiontxt); if (stat(ebuff,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"(Plug-in %s not found)",ebuff); Banner(OUTPUT); return false; } if ((statbuf.st_uid != 0) && (statbuf.st_uid != getuid())) { snprintf(OUTPUT,CF_BUFSIZE*2,"Module %s was not owned by uid=%d executing cfagent\n",ebuff,getuid()); CfLog(cferror,OUTPUT,""); return false; } snprintf(OUTPUT,CF_BUFSIZE*2,"Plug-in `%s\'",actiontxt); Banner(OUTPUT); strcat(ebuff," "); if (BufferOverflow(ebuff,args)) { snprintf(OUTPUT,CF_BUFSIZE*2,"Culprit: class list for module (shouldn't happen)\n" ); CfLog(cferror,OUTPUT,""); return false; } strcat(ebuff,args); ExpandVarstring(ebuff,command,NULL); Verbose("Exec module [%s]\n",command); if ((pp = cfpopen(command,"r")) == NULL) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open pipe from %s\n",actiontxt); CfLog(cferror,OUTPUT,"cfpopen"); return false; } while (!feof(pp)) { if (ferror(pp)) /* abortable */ { snprintf(OUTPUT,CF_BUFSIZE*2,"Shell command pipe %s\n",actiontxt); CfLog(cferror,OUTPUT,"ferror"); break; } ReadLine(line,CF_BUFSIZE,pp); if (strlen(line) > CF_BUFSIZE - 80) { snprintf(OUTPUT,CF_BUFSIZE*2,"Line from module %s is too long to be sensible\n",actiontxt); CfLog(cferror,OUTPUT,""); break; } if (ferror(pp)) /* abortable */ { snprintf(OUTPUT,CF_BUFSIZE*2,"Shell command pipe %s\n",actiontxt); CfLog(cferror,OUTPUT,"ferror"); break; } print = false; for (sp = line; *sp != '\0'; sp++) { if (! isspace((int)*sp)) { print = true; break; } } switch (*line) { case '+': Verbose("Activated classes: %s\n",line+1); CheckClass(line+1,command); AddMultipleClasses(line+1); break; case '-': Verbose("Deactivated classes: %s\n",line+1); CheckClass(line+1,command); NegateCompoundClass(line+1,&VNEGHEAP); break; case '=': content[0] = '\0'; sscanf(line+1,"%[^=]=%[^\n]",name,content); Verbose("Defined Macro: %s, Value: %s\n",name,content); AddMacroValue(CONTEXTID,name,content); break; default: if (print) { snprintf(OUTPUT,CF_BUFSIZE,"%s: %s\n",actiontxt,line); CfLog(cferror,OUTPUT,""); } } } cfpclose(pp); return true; }