19 #include "nomos_regex.h"
20 #include "nomos_utils.h"
22 #define MM_CACHESIZE 20
25 #ifdef REUSE_STATIC_MEMORY
26 static char grepzone[10485760];
33 static char utilbuf[myBUFSIZ];
35 static char cmdBuf[512];
39 #define MEMCACHESIZ 200000
40 static int memlast = -1;
41 static struct mm_cache memcache[MEMCACHESIZ];
53 traceFunc(
"== isDIR(%s)\n", dpath);
56 return(
isINODE(dpath, S_IFDIR));
68 traceFunc(
"== isEMPTYFILE(%s)\n", fpath);
74 return(cur.stbuf.st_size == 0);
86 traceFunc(
"== isBLOCK(%s)\n", bpath);
89 return(
isINODE(bpath, S_IFBLK));
101 traceFunc(
"== isCHAR(%s)\n", cpath);
104 return(
isINODE(cpath, S_IFCHR));
116 traceFunc(
"== isPIPE(%s)\n", ppath);
119 return(
isINODE(ppath, S_IFIFO));
131 traceFunc(
"== isSYMLINK(%s)\n", spath);
134 return(
isINODE(spath, S_IFLNK));
146 char sErrorBuf[1024];
149 traceFunc(
"== isINODE(%s, 0x%x)\n", ipath, typ);
152 if ((ret = stat(ipath, &cur.stbuf)) < 0) {
158 if (errno == ENOENT) {
161 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
162 LOG_ERROR(
"Error: %s getting stat on file: %s", sErrorBuf, ipath)
167 return((
int)(cur.stbuf.st_mode & S_IFMT & typ));
177 static char newpath[myBUFSIZ];
181 traceFunc(
"== newReloTarget(%s)\n", basename);
185 (void) sprintf(newpath,
"%s_%s-renamed.%03d", basename, gl.
progName, i);
186 if (access(newpath, F_OK) && errno == ENOENT) {
191 LOG_FATAL(
"%s: no suitable relocation target (%d tries)", basename, i)
199 #ifdef MEMORY_TRACING
205 char *memAllocTagged(
int size,
char *name)
215 #if defined(PROC_TRACE) || defined(MEM_ACCT)
216 traceFunc(
"== memAllocTagged(%d, \"%s\")\n",
size, name);
220 LOG_FATAL(
"Cannot alloc %d bytes!",
size)
223 if (++memlast == MEMCACHESIZ) {
224 LOG_FATAL(
"*** memAllocTagged: out of memcache entries")
228 if ((ptr = calloc((
size_t) 1, (
size_t)
size)) == (
void *) NULL) {
229 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
230 LOG_FATAL(
"calloc for %s, error: %s", name, sErrorBuf)
234 if ((ptr = malloc((
size_t)
size)) == (
void *) NULL) {
235 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
236 LOG_FATAL(
"malloc for %s, error: %s", name, sErrorBuf)
239 (void) memset(ptr, 0, (
size_t)
size);
241 #if DEBUG > 3 || defined(MEM_ACCT)
242 printf(
"+%p:%p=(%d)\n", ptr, ptr+
size-1,
size);
244 memcache[memlast].mmPtr = ptr;
245 memcache[memlast].size =
size;
246 (void) strcpy(memcache[memlast].
label, name);
248 printf(
"memAllocTagged(%d, \"%s\") == %p [entry %04d]\n",
size, name, ptr,
256 void memFreeTagged(
void *ptr,
char *note)
261 #if defined(PROC_TRACE) || defined(MEM_ACCT)
262 traceFunc(
"== memFree(%p, \"%s\")\n", ptr, note);
265 #ifdef MEMORY_TRACING
266 DEBUG(
"mprobe(%p)\n", ptr)
269 for (mmp = memcache, i = 0; i <= memlast; mmp++, i++) {
270 if (mmp->
mmPtr == ptr) {
272 printf(
"memFree(%p, \"%s\") is entry %04d (%d bytes)\n", ptr, note, i,
279 LOG_FATAL(
"Could not locate %p to free!", ptr)
283 #if DEBUG > 3 || defined(MEM_ACCT)
284 printf(
"-%p=(%d)\n", ptr, mmp->
size);
287 (void) memmove(&memcache[i], &memcache[i+1],
288 (memlast-i)*
sizeof(
struct mm_cache));
290 memset(&memcache[memlast], 0,
sizeof(
struct mm_cache));
293 memCacheDump(
"post-memFree:");
299 void memCacheDump(
char *
s)
302 static int first = 1;
309 printf(
"%%%%%% mem-cache is EMPTY\n");
312 start = (memlast > 50 ? memlast-50 : 0);
313 printf(
"%%%%%% mem-cache @ %p [last=%d]\n", memcache, memlast);
314 for (m = memcache+
start, i =
start; i <= memlast; m++, i++) {
315 printf(
"mem-entry %04d: %p (%d) - %s\n", i, m->
mmPtr,
318 printf(
"... \"%s\"\n", m->
mmPtr);
321 printf(
"%%%%%% mem-cache END\n");
345 traceFunc(
"== findBol(%p, %p)\n",
s, upperLimit);
351 for (cp =
s; cp > upperLimit; cp--) {
353 DEBUG(
"cp %p upperLimit %p\n", cp, upperLimit)
357 DEBUG(
"Got it! BOL == %p\n", cp)
359 return((
char*)(cp+1));
362 if (cp == upperLimit) {
364 DEBUG(
"AT upperLimit %p\n", upperLimit);
383 traceFunc(
"== findEol(%p)\n",
s);
412 char sErrorBuf[1024];
417 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG)
418 traceFunc(
"== renameInode(%s, %s)\n", oldpath, newpath);
422 (void)
mySystem(
"ls -ldi '%s'", oldpath);
424 if (rename(oldpath, newpath) < 0) {
425 if (errno == EXDEV) {
426 err =
mySystem(
"mv '%s' %s", oldpath, newpath);
432 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
433 LOG_FATAL(
"rename(%s, %s) error: %s", oldpath, newpath, sErrorBuf)
438 (void)
mySystem(
"ls -ldi %s", newpath);
452 char sErrorBuf[1024];
457 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG)
458 traceFunc(
"== chmodInode(%s, 0%o)\n", pathname, mode);
461 if (chmod(pathname, mode) < 0) {
462 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
463 LOG_FATAL(
"chmod(\"%s\", 0%o) error: %s", pathname, mode, sErrorBuf)
479 char sErrorBuf[1024];
486 traceFunc(
"== fopenFile(%s, \"%s\")\n", pathname, mode);
489 if ((fp = fopen(pathname, mode)) == (FILE *) NULL) {
490 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
491 LOG_FATAL(
"fopen(%s) error: %s", pathname, sErrorBuf);
524 char sErrorBuf[1024];
531 traceFunc(
"== popenProc(\"%s\", %s)\n", command, mode);
534 if ((pp = popen(command, mode)) == (FILE *) NULL) {
535 #ifdef MEMORY_TRACING
536 memCacheDump(
"Post-popen-failure:");
538 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
539 LOG_FATAL(
"popen(\"%s\") error: %s", command, sErrorBuf)
553 static char wcbuf[64];
558 traceFunc(
"== wordCount(%p)\n", textp);
562 for (cp = textp; *cp; cp++) {
578 (void) sprintf(wcbuf,
"%d lines", lines);
599 traceFunc(
"== copyString(%p, \"%s\")\n",
s,
label);
602 cp = memAlloc(len=(strlen(
s)+1),
label);
604 printf(
"+CS: %d @ %p\n", len, cp);
606 (void) strcpy(cp,
s);
620 traceFunc(
"== pathBasename(\"%s\")\n", path);
623 cp = strrchr(path,
'/');
624 return(cp ==
NULL_STR ? path : (
char *)(cp+1));
636 static char *ibuf = NULL;
637 static int bufmax = 0;
638 char *sep =
_REGEX(_UTIL_XYZZY);
649 int regexFlags = REG_ICASE|REG_EXTENDED;
651 #if defined(PROC_TRACE) || defined(PHRASE_DEBUG) || defined(DOCTOR_DEBUG)
652 traceFunc(
"== getInstances(%p, %d, %d, %d, \"%s\", %d)\n", textp,
size,
653 nBefore, nAfter, regex, recordOffsets);
656 if ((notDone =
strGrep(regex, textp, regexFlags)) == 0) {
658 printf(
"... no match: 1st strGrep()\n");
669 p->seqNo = cur.offList.
used;
672 if (p->bList) free(p->bList);
673 p->bList = (
list_t *)memAlloc(
sizeof(
list_t), MTAG_LIST);
674 (void) sprintf(utilbuf,
"\"%c%c%c%c%c%c%c%c%c%c\" match-list",
675 *regex, *(regex+1), *(regex+2), *(regex+3), *(regex+4),
676 *(regex+5), *(regex+6), *(regex+7), *(regex+8), *(regex+9));
678 printf(
"Creating %s\n", utilbuf);
684 LOG_FATAL(
"Called getInstances(%s) more than once", regex)
689 #ifdef REUSE_STATIC_MEMORY
692 bufmax =
sizeof(grepzone);
694 else if (ibuf != grepzone) {
697 bufmax =
sizeof(grepzone);
701 ibuf = memAlloc((bufmax = 1024*1024), MTAG_SEARCHBUF);
711 printf(
"getInstances: \"%s\" [#1] in buf [%d-%d]\n", regex,
712 cur.regm.rm_so, cur.regm.rm_eo-1);
713 printf(
"Really in the buffer: [");
714 for (cp = textp + cur.regm.rm_so; cp < (textp + cur.regm.rm_eo); cp++) {
725 fileeof = (
char *) (textp+
size);
729 printf(
"... found Match #%d\n", p->nMatch);
732 (void) sprintf(utilbuf,
"buf%05d", p->nMatch);
741 if ((nBefore > 0) && (
start > textp)) {
742 for (i = 0; (i < nBefore) && (
start > textp); i++) {
751 DEBUG(
"start = %p\n",
start)
756 bp->bStart =
start-textp;
774 curptr += cur.regm.rm_eo;
780 for (i = 0; end < fileeof; end++) {
786 LOG_FATAL(
"lost the end-of-line")
796 if ((end < fileeof) && *end) {
801 printf(
"Snippet, with %d lines below:\n----\n", nAfter);
802 for (cp =
start; cp < end; cp++) {
807 notDone =
strGrep(regex, curptr, regexFlags);
810 printf(
"... next match @ %d:%d (end=%d)\n",
811 curptr - textp + cur.regm.rm_so,
812 curptr - textp + cur.regm.rm_eo - 1, end - textp);
815 if ((curptr + cur.regm.rm_eo) > fileeof) {
820 if ((curptr + cur.regm.rm_eo) > end) {
835 bp->bLen = end-
start;
839 printf(
"%s starts @%d, len %d ends [%c%c%c%c%c%c%c]\n",
840 utilbuf, bp->bStart, bp->bLen, *(end-8), *(end-7),
841 *(end-6), *(end-5), *(end-4), *(end-3), *(end-2));
844 newDataLen = end-
start+(notDone ? strlen(sep)+1 : 0);
845 while (buflen+newDataLen > bufmax) {
848 Assert(
NO,
"data(%d) > bufmax(%d)", buflen+newDataLen,
853 printf(
"... DOUBLE search-pattern buffer (%d -> %d)\n",
856 new = memAlloc(bufmax, MTAG_DOUBLED);
857 (void) memcpy(
new, ibuf, buflen);
859 printf(
"REPLACING buf %p(%d) with %p(%d)\n", ibuf,
860 bufmax/2,
new, bufmax);
862 #ifdef REUSE_STATIC_MEMORY
863 if (ibuf != grepzone) {
871 cp = bufmark = ibuf+buflen-1;
872 buflen += newDataLen;
873 bufmark += sprintf(bufmark,
"%s",
start);
875 bufmark += sprintf(bufmark,
"%s\n", sep);
891 printf(
"Loop end, BUF IS NOW: [\"%s\":%d]\n----\n%s====\n",
892 regex, strlen(ibuf), ibuf);
896 #if defined(PHRASE_DEBUG) || defined(DOCTOR_DEBUG)
897 printf(
"getInstances(\"%s\"): Found %d bytes of data...\n", regex,
901 printf(
"getInstances(\"%s\"): buffer %p --------\n%s\n========\n",
915 static char datebuf[32];
920 (void) ctime_r(&thyme, datebuf);
921 if ((cp = strrchr(datebuf,
'\n')) ==
NULL_STR) {
922 LOG_FATAL(
"Unexpected time format from ctime_r()!")
931 void memStats(
char *
s)
933 static int first = 1;
934 static char mbuf[128];
938 sprintf(mbuf,
"grep VmRSS /proc/%d/status", getpid());
943 for (i = (
int) (strlen(
s)+2); i < 50; i++) {
949 system(
"grep Vm /proc/self/status");
950 system(
"grep Brk /proc/self/status");
962 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG)
963 traceFunc(
"== makeSymlink(%s)\n", path);
966 (void) sprintf(cmdBuf,
".%s", strrchr(path,
'/'));
967 if (symlink(path, cmdBuf) < 0) {
969 LOG_FATAL(
"Failed: symlink(%s, %s)", path, cmdBuf)
992 static char misc[64];
998 traceFunc(
"== printRegexMatch(%d, %d)\n", n, cached);
1008 save_so = cur.regm.rm_so;
1009 save_eo = cur.regm.rm_eo;
1015 printf(
"Match [%d:%d]\n", save_so, save_eo);
1018 (void) sprintf(misc,
"=#%03d", n);
1019 if (
strGrep(misc, textp, REG_EXTENDED)) {
1021 printf(
"Patt: %s\nMatch: %d:%d\n", misc,
1022 cur.regm.rm_so, cur.regm.rm_eo);
1024 x = textp + cur.regm.rm_so;
1025 cp = textp + cur.regm.rm_so;
1027 while (*--x !=
'[') {
1029 LOG_FATAL(
"Cannot locate debug symbol")
1034 (void) strncpy(misc, x, cp - x);
1037 (void) strcpy(misc,
"?");
1044 printf(
"RESTR [%d:%d]\n", cur.regm.rm_so, cur.regm.rm_eo);
1047 cur.regm.rm_so = save_so;
1048 cur.regm.rm_eo = save_eo;
1049 printf(
"%s regex %d ", cached ?
"Cached" :
"Found", n);
1051 printf(
"(%s) ", misc);
1054 printf(
"\"%s\"",
_REGEX(n));
1058 printf(
"Seed: \"%s\"\n",
_SEED(n));
1072 for (pBuf = Buffer; BufferSize--; pBuf++)
1073 if (*pBuf == 0) *pBuf =
' ';
1091 traceFunc(
"== mmapFile(%s)\n", pathname);
1094 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1095 if (mmp->
inUse == 0) {
1106 if ((mmp->
fd = open(pathname, O_RDONLY)) < 0) {
1107 if (errno == ENOENT) {
1110 mmp->
mmPtr = (
void *) NULL;
1112 printf(
"mmapFile: ENOENT %s\n", pathname);
1117 (void)
mySystem(
"ls -l %s", pathname);
1118 LOG_FATAL(
"%s: open failure!", pathname)
1122 if (fstat(mmp->
fd, &cur.stbuf) < 0) {
1123 printf(
"fstat failure!\n");
1127 if (S_ISDIR(cur.stbuf.st_mode)) {
1128 printf(
"mmapFile(%s): is a directory\n", pathname);
1132 (void) strcpy(mmp->
label, pathname);
1133 if (cur.stbuf.st_size)
1135 mmp->
size = cur.stbuf.st_size + 1;
1136 mmp->
mmPtr = memAlloc(mmp->
size, MTAG_MMAPFILE);
1138 printf(
"+MM: %lu @ %p\n", mmp->
size, mmp->
mmPtr);
1151 if ((n = (
int) read(mmp->
fd, cp, (
size_t) rem)) < 0) {
1155 LOG_WARNING(
"nomos read error: %s, file: %s, read size: %d, pfile_pk: %ld\n", strerror(errno), pathname, rem, cur.
pFileFk);
1164 return((
char *) mmp->
mmPtr);
1169 (void) close(mmp->
fd);
1171 Assert(
NO,
"mmapFile: returning NULL");
1177 void mmapOpenListing()
1182 printf(
"=== mm-cache BEGIN ===\n");
1183 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1185 printf(
"mm[%d]: (%d) %s:%d\n", i, mmp->
fd,
1189 printf(
"--- mm-cache END ---\n");
1203 traceFunc(
"== munmapFile(%p)\n", ptr);
1206 if (ptr == (
void *) NULL) {
1208 Assert(
NO,
"NULL sent to munmapFile()!");
1212 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1213 if (mmp->
inUse == 0) {
1216 if (mmp->
mmPtr == ptr) {
1218 printf(
"munmapFile: clearing entry %d\n", i);
1222 (void) munmap((
void *) ptr, (size_t) mmp->
size);
1225 if (close(mmp->
fd) < 0) {
1230 mmp->buf = (
void *) NULL;
1234 printf(
"DEBUG: munmapFile: freeing %lu bytes\n",
1256 char *eofaddr = NULL;
1260 traceFunc(
"== bufferLineCount(%p, %d)\n", p, len);
1266 eofaddr = (
char *) (p+len);
1267 for (i = 0, cp = p; cp <= eofaddr; cp++, i++) {
1273 printf(
"bufferLineCount == %d\n", i);
1288 traceFunc(
"== appendFile(%s, \"%s\")\n", pathname, str);
1292 fprintf(fp,
"%s\n", str);
1307 (void) vsprintf(cmdBuf, fmt, ap);
1310 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG)
1311 traceFunc(
"== mySystem('%s')\n", cmdBuf);
1314 ret = system(cmdBuf);
1315 if (WIFEXITED(ret)) {
1316 ret = WEXITSTATUS(ret);
1319 LOG_ERROR(
"system(%s) returns %d", cmdBuf, ret)
1323 else if (WIFSIGNALED(ret)) {
1324 ret = WTERMSIG(ret);
1325 LOG_ERROR(
"system(%s) died from signal %d", cmdBuf, ret)
1327 else if (WIFSTOPPED(ret)) {
1328 ret = WSTOPSIG(ret);
1329 LOG_ERROR(
"system(%s) stopped, signal %d", cmdBuf, ret)
1344 traceFunc(
"== isFILE(%s)\n", pathname);
1347 return(
isINODE(pathname, S_IFREG));
1358 int addEntry(
char *pathname,
int forceFlag,
const char *fmt, ...)
1361 vsprintf(utilbuf, fmt, ap);
1365 traceFunc(
"== addEntry(%s, %d, \"%s\")\n", pathname, forceFlag, utilbuf);
1369 Assert(
YES,
"addEntry - NULL pathname");
1371 if (forceFlag || !
lineInFile(pathname, utilbuf)) {
1382 void Msg(
const char *fmt, ...)
1385 (void) vprintf(fmt, ap);
1395 void Assert(
int fatalFlag,
const char *fmt, ...)
1398 (void) sprintf(utilbuf,
"ASSERT: ");
1399 (void) vsprintf(utilbuf+strlen(utilbuf), fmt, ap);
1403 traceFunc(
"!! Assert(\"%s\")\n", utilbuf+strlen(gl.
progName)+3);
1406 (void) strcat(utilbuf,
"\n");
1415 void traceFunc(
char *fmtStr, ...)
1419 #ifdef PROC_TRACE_SWITCH
1422 va_start(args, fmtStr);
1424 vprintf(fmtStr, args);
1426 #ifdef PROC_TRACE_SWITCH
1433 char *memAllocLogged(
int size)
1437 ptr = calloc(
size, 1);
1438 printf(
"%p = calloc( %d , 1 )\n", ptr,
size);
1442 void memFreeLogged(
void *ptr)
1444 printf(
"free( %p )\n", ptr);
int s
The socket that the CLI will use to communicate.
item_t * listGetItem(list_t *l, char *s)
get an item from the itemlist. If the item is not in the itemlist, then add it to the itemlist.
void listInit(list_t *l, int size, char *label)
intialize a list, if the list is not empty, empty it (initialize it to zero's).
char * findBol(char *s, char *upperLimit)
Find Begin of Line in a string.
int isSYMLINK(char *spath)
Check if given path is a symbolic link.
void munmapFile(void *ptr)
void ReplaceNulls(char *Buffer, int BufferSize)
Replace all nulls in Buffer with blanks.
FILE * fopenFile(char *pathname, char *mode)
Open a file and return the file pointer.
int isFILE(char *pathname)
Check if an inode is a file.
int isINODE(char *ipath, int typ)
Check for a inode against a flag.
int isEMPTYFILE(char *fpath)
Check if given file is empty.
void printRegexMatch(int n, int cached)
CDB – Need to review this code, particularly for the use of an external file (Nomos....
char * pathBasename(char *path)
Get the basename from a file path.
char * getInstances(char *textp, int size, int nBefore, int nAfter, char *regex, int recordOffsets)
Get occurrence of a regex in a given string pointer.
FILE * popenProc(char *command, char *mode)
Open a process pipe using popen()
int isDIR(char *dpath)
Check if given path is a directory.
char * copyString(char *s, char *label)
Create a copy of a string.
int isPIPE(char *ppath)
Check if given path is a pipe.
char * curDate()
Get the current date.
void Assert(int fatalFlag, const char *fmt,...)
Raise an assert.
char * wordCount(char *textp)
VERY simple line count, does NOT have to be perfect!
void renameInode(char *oldpath, char *newpath)
Rename an inode at oldpath to newpath.
int mySystem(const char *fmt,...)
Run a system command.
int isBLOCK(char *bpath)
Check if given path is a Block device.
#define MM_CACHESIZE
MM Cache size.
int bufferLineCount(char *p, int len)
Finds the length of first line in a buffer.
void appendFile(char *pathname, char *str)
Append a string at the end of the file.
void chmodInode(char *pathname, int mode)
Change inode mode bits.
void makeSymlink(char *path)
Create symbolic links for a given path in current directory.
char * findEol(char *s)
Find first ROL in a string.
void Msg(const char *fmt,...)
DO NOT automatically add to a string passed to Msg(); in parseDistro, we sometimes want to dump a p...
int addEntry(char *pathname, int forceFlag, const char *fmt,...)
adds a line to the specified pathname
int isCHAR(char *cpath)
Check if given path is a character device.
char * mmapFile(char *pathname)
Blarg. Files that are EXACTLY a multiple of the system pagesize do not get a NULL on the end of the b...
char * newReloTarget(char *basename)
Check if a relocation target is accessible.
char debugStr[myBUFSIZ]
Debug string.
#define NULL_STR
NULL string.
#define MAX_RENAME
Max rename length.
#define isEOL(x)
Check if x points to a EOL character.
void Bail(int exitval)
Close connections and exit.
#define NULL_CHAR
NULL character.
int lineInFile(char *pathname, char *regex)
Check if a line exists in a file.
int strGrep(char *regex, char *data, int flags)
General-purpose grep function, used for one-time-only searches.
start($application)
start the application Assumes application is restartable via /etc/init.d/<script>....
char initwd[myBUFSIZ]
CDB, would like to workaround/eliminate.
char progName[64]
Program name.
list_t type structure used to keep various lists. (e.g. there are multiple lists).
tricky data structure used for a list of 'items'
Store the results of a regex match.
char label[myBUFSIZ]
Label.
void * mmPtr
Memory pointer.