static const char *load_libs(loader_t *l) { char path[PATH_MAX], *err; void *h; int i, j; for (i = 0; i < l->nlib; i++) { for (j = 0; j < l->ndir; j++) { mrp_log_info("Looking for %s in %s...", l->libs[i], l->dirs[j]); if (find_matching(path, sizeof(path), l->dirs[j], l->libs[i])) { h = dlopen(path, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND); if (h != NULL) { mrp_log_info("Preloaded %s.", path); l->handles[i] = h; break; } else { err = dlerror(); mrp_log_warning("Failed to load %s (error: %s).", l->libs[i], err ? err : "unknown"); } } } if (l->handles[i] == NULL) { mrp_log_error("Failed to preload %s.", l->libs[i]); return l->libs[i]; } } return NULL; }
/** Skip whitespaces in a string * * \param p string to skip whitespace out of * \return a pointer to the first non-white character of the string, or NULL if p is entirely composed of whitespaces * \see isspace(3) */ const char* skip_white(const char *p) { int l = -1; find_matching(p, !(isspace (*p)), l); if (*p == '\0') p = NULL; return p; }
/** Find the first occurence of a character in a string up to a nul character * or a given number of characters, whichever comes first, * * \param str a possibly nul-terminated string * \param c the character to look for * \param len the maximum length to search the string for * \return a pointer to character c in str, or NULL */ const char* find_charn(const char *str, char c, int len) { find_matching(str, (*str == c), len); if (len<0 || !*str) { return NULL; } return str; }
static int find_func_name( BFile file, long funcOff, long bodyOff, long *nameOffPtr, long *nameLenPtr ) { #define nameOff (*nameOffPtr) #define nameLen (*nameLenPtr) int returnValue = 0; int iChar = EOF; long nameEndOff = 0; bfile_forward(file); bfile_set_off(file, bodyOff); bfile_reverse(file); get_char_from_c_file(file); /* skip '{' */ skip_white_and_comment(file); if ((iChar = get_char_from_c_file(file)) != ')') { fprintf(stderr, "Syntax error near function name.\n"); return -1; } if (find_matching(file, '(', NULL) < 0) { fprintf(stderr, "Unbalanced parens.\n"); return -1; } skip_white_and_comment(file); nameEndOff = bfile_get_off(file); iChar = get_char_from_c_file(file); while ((iChar != EOF) && (char_is_legal_for_ident(iChar))) { iChar = bfile_get_char(file); } nameOff = bfile_get_off(file) + 2; if ((nameOff < funcOff) || (nameOff > nameEndOff)) { returnValue = -1; } else { nameLen = (nameEndOff - nameOff + 1); } return returnValue; #undef nameOff #undef nameLen }
static int find_matching(BFile file, int matchChar, long *matchOffPtr) { int returnValue = 0; int iChar = -1; BOOL foundMatching = FALSE; BOOL quit = FALSE; long startOff = bfile_get_off(file); /* printf("find_matching(%c) at %ld\n", matchChar, startOff); */ while ((!quit) && (!bfile_eof(file))) { iChar = get_char_from_c_file(file); if (iChar == matchChar) { quit = TRUE; foundMatching = TRUE; } else { switch (iChar) { case EOF: quit = TRUE; break; case '{': if (find_matching(file, '}', NULL) < 0) { fprintf(stderr, "Unbalanced braces {}.\n"); quit = TRUE; returnValue = -1; } break; case '}': if (find_matching(file, '{', NULL) < 0) { fprintf(stderr, "Unbalanced braces {}\n"); quit = TRUE; returnValue = -1; } break; case '(': if (find_matching(file, ')', NULL) < 0) { fprintf(stderr, "Unbalanced parens ()\n"); quit = TRUE; returnValue = -1; } break; case ')': if (find_matching(file, '(', NULL) < 0) { fprintf(stderr, "Unbalanced parens ()\n"); quit = TRUE; returnValue = -1; } break; } } } if (foundMatching) { /* printf("<<match found(%c) for %ld>>\n", matchChar, startOff); */ if (matchOffPtr != NULL) { *matchOffPtr = bfile_get_off(file); if (file->reverse) { ++(*matchOffPtr); } else { --(*matchOffPtr); } } } if ((returnValue >=0) && (!foundMatching)) { returnValue = -1; } return returnValue; }
static int find_func( BFile file, long *funcOffPtr, long *funcLenPtr, long *bodyOffPtr, long *bodyLenPtr ) { #define funcOff (*funcOffPtr) #define funcLen (*funcLenPtr) #define bodyOff (*bodyOffPtr) #define bodyLen (*bodyLenPtr) int returnValue = 0; long openingBraceOff = 0; long closingBraceOff = 0; int iChar = -1; skip_white(file); /* * Scan, looking for opening { */ /* } vi hack */ funcOff = bfile_get_off(file); openingBraceOff = -1; while ((openingBraceOff < 0) && (!bfile_eof(file))) { iChar = get_char_from_c_file(file); switch (iChar) { case ';': /* function must start after one of these chars */ funcOff = bfile_get_off(file); break; case '{': /* } vi hack */ openingBraceOff = bfile_get_off(file) - 1; break; } } if ((openingBraceOff < 0) || (openingBraceOff <= funcOff)) { return -1; } /* printf("opening brace %ld\n", openingBraceOff); */ if (find_matching(file, '}', &closingBraceOff) < 0) { fprintf(stderr, "Mismatched braces {}.\nn"); return -1; } /* printf("closing brace %ld\n", closingBraceOff); */ bodyOff = openingBraceOff; bodyLen = (closingBraceOff - openingBraceOff) + 1; funcLen = (closingBraceOff - funcOff + 1); if ((bodyLen < 0) || (funcLen < 0)) { returnValue = -1; } return returnValue; #undef funcOff #undef funcLen #undef bodyOff #undef bodyLen }
/** Find first whitespace in a string * * \param p string to search for whitespace in * \return a pointer to the first whitespace character of the string, which might be the end of the string * \see isspace(3) */ const char* find_white(const char *p) { int l = -1; find_matching(p, (isspace (*p)), l); return p; }
/** Find the first occurence of a character in a string up to a nul character * or a given number of characters, whichever comes first, * * \param str a possibly nul-terminated string * \param c the character to look for * \param len the maximum length to search the string for * \return a pointer to character c in str, or NULL */ const char* find_charn(const char *str, char c, int len) { find_matching(str, (*str == c), len); return str; }