bool checkPackageMapMatchesTarget(const char *target, const char *match) { if (!match || !*match) return false; if (isWildString(match)) return WildMatch(target, match); return streq(target, match); }
/** Do a case insensitive find for the pattern. \param text The text to match an ignore pattern against. \return Returns true if the directory should be ignored, false otherwise. **/ bool FileGlobBase::MatchIgnorePattern( const char* text ) { for ( StringList::iterator it = m_ignorePatterns.begin(); it != m_ignorePatterns.end(); ++it ) { if ( WildMatch( (*it).c_str(), text, false ) ) return true; } return false; }
ForEachItemIn(idx, patterns) { bool match; const char *pattern = patterns.item(idx); if (strchr(pattern, '*')) { match = WildMatch(name, pattern, true); } else match = streq(name, pattern); if (match) return true; }
void GetNameInfo(void) { int i, found = false; char *sp, *sp2; time_t tloc; struct hostent *hp; struct sockaddr_in cin; #ifdef AIX char real_version[_SYS_NMLN]; #endif #ifdef IRIX char real_version[256]; /* see <sys/syssgi.h> */ #endif #ifdef HAVE_SYSINFO #ifdef SI_ARCHITECTURE long sz; #endif #endif Debug("GetNameInfo()\n"); g_vfqname[0] = g_vuqname[0] = '\0'; if (uname(&g_vsysname) == -1) { perror("uname "); FatalError("Uname couldn't get kernel name info!!\n"); } #ifdef AIX snprintf(real_version, _SYS_NMLN, "%.80s.%.80s", g_vsysname.version, g_vsysname.release); strncpy(g_vsysname.release, real_version, _SYS_NMLN); #elif defined IRIX /* This gets us something like `6.5.19m' rather than just `6.5'. */ syssgi (SGI_RELEASE_NAME, 256, real_version); #endif for (sp = g_vsysname.sysname; *sp != '\0'; sp++) { *sp = ToLower(*sp); } for (sp = g_vsysname.machine; *sp != '\0'; sp++) { *sp = ToLower(*sp); } for (i = 0; g_classattributes[i][0] != '\0'; i++) { if (WildMatch(g_classattributes[i][0], ToLowerStr(g_vsysname.sysname))) { if (WildMatch(g_classattributes[i][1], g_vsysname.machine)) { if (WildMatch(g_classattributes[i][2], g_vsysname.release)) { if (g_underscore_classes) { snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]); AddClassToHeap(g_vbuff); } else { AddClassToHeap(g_classtext[i]); } found = true; g_vsystemhardclass = (enum classes) i; break; } } else { Debug2("Cfengine: I recognize %s but not %s\n", g_vsysname.sysname, g_vsysname.machine); continue; } } } if ((sp = malloc(strlen(g_vsysname.nodename)+1)) == NULL) { FatalError("malloc failure in initialize()"); } strcpy(sp, g_vsysname.nodename); SetDomainName(sp); /* Truncate fully qualified name */ for (sp2=sp; *sp2 != '\0'; sp2++) { if (*sp2 == '.') { *sp2 = '\0'; Debug("Truncating fully qualified hostname %s to %s\n", g_vsysname.nodename,sp); break; } } g_vdefaultbinserver.name = sp; AddClassToHeap(CanonifyName(sp)); if ((tloc = time((time_t *)NULL)) == -1) { printf("Couldn't read system clock\n"); } if (g_verbose || g_debug || g_d2 || g_d3) { if (g_underscore_classes) { snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]); } else { snprintf(g_vbuff, CF_BUFSIZE, "%s", g_classtext[i]); } if (g_iscfengine) { printf ("cfng: configuration agent (cfagent) - \n%s\n%s\n\n", VERSION, g_copyright); } else { printf ("cfng: configuration server (cfservd) - \n%s\n%s\n\n", VERSION, g_copyright); } printf ("------------------------------------------------------------------------\n\n"); printf ("Host name is: %s\n", g_vsysname.nodename); printf ("Operating System Type is %s\n", g_vsysname.sysname); printf ("Operating System Release is %s\n", g_vsysname.release); printf ("Architecture = %s\n\n\n", g_vsysname.machine); printf ("Using internal soft-class %s for host %s\n\n", g_vbuff, g_classtext[g_vsystemhardclass]); printf ("The time is now %s\n\n", ctime(&tloc)); printf ("------------------------------------------------------------------------\n\n"); } sprintf(g_vbuff, "%d_bit", sizeof(long)*8); AddClassToHeap(g_vbuff); Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff)); snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname, g_vsysname.release); AddClassToHeap(CanonifyName(g_vbuff)); #ifdef IRIX /* * Get something like `irix64_6_5_19m' defined as well as * `irix64_6_5'. Just copying the latter into g_vsysname.release * wouldn't be backwards-compatible. */ snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname, real_version); AddClassToHeap(CanonifyName(g_vbuff)); #endif AddClassToHeap(CanonifyName(g_vsysname.machine)); Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff)); snprintf(g_vbuff, CF_BUFSIZE,"%s_%s", g_vsysname.sysname, g_vsysname.machine); AddClassToHeap(CanonifyName(g_vbuff)); Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff)); snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s", g_vsysname.sysname, g_vsysname.machine, g_vsysname.release); AddClassToHeap(CanonifyName(g_vbuff)); Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff)); #ifdef HAVE_SYSINFO #ifdef SI_ARCHITECTURE sz = sysinfo(SI_ARCHITECTURE, g_vbuff, CF_BUFSIZE); if (sz == -1) { Verbose("cfagent internal: sysinfo returned -1\n"); } else { AddClassToHeap(CanonifyName(g_vbuff)); Verbose("Additional hard class defined as: %s\n", g_vbuff); } #endif #endif snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s_%s", g_vsysname.sysname, g_vsysname.machine, g_vsysname.release, g_vsysname.version); if (strlen(g_vbuff) < CF_MAXVARSIZE-2) { g_varch = strdup(CanonifyName(g_vbuff)); } else { Verbose("cfagent internal: $(arch) overflows CF_MAXVARSIZE! Truncating\n"); g_varch = strdup(CanonifyName(g_vsysname.sysname)); } snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname, g_vsysname.machine); g_varch2 = strdup(CanonifyName(g_vbuff)); AddClassToHeap(g_varch); Verbose("Additional hard class defined as: %s\n", g_varch); if (! found) { CfLog(cferror,"Cfengine: I don't understand " "what architecture this is!",""); } strcpy(g_vbuff, "compiled_on_"); strcat(g_vbuff, CanonifyName(AUTOCONF_SYSNAME)); AddClassToHeap(CanonifyName(g_vbuff)); Verbose("\nGNU autoconf class from compile time: %s\n\n", g_vbuff); /* Get IP address from nameserver */ if ((hp = gethostbyname(g_vsysname.nodename)) == NULL) { return; } else { memset(&cin, 0, sizeof(cin)); cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; Verbose("Address given by nameserver: %s\n", inet_ntoa(cin.sin_addr)); strcpy(g_vipaddress, inet_ntoa(cin.sin_addr)); for (i=0; hp->h_aliases[i] != NULL; i++) { Debug("Adding alias %s..\n", hp->h_aliases[i]); AddClassToHeap(CanonifyName(hp->h_aliases[i])); } } }
bool FileUtils::WildMatch(const wxString& mask, const wxString& filename) { return WildMatch(mask, wxFileName(filename)); }
void next(size_t maxfilenamesize, char *outfilename, bool &isdir, rfs_fpos_t &filesizeout, time_t &outmodifiedtime) { #ifdef _WIN32 WIN32_FIND_DATA info; bool nocase = true; #else struct dirent *entry; bool nocase = false; #endif while (1) { *outfilename = 0; if (level<0) return; if (first) { first = false; handles = (_Handle *)realloc(handles,sizeof(_Handle)*(level+1)); #ifdef _WIN32 path.appendc('*'); handles[level] = FindFirstFile(path.str(), &info); path.decLength(); #else handles[level] = opendir(path.str()); if (handles[level]) entry = readdir(handles[level]); // don't need _r here #endif } else { #ifdef _WIN32 if (!FindNextFile(handles[level], &info)) { FindClose(handles[level]); #else entry = readdir(handles[level]); // don't need _r here if (!entry) { closedir(handles[level]); #endif handles[level] = INVALID_HANDLE_VALUE; } } if (handles[level]!=INVALID_HANDLE_VALUE) { free(tail); #ifdef _WIN32 tail = _strdup(info.cFileName); isdir = ((info.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0); #else tail = _strdup(entry->d_name); #endif size_t hs = path.length()-pathhead; size_t ts = strlen(tail); if (hs>=maxfilenamesize) hs = maxfilenamesize-1; if (hs+ts>=maxfilenamesize) ts = maxfilenamesize-1-hs; memcpy(outfilename,path.str()+pathhead,hs); memcpy(outfilename+hs,tail,ts); outfilename[hs+ts] = 0; #ifndef _WIN32 struct stat info; if (stat(outfilename, &info) != 0) // will follow link continue; isdir = S_ISDIR(info.st_mode); #endif if ((strcmp(tail,".")==0)||(strcmp(tail,"..")==0)) continue; bool matched = (mask&&*mask)?WildMatch(tail,mask,nocase):false; if (!matched&&(!recursive||!isdir)) continue; if (isdir&&!recursive&&!includedirs) continue; if (isdir) { if (recursive) { // add name path.appends(tail); if (path.lastChar()!='\\') path.appendc('\\'); first = true; level++; } if (!includedirs||!matched) continue; filesizeout = (rfs_fpos_t)0; } else { #ifdef _WIN32 LARGE_INTEGER x; x.LowPart = info.nFileSizeLow; x.HighPart = info.nFileSizeHigh; filesizeout = (rfs_fpos_t)x.QuadPart; } outmodifiedtime = FileTimeToUnixTime(&info.ftLastWriteTime); #else filesizeout = info.st_size; } outmodifiedtime = info.st_mtime; #endif break; } level--; if (level<0) return; if (path.lastChar()=='\\') path.decLength(); while (path.length()) { if (path.lastChar()=='\\') break; path.decLength(); } } }
int FindMatches(struct Process *pp, struct Item *procdata, struct Item **killlist) { struct Item *ip, *ip2; char *sp,saveuid[16]; int pid=-1, ret, matches=0, got, i; regex_t rx,rxcache; regmatch_t pmatch; pid_t cfengine_pid = getpid(); char *names[CF_PROCCOLS]; /* ps headers */ int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; Debug2("Looking for process %s\n",pp->expr); if (CfRegcomp(&rxcache,pp->expr,REG_EXTENDED) != 0) { return 0; } GetProcessColumns(procdata->name,(char **)names,start,end); for (ip = procdata; ip != NULL; ip=ip->next) { /* To fix a bug on some implementations where rx gets emptied */ bcopy(&rxcache,&rx,sizeof(rx)); if (regexec(&rx,ip->name,1,&pmatch,0) == 0) { pid = -1; got = true; Debug("Regex %s matched %s\n",ip->name,pp->expr); for (ip2 = pp->inclusions; ip2 != NULL; ip2 = ip2->next) { got = false; if (strstr(ip->name,ip2->name) || WildMatch(ip2->name,ip->name)) { got = true; break; } } if (!got) { continue; } got = false; for (ip2 = pp->exclusions; ip2 != NULL; ip2 = ip2->next) { if (strstr(ip->name,ip2->name) || WildMatch(ip2->name,ip->name)) { got = true; break; } } if (!ProcessFilter(ip->name,pp->filters,names,start,end)) { Debug("%s Filtered away\n",ip->name); continue; } if (got) { continue; } Debug("Matched proc[%s]\n",ip->name); /* if first field contains alpha, skip */ for (sp = ip->name; *sp != '\0'; sp++) { while (true) { while (!isdigit((int)*sp) && (*sp != '\0')) { sp++; } /* Username contains number*/ if ((sp > ip->name) && isalnum((int)*(sp-1))) { sp++; } else { break; } } sscanf(sp,"%d",&pid); if (pid != -1) { break; } } if (pid == -1) { snprintf(g_output,CF_BUFSIZE*2, "Unable to extract pid while looking for %s\n", pp->expr); CfLog(cfverbose,g_output,""); continue; } Debug2("Found matching pid %d\n",pid); matches++; if (pid == 1 && pp->signal == cfhup) { Verbose("(Okay to send HUP to init)\n"); } else if (pid < 4) { Verbose("%s: will not signal or restart processes 0,1,2,3\n", g_vprefix); Verbose("%s: occurred while looking for %s\n", g_vprefix,pp->expr); continue; } if (pp->action == 'w') { snprintf(g_output,CF_BUFSIZE*2,"Process alert: %s\n", procdata->name); CfLog(cferror,g_output,""); snprintf(g_output,CF_BUFSIZE*2,"Process alert: %s\n",ip->name); CfLog(cferror,g_output,""); continue; } if (pp->signal != cfnosignal) { if (!g_dontdo) { if (pid == cfengine_pid) { CfLog(cfverbose,"Cfengine will not kill itself!\n",""); continue; } if (pp->action == 'm') { sprintf(saveuid,"%d",pid); PrependItem(killlist,saveuid,""); } else { if ((ret = kill((pid_t)pid,pp->signal)) < 0) { snprintf(g_output,CF_BUFSIZE*2, "Couldn't send signal to pid %d\n",pid); CfLog(cfverbose,g_output,"kill"); continue; } snprintf(g_output,CF_BUFSIZE*2, "Signalled process %d (%s) with %s\n",pid, pp->expr,g_signals[pp->signal]); CfLog(cfinform,g_output,""); if ((pp->signal == cfkill || pp->signal == cfterm) && ret >= 0) { snprintf(g_output, CF_BUFSIZE*2, "Killed: %s\n",ip->name); CfLog(cfinform,g_output,""); } } } } } } for (i = 0; i < CF_PROCCOLS; i++) { if (names[i] != NULL) { free(names[i]); } } regfree(&rx); return matches; }
////////////////////////////////////////////////////////////////////////////// // Compare a location/channel string against the filter string // filter_str contains a comma separated list of location/channel pairs // chan_str contatins a single location/channel // Wildcards *,? are allowed in filter_str, not in chan_str // Returns 1 if filter_str is NULL // Returns 1 if chan_str matches one of the filters // Returns 0 if chan_str does not match one of the filters // Returns -1 if there is a syntax error in filter_str int check_filter(const char *filter_str, const char *chan_str) { char *entry_ptr; char entry_str[16]; char pattern_str[4]; char target_str[4]; int i,j; if (filter_str == NULL) return 1; // Loop through each entry in filter_str for (entry_ptr = (char *)filter_str; *entry_ptr != 0;) { // Copy entry for (i=0; *entry_ptr != 0 && *entry_ptr != ','; i++, entry_ptr++) { entry_str[i] = *entry_ptr; if (i > 5) return -1; // loc/channel is never more than 6 chars } if (*entry_ptr == ',') entry_ptr++; entry_str[i] = 0; if (i < 2) return -1; // shortest legal filter is "/*" // Compare locations strncpy(target_str, chan_str, 2); target_str[2] = 0; for (i=0; i < 2; i++) { if (entry_str[0] == '/') { strcpy(pattern_str, " "); j = 2; break; } if (entry_str[i] != '/') { pattern_str[i] = entry_str[i]; } if (entry_str[i] == '/') break; } // Copy pattern location pattern_str[i] = 0; if (entry_str[i] != '/') return -1; // Syntax error in filter location if (!WildMatch(pattern_str, target_str)) continue; // Match channel strings strncpy(target_str, &chan_str[3], 3); target_str[3] = 0; strncpy(pattern_str, &entry_str[i+1], 3); pattern_str[3] = 0; if (strlen(entry_str) - i > 4) { if (gDebug) fprintf(stderr, "check_filter entry_str '%s' %d > %d+%d+1\n", entry_str, strlen(entry_str), i,4); else syslog(LOG_ERR, "check_filter entry_str '%s' %d > %d+%d+1\n", entry_str, strlen(entry_str), i,4); return -1; // channel name too long } if (WildMatch(pattern_str, target_str)) { if (VERBOSE) fprintf(stderr, "Matched filter '%s' against '%s'\n", entry_str, chan_str); return 1; } } // loop through all filter pairs // If we get here then there was no match return 0; } // check_filter()
/** \internal Does all the actual globbing. \author Matthias Wandel ([email protected]) http://http://www.sentex.net/~mwandel/ \author Joshua Jensen ([email protected]) Matthias Wandel wrote the original C algorithm, which is contained in his Exif Jpeg header parser at http://www.sentex.net/~mwandel/jhead/ under the filename MyGlob.c. It should be noted that the MAJORITY of this function is his, albeit rebranded style-wise. I have made the following extensions: - Support for ignoring directories. - Perforce-style (and DJGPP-style) ... for recursion, instead of **. - Automatic conversion from ...Stuff to .../*Stuff. Allows lookup of files by extension, too: '....h' translates to '.../*.h'. - Ability to handle forward slashes and backslashes. - A minimal C++ class design. - Wildcard matching not based on FindFirstFile(). Should allow greater control in the future and patching in of the POSIX fnmatch() function on systems that support it. **/ void FileGlobBase::GlobHelper( const char* inPattern ) { char patternBuf[ _MAX_PATH * 2 ]; strcpy( patternBuf, inPattern ); DoRecursion: char basePath[ _MAX_PATH ]; char* basePathEndPtr = basePath; char* recurseAtPtr = NULL; // Split the path into base path and pattern to match against. bool hasWildcard = false; char* pattern; for ( pattern = patternBuf; *pattern != '\0'; ++pattern ) { char ch = *pattern; // Is it a '?' ? if ( ch == '?' ) hasWildcard = true; // Is it a '*' ? else if ( ch == '*' ) { hasWildcard = true; // Is there a '**'? if ( pattern[ 1 ] == '*' ) { // If we're just starting the pattern or the characters immediately // preceding the pattern are a drive letter ':' or a directory path // '/', then set up the internals for later recursion. if ( pattern == patternBuf || pattern[ -1 ] == '/' || pattern[ -1 ] == ':') { char ch2 = pattern[ 2 ]; if ( ch2 == '/' ) { recurseAtPtr = pattern; memcpy(pattern, pattern + 3, strlen( pattern ) - 2 ); } else if ( ch2 == '\0' ) { recurseAtPtr = pattern; *pattern = '\0'; } } } } // Is there a '/' or ':' in the pattern at this location? if ( ch == '/' || ch == ':' ) { if ( hasWildcard ) break; basePathEndPtr = &basePath[ pattern - patternBuf + 1 ]; } } // If there is no wildcard this time, then just add the current file and // get out of here. if ( !hasWildcard ) { // This should refer to a file. FoundMatch( patternBuf ); return; } // Did we make it to the end of the pattern? If so, we should match files, // since there were no slashes encountered. bool matchFiles = *pattern == '\0'; // Copy the directory down. size_t basePathLen = basePathEndPtr - basePath; strncpy( basePath, patternBuf, basePathLen ); // Copy the wildcard matching string. char matchPattern[ _MAX_PATH ]; size_t matchLen = ( pattern - patternBuf ) - basePathLen; strncpy( matchPattern, patternBuf + basePathLen, matchLen + 1 ); if ( matchPattern[ matchLen ] == '/' ) matchPattern[ matchLen ] = 0; StringList fileList; // Do the file search with *.* in the directory specified in basePattern. strcpy( basePathEndPtr, "*.*" ); // Start the find. WIN32_FIND_DATA fd; HANDLE handle = FindFirstFile( basePath, &fd ); // Clear out the *.* so we can use the original basePattern string. *basePathEndPtr = 0; // Any files found? if ( handle != INVALID_HANDLE_VALUE ) { for ( ;; ) { // Is the file a directory? if ( ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && !matchFiles ) { // Do a wildcard match. if ( WildMatch( matchPattern, fd.cFileName, false ) ) { // It matched. Let's see if the file should be ignored. bool ignore = false; // Knock out "." or ".." if they haven't already been. size_t len = strlen( fd.cFileName ); fd.cFileName[ len ] = '/'; fd.cFileName[ len + 1 ] = '\0'; // See if this is a directory to ignore. ignore = MatchIgnorePattern( fd.cFileName ); fd.cFileName[ len ] = 0; // Should this file be ignored? if ( !ignore ) { // Nope. Add it to the linked list. fileList.push_back( fd.cFileName ); } } } else if ( !( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && matchFiles ) { // Do a wildcard match. if ( WildMatch( matchPattern, fd.cFileName, false ) ) { // It matched. Let's see if the file should be ignored. bool ignore = MatchIgnorePattern( fd.cFileName ); // Is this pattern exclusive? if ( !ignore && m_exclusiveFilePatterns.begin() != m_exclusiveFilePatterns.end() ) { ignore = !MatchExclusivePattern( fd.cFileName ); } // Should this file be ignored? if ( !ignore ) { // Nope. Add it to the linked list. fileList.push_back( fd.cFileName ); } } } // Look up the next file. if ( !FindNextFile( handle, &fd ) ) break; } // Close down the file find handle. FindClose( handle ); } // Sort the list. fileList.sort(); // Iterate the file list and either recurse or add the file as a found // file. if ( !matchFiles ) { for ( StringList::iterator it = fileList.begin(); it != fileList.end(); ++it ) { char combinedName[ _MAX_PATH * 2 ]; // Need more directories. CatPath( combinedName, basePath, (*it).c_str() ); strcat( combinedName, pattern ); GlobHelper( combinedName ); } } else // if ( !matchFiles ) { for ( StringList::iterator it = fileList.begin(); it != fileList.end(); ++it ) { char combinedName[ _MAX_PATH * 2 ]; CatPath( combinedName, basePath, (*it).c_str()); FoundMatch( combinedName ); } } // Clear out the file list, so the goto statement below can recurse // internally. fileList.clear(); // Do we need to recurse? if ( !recurseAtPtr ) return; // Copy in the new recursive pattern to match. strcpy( matchPattern, recurseAtPtr ); strcpy( recurseAtPtr, "*/**/" ); strcat( patternBuf, matchPattern ); // As this function context is no longer needed, we can just go back // to the top of it to avoid adding another context on the stack. goto DoRecursion; }