31 #include "nomos_regex.h" 32 #include "nomos_utils.h" 34 #define MM_CACHESIZE 20 37 #ifdef REUSE_STATIC_MEMORY 38 static char grepzone[10485760];
45 static char utilbuf[myBUFSIZ];
47 static char cmdBuf[512];
51 #define MEMCACHESIZ 200000 52 static int memlast = -1;
53 static struct mm_cache memcache[MEMCACHESIZ];
65 traceFunc(
"== isDIR(%s)\n", dpath);
68 return(
isINODE(dpath, S_IFDIR));
80 traceFunc(
"== isEMPTYFILE(%s)\n", fpath);
86 return(cur.stbuf.st_size == 0);
98 traceFunc(
"== isBLOCK(%s)\n", bpath);
101 return(
isINODE(bpath, S_IFBLK));
113 traceFunc(
"== isCHAR(%s)\n", cpath);
116 return(
isINODE(cpath, S_IFCHR));
128 traceFunc(
"== isPIPE(%s)\n", ppath);
131 return(
isINODE(ppath, S_IFIFO));
143 traceFunc(
"== isSYMLINK(%s)\n", spath);
146 return(
isINODE(spath, S_IFLNK));
158 char sErrorBuf[1024];
161 traceFunc(
"== isINODE(%s, 0x%x)\n", ipath, typ);
164 if ((ret = stat(ipath, &cur.stbuf)) < 0) {
170 if (errno == ENOENT) {
173 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
174 LOG_ERROR(
"Error: %s getting stat on file: %s", sErrorBuf, ipath)
179 return((
int)(cur.stbuf.st_mode & S_IFMT & typ));
189 static char newpath[myBUFSIZ];
193 traceFunc(
"== newReloTarget(%s)\n", basename);
197 (void) sprintf(newpath,
"%s_%s-renamed.%03d", basename, gl.
progName, i);
198 if (access(newpath, F_OK) && errno == ENOENT) {
202 if (i == MAX_RENAME) {
203 LOG_FATAL(
"%s: no suitable relocation target (%d tries)", basename, i)
211 #ifdef MEMORY_TRACING 217 char *memAllocTagged(
int size,
char *name)
227 #if defined(PROC_TRACE) || defined(MEM_ACCT) 228 traceFunc(
"== memAllocTagged(%d, \"%s\")\n",
size, name);
232 LOG_FATAL(
"Cannot alloc %d bytes!",
size)
235 if (++memlast == MEMCACHESIZ) {
236 LOG_FATAL(
"*** memAllocTagged: out of memcache entries")
240 if ((ptr = calloc((
size_t) 1, (
size_t)
size)) == (
void *) NULL) {
241 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
242 LOG_FATAL(
"calloc for %s, error: %s", name, sErrorBuf)
246 if ((ptr = malloc((
size_t) size)) == (
void *) NULL) {
247 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
248 LOG_FATAL(
"malloc for %s, error: %s", name, sErrorBuf)
251 (void) memset(ptr, 0, (
size_t)
size);
253 #if DEBUG > 3 || defined(MEM_ACCT) 254 printf(
"+%p:%p=(%d)\n", ptr, ptr+size-1, size);
256 memcache[memlast].mmPtr = ptr;
257 memcache[memlast].size =
size;
258 (void) strcpy(memcache[memlast].
label, name);
260 printf(
"memAllocTagged(%d, \"%s\") == %p [entry %04d]\n", size, name, ptr,
268 void memFreeTagged(
void *ptr,
char *note)
273 #if defined(PROC_TRACE) || defined(MEM_ACCT) 274 traceFunc(
"== memFree(%p, \"%s\")\n", ptr, note);
277 #ifdef MEMORY_TRACING 278 DEBUG(
"mprobe(%p)\n", ptr)
281 for (mmp = memcache, i = 0; i <= memlast; mmp++, i++) {
282 if (mmp->
mmPtr == ptr) {
284 printf(
"memFree(%p, \"%s\") is entry %04d (%d bytes)\n", ptr, note, i,
291 LOG_FATAL(
"Could not locate %p to free!", ptr)
295 #if DEBUG > 3 || defined(MEM_ACCT) 296 printf(
"-%p=(%d)\n", ptr, mmp->
size);
299 (void) memmove(&memcache[i], &memcache[i+1],
300 (memlast-i)*
sizeof(
struct mm_cache));
302 memset(&memcache[memlast], 0,
sizeof(
struct mm_cache));
305 memCacheDump(
"post-memFree:");
311 void memCacheDump(
char *
s)
314 static int first = 1;
321 printf(
"%%%%%% mem-cache is EMPTY\n");
324 start = (memlast > 50 ? memlast-50 : 0);
325 printf(
"%%%%%% mem-cache @ %p [last=%d]\n", memcache, memlast);
326 for (m = memcache+start, i = start; i <= memlast; m++, i++) {
327 printf(
"mem-entry %04d: %p (%d) - %s\n", i, m->
mmPtr,
330 printf(
"... \"%s\"\n", m->
mmPtr);
333 printf(
"%%%%%% mem-cache END\n");
357 traceFunc(
"== findBol(%p, %p)\n", s, upperLimit);
363 for (cp = s; cp > upperLimit; cp--) {
365 DEBUG(
"cp %p upperLimit %p\n", cp, upperLimit)
369 DEBUG(
"Got it! BOL == %p\n", cp)
371 return((
char*)(cp+1));
374 if (cp == upperLimit) {
376 DEBUG(
"AT upperLimit %p\n", upperLimit);
395 traceFunc(
"== findEol(%p)\n", s);
424 char sErrorBuf[1024];
429 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG) 430 traceFunc(
"== renameInode(%s, %s)\n", oldpath, newpath);
434 (void)
mySystem(
"ls -ldi '%s'", oldpath);
436 if (rename(oldpath, newpath) < 0) {
437 if (errno == EXDEV) {
438 err =
mySystem(
"mv '%s' %s", oldpath, newpath);
444 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
445 LOG_FATAL(
"rename(%s, %s) error: %s", oldpath, newpath, sErrorBuf)
450 (void)
mySystem(
"ls -ldi %s", newpath);
464 char sErrorBuf[1024];
469 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG) 470 traceFunc(
"== chmodInode(%s, 0%o)\n", pathname, mode);
473 if (chmod(pathname, mode) < 0) {
474 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
475 LOG_FATAL(
"chmod(\"%s\", 0%o) error: %s", pathname, mode, sErrorBuf)
491 char sErrorBuf[1024];
498 traceFunc(
"== fopenFile(%s, \"%s\")\n", pathname, mode);
501 if ((fp = fopen(pathname, mode)) == (FILE *) NULL) {
502 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
503 LOG_FATAL(
"fopen(%s) error: %s", pathname, sErrorBuf);
536 char sErrorBuf[1024];
543 traceFunc(
"== popenProc(\"%s\", %s)\n", command, mode);
546 if ((pp = popen(command, mode)) == (FILE *) NULL) {
547 #ifdef MEMORY_TRACING 548 memCacheDump(
"Post-popen-failure:");
550 strerror_r(errno, sErrorBuf,
sizeof(sErrorBuf));
551 LOG_FATAL(
"popen(\"%s\") error: %s", command, sErrorBuf)
565 static char wcbuf[64];
570 traceFunc(
"== wordCount(%p)\n", textp);
574 for (cp = textp; *cp; cp++) {
590 (void) sprintf(wcbuf,
"%d lines", lines);
611 traceFunc(
"== copyString(%p, \"%s\")\n", s, label);
614 cp = memAlloc(len=(strlen(s)+1), label);
616 printf(
"+CS: %d @ %p\n", len, cp);
618 (void) strcpy(cp, s);
632 traceFunc(
"== pathBasename(\"%s\")\n", path);
635 cp = strrchr(path,
'/');
636 return(cp ==
NULL_STR ? path : (
char *)(cp+1));
648 static char *ibuf = NULL;
649 static int bufmax = 0;
650 char *sep =
_REGEX(_UTIL_XYZZY);
661 int regexFlags = REG_ICASE|REG_EXTENDED;
663 #if defined(PROC_TRACE) || defined(PHRASE_DEBUG) || defined(DOCTOR_DEBUG) 664 traceFunc(
"== getInstances(%p, %d, %d, %d, \"%s\", %d)\n", textp, size,
665 nBefore, nAfter, regex, recordOffsets);
668 if ((notDone =
strGrep(regex, textp, regexFlags)) == 0) {
670 printf(
"... no match: 1st strGrep()\n");
681 p->seqNo = cur.offList.
used;
684 if (p->bList) free(p->bList);
685 p->bList = (
list_t *)memAlloc(
sizeof(
list_t), MTAG_LIST);
686 (void) sprintf(utilbuf,
"\"%c%c%c%c%c%c%c%c%c%c\" match-list",
687 *regex, *(regex+1), *(regex+2), *(regex+3), *(regex+4),
688 *(regex+5), *(regex+6), *(regex+7), *(regex+8), *(regex+9));
690 printf(
"Creating %s\n", utilbuf);
696 LOG_FATAL(
"Called getInstances(%s) more than once", regex)
701 #ifdef REUSE_STATIC_MEMORY 704 bufmax =
sizeof(grepzone);
706 else if (ibuf != grepzone) {
709 bufmax =
sizeof(grepzone);
713 ibuf = memAlloc((bufmax = 1024*1024), MTAG_SEARCHBUF);
723 printf(
"getInstances: \"%s\" [#1] in buf [%d-%d]\n", regex,
724 cur.regm.rm_so, cur.regm.rm_eo-1);
725 printf(
"Really in the buffer: [");
726 for (cp = textp + cur.regm.rm_so; cp < (textp + cur.regm.rm_eo); cp++) {
737 fileeof = (
char *) (textp+size);
741 printf(
"... found Match #%d\n", p->nMatch);
744 (void) sprintf(utilbuf,
"buf%05d", p->nMatch);
747 start =
findBol(curptr + cur.regm.rm_so, textp);
753 if ((nBefore > 0) && (start > textp)) {
754 for (i = 0; (i < nBefore) && (start > textp); i++) {
756 if ((start > textp) &&
isEOL(*start)) {
763 DEBUG(
"start = %p\n", start)
768 bp->bStart = start-textp;
786 curptr += cur.regm.rm_eo;
792 for (i = 0; end < fileeof; end++) {
798 LOG_FATAL(
"lost the end-of-line")
808 if ((end < fileeof) && *end) {
813 printf(
"Snippet, with %d lines below:\n----\n", nAfter);
814 for (cp = start; cp < end; cp++) {
819 notDone =
strGrep(regex, curptr, regexFlags);
822 printf(
"... next match @ %d:%d (end=%d)\n",
823 curptr - textp + cur.regm.rm_so,
824 curptr - textp + cur.regm.rm_eo - 1, end - textp);
827 if ((curptr + cur.regm.rm_eo) > fileeof) {
832 if ((curptr + cur.regm.rm_eo) > end) {
847 bp->bLen = end-
start;
851 printf(
"%s starts @%d, len %d ends [%c%c%c%c%c%c%c]\n",
852 utilbuf, bp->bStart, bp->bLen, *(end-8), *(end-7),
853 *(end-6), *(end-5), *(end-4), *(end-3), *(end-2));
856 newDataLen = end-start+(notDone ? strlen(sep)+1 : 0);
857 while (buflen+newDataLen > bufmax) {
860 Assert(
NO,
"data(%d) > bufmax(%d)", buflen+newDataLen,
865 printf(
"... DOUBLE search-pattern buffer (%d -> %d)\n",
868 new = memAlloc(bufmax, MTAG_DOUBLED);
869 (void) memcpy(
new, ibuf, buflen);
871 printf(
"REPLACING buf %p(%d) with %p(%d)\n", ibuf,
872 bufmax/2,
new, bufmax);
874 #ifdef REUSE_STATIC_MEMORY 875 if (ibuf != grepzone) {
883 cp = bufmark = ibuf+buflen-1;
884 buflen += newDataLen;
885 bufmark += sprintf(bufmark,
"%s", start);
887 bufmark += sprintf(bufmark,
"%s\n", sep);
903 printf(
"Loop end, BUF IS NOW: [\"%s\":%d]\n----\n%s====\n",
904 regex, strlen(ibuf), ibuf);
908 #if defined(PHRASE_DEBUG) || defined(DOCTOR_DEBUG) 909 printf(
"getInstances(\"%s\"): Found %d bytes of data...\n", regex,
913 printf(
"getInstances(\"%s\"): buffer %p --------\n%s\n========\n",
927 static char datebuf[32];
932 (void) ctime_r(&thyme, datebuf);
933 if ((cp = strrchr(datebuf,
'\n')) ==
NULL_STR) {
934 LOG_FATAL(
"Unexpected time format from ctime_r()!")
943 void memStats(
char *
s)
945 static int first = 1;
946 static char mbuf[128];
950 sprintf(mbuf,
"grep VmRSS /proc/%d/status", getpid());
955 for (i = (
int) (strlen(s)+2); i < 50; i++) {
961 system(
"grep Vm /proc/self/status");
962 system(
"grep Brk /proc/self/status");
974 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG) 975 traceFunc(
"== makeSymlink(%s)\n", path);
978 (void) sprintf(cmdBuf,
".%s", strrchr(path,
'/'));
979 if (symlink(path, cmdBuf) < 0) {
981 LOG_FATAL(
"Failed: symlink(%s, %s)", path, cmdBuf)
1004 static char misc[64];
1010 traceFunc(
"== printRegexMatch(%d, %d)\n", n, cached);
1014 strncpy(debugStr, gl.
initwd,
sizeof(debugStr)-1);
1015 strncat(debugStr,
"/Nomos.strings.txt",
sizeof(debugStr)-1);
1017 printf(
"File: %s\n", debugStr);
1020 save_so = cur.regm.rm_so;
1021 save_eo = cur.regm.rm_eo;
1027 printf(
"Match [%d:%d]\n", save_so, save_eo);
1030 (void) sprintf(misc,
"=#%03d", n);
1031 if (
strGrep(misc, textp, REG_EXTENDED)) {
1033 printf(
"Patt: %s\nMatch: %d:%d\n", misc,
1034 cur.regm.rm_so, cur.regm.rm_eo);
1036 x = textp + cur.regm.rm_so;
1037 cp = textp + cur.regm.rm_so;
1039 while (*--x !=
'[') {
1041 LOG_FATAL(
"Cannot locate debug symbol")
1046 (void) strncpy(misc, x, cp - x);
1049 (void) strcpy(misc,
"?");
1056 printf(
"RESTR [%d:%d]\n", cur.regm.rm_so, cur.regm.rm_eo);
1059 cur.regm.rm_so = save_so;
1060 cur.regm.rm_eo = save_eo;
1061 printf(
"%s regex %d ", cached ?
"Cached" :
"Found", n);
1063 printf(
"(%s) ", misc);
1066 printf(
"\"%s\"",
_REGEX(n));
1070 printf(
"Seed: \"%s\"\n",
_SEED(n));
1084 for (pBuf = Buffer; BufferSize--; pBuf++)
1085 if (*pBuf == 0) *pBuf =
' ';
1103 traceFunc(
"== mmapFile(%s)\n", pathname);
1106 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1107 if (mmp->
inUse == 0) {
1112 if (i == MM_CACHESIZE) {
1113 printf(
"mmap-cache too small [%d]!\n", MM_CACHESIZE);
1118 if ((mmp->
fd = open(pathname, O_RDONLY)) < 0) {
1119 if (errno == ENOENT) {
1122 mmp->
mmPtr = (
void *) NULL;
1124 printf(
"mmapFile: ENOENT %s\n", pathname);
1129 (void)
mySystem(
"ls -l %s", pathname);
1130 LOG_FATAL(
"%s: open failure!", pathname)
1134 if (fstat(mmp->
fd, &cur.stbuf) < 0) {
1135 printf(
"fstat failure!\n");
1139 if (S_ISDIR(cur.stbuf.st_mode)) {
1140 printf(
"mmapFile(%s): is a directory\n", pathname);
1144 (void) strcpy(mmp->
label, pathname);
1145 if (cur.stbuf.st_size)
1147 mmp->
size = cur.stbuf.st_size + 1;
1148 mmp->
mmPtr = memAlloc(mmp->
size, MTAG_MMAPFILE);
1150 printf(
"+MM: %lu @ %p\n", mmp->
size, mmp->
mmPtr);
1163 if ((n = (
int) read(mmp->
fd, cp, (
size_t) rem)) < 0) {
1167 LOG_WARNING(
"nomos read error: %s, file: %s, read size: %d, pfile_pk: %ld\n", strerror(errno), pathname, rem, cur.
pFileFk);
1176 return((
char *) mmp->
mmPtr);
1181 (void) close(mmp->
fd);
1183 Assert(
NO,
"mmapFile: returning NULL");
1189 void mmapOpenListing()
1194 printf(
"=== mm-cache BEGIN ===\n");
1195 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1197 printf(
"mm[%d]: (%d) %s:%d\n", i, mmp->
fd,
1201 printf(
"--- mm-cache END ---\n");
1215 traceFunc(
"== munmapFile(%p)\n", ptr);
1218 if (ptr == (
void *) NULL) {
1220 Assert(
NO,
"NULL sent to munmapFile()!");
1224 for (mmp = mmap_data, i = 0; i <
MM_CACHESIZE; i++, mmp++) {
1225 if (mmp->
inUse == 0) {
1228 if (mmp->
mmPtr == ptr) {
1230 printf(
"munmapFile: clearing entry %d\n", i);
1234 (void) munmap((
void *) ptr, (size_t) mmp->
size);
1237 if (close(mmp->
fd) < 0) {
1242 mmp->buf = (
void *) NULL;
1246 printf(
"DEBUG: munmapFile: freeing %lu bytes\n",
1268 char *eofaddr = NULL;
1272 traceFunc(
"== bufferLineCount(%p, %d)\n", p, len);
1278 eofaddr = (
char *) (p+len);
1279 for (i = 0, cp = p; cp <= eofaddr; cp++, i++) {
1285 printf(
"bufferLineCount == %d\n", i);
1300 traceFunc(
"== appendFile(%s, \"%s\")\n", pathname, str);
1304 fprintf(fp,
"%s\n", str);
1319 (void) vsprintf(cmdBuf, fmt, ap);
1322 #if defined(PROC_TRACE) || defined(UNPACK_DEBUG) 1323 traceFunc(
"== mySystem('%s')\n", cmdBuf);
1326 ret = system(cmdBuf);
1327 if (WIFEXITED(ret)) {
1328 ret = WEXITSTATUS(ret);
1331 LOG_ERROR(
"system(%s) returns %d", cmdBuf, ret)
1335 else if (WIFSIGNALED(ret)) {
1336 ret = WTERMSIG(ret);
1337 LOG_ERROR(
"system(%s) died from signal %d", cmdBuf, ret)
1339 else if (WIFSTOPPED(ret)) {
1340 ret = WSTOPSIG(ret);
1341 LOG_ERROR(
"system(%s) stopped, signal %d", cmdBuf, ret)
1356 traceFunc(
"== isFILE(%s)\n", pathname);
1359 return(
isINODE(pathname, S_IFREG));
1370 int addEntry(
char *pathname,
int forceFlag,
const char *fmt, ...)
1373 vsprintf(utilbuf, fmt, ap);
1377 traceFunc(
"== addEntry(%s, %d, \"%s\")\n", pathname, forceFlag, utilbuf);
1381 Assert(
YES,
"addEntry - NULL pathname");
1383 if (forceFlag || !
lineInFile(pathname, utilbuf)) {
1394 void Msg(
const char *fmt, ...)
1397 (void) vprintf(fmt, ap);
1407 void Assert(
int fatalFlag,
const char *fmt, ...)
1410 (void) sprintf(utilbuf,
"ASSERT: ");
1411 (void) vsprintf(utilbuf+strlen(utilbuf), fmt, ap);
1415 traceFunc(
"!! Assert(\"%s\")\n", utilbuf+strlen(gl.
progName)+3);
1418 (void) strcat(utilbuf,
"\n");
1427 void traceFunc(
char *fmtStr, ...)
1431 #ifdef PROC_TRACE_SWITCH 1434 va_start(args, fmtStr);
1436 vprintf(fmtStr, args);
1438 #ifdef PROC_TRACE_SWITCH 1445 char *memAllocLogged(
int size)
1449 ptr = calloc(size, 1);
1450 printf(
"%p = calloc( %d , 1 )\n", ptr, size);
1454 void memFreeLogged(
void *ptr)
1456 printf(
"free( %p )\n", ptr);
int isFILE(char *pathname)
Check if an inode is a file.
int isEMPTYFILE(char *fpath)
Check if given file is empty.
char * curDate()
Get the current date.
Store the results of a regex match.
tricky data structure used for a list of 'items'
void chmodInode(char *pathname, int mode)
Change inode mode bits.
int s
The socket that the CLI will use to communicate.
char * wordCount(char *textp)
VERY simple line count, does NOT have to be perfect!
void ReplaceNulls(char *Buffer, int BufferSize)
Replace all nulls in Buffer with blanks.
int bufferLineCount(char *p, int len)
Finds the length of first line in a buffer.
void Bail(int exitval)
Close connections and exit.
char * getInstances(char *textp, int size, int nBefore, int nAfter, char *regex, int recordOffsets)
Get occurrence of a regex in a given string pointer.
int isCHAR(char *cpath)
Check if given path is a character device.
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 initwd[myBUFSIZ]
CDB, would like to workaround/eliminate.
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...
int lineInFile(char *pathname, char *regex)
Check if a line exists in a file.
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
#define NULL_CHAR
NULL character.
#define MM_CACHESIZE
MM Cache size.
void Assert(int fatalFlag, const char *fmt,...)
Raise an assert.
start($application)
start the application Assumes application is restartable via /etc/init.d/<script>. The application passed in should match the script name in /etc/init.d
char debugStr[myBUFSIZ]
Debug string.
#define MAX_RENAME
Max rename length.
void printRegexMatch(int n, int cached)
CDB – Need to review this code, particularly for the use of an external file (Nomos.strings.txt). Despite the fact that variable is named debugStr, the file appears to be used for more than just debugging.
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...
#define isEOL(x)
Check if x points to a EOL character.
char * copyString(char *s, char *label)
Create a copy of a string.
char * pathBasename(char *path)
Get the basename from a file path.
int isSYMLINK(char *spath)
Check if given path is a symbolic link.
int isDIR(char *dpath)
Check if given path is a directory.
int mySystem(const char *fmt,...)
Run a system command.
void renameInode(char *oldpath, char *newpath)
Rename an inode at oldpath to newpath.
char label[myBUFSIZ]
Label.
#define NULL_STR
NULL string.
int isBLOCK(char *bpath)
Check if given path is a Block device.
list_t type structure used to keep various lists. (e.g. there are multiple lists).
int strGrep(char *regex, char *data, int flags)
General-purpose grep function, used for one-time-only searches.
char * findEol(char *s)
Find first ROL in a string.
int isPIPE(char *ppath)
Check if given path is a pipe.
int isINODE(char *ipath, int typ)
Check for a inode against a flag.
void munmapFile(void *ptr)
void appendFile(char *pathname, char *str)
Append a string at the end of the file.
char * findBol(char *s, char *upperLimit)
Find Begin of Line in a string.
void * mmPtr
Memory pointer.
void makeSymlink(char *path)
Create symbolic links for a given path in current directory.
FILE * fopenFile(char *pathname, char *mode)
Open a file and return the file pointer.
FILE * popenProc(char *command, char *mode)
Open a process pipe using popen()
char * newReloTarget(char *basename)
Check if a relocation target is accessible.
char progName[64]
Program name.