📄 ldconfig.c
字号:
/* have we already seen one with the same so name? */ for (lp = libs; lp; lp = lp->next) { if (strcmp(so, lp->so) == 0) { /* we have, which one do we want to use? */ if ((!islink && lp->islink) || (islink == lp->islink && libcmp(ent->d_name, lp->name) > 0)) { /* let's use the new one */ free(lp->name); lp->name = xstrdup(ent->d_name); lp->libtype = libtype; lp->islink = islink; } break; } } /* congratulations, you're the first one we've seen */ if (!lp) { lp = xmalloc(sizeof *lp); lp->so = xstrdup(so); lp->name = xstrdup(ent->d_name); lp->libtype = libtype; lp->islink = islink; lp->next = libs; libs = lp; } free(so); } /* don't need this any more */ closedir(dir); /* now we have all the latest libs, update the links */ for (lp = libs; lp; lp = lp->next) { if (!lp->islink) link_shlib(name, lp->name, lp->so); if (!nocache) cache_dolib(name, lp->so, lp->libtype); } /* always try to clean up after ourselves */ while (libs) { lp = libs->next; free(libs->so); free(libs->name); free(libs); libs = lp; } return;}/* return the list of system-specific directories */char *get_extpath(void){ char *res = NULL, *cp; FILE *file; struct stat stat; if ((file = fopen(conffile, "r")) != NULL) { fstat(fileno(file), &stat); res = xmalloc(stat.st_size + 1); fread(res, 1, stat.st_size, file); fclose(file); res[stat.st_size] = '\0'; /* convert comments fo spaces */ for (cp = res; *cp; /*nada*/) { if (*cp == '#') { do *cp++ = ' '; while (*cp && *cp != '\n'); } else { cp++; } } } return res;}void usage(void){ fprintf(stderr, "ldconfig - update shared library symlinks\n" "\n" "usage: ldconfig [-DvqnNX] [-f conf] [-C cache] [-r root] dir ...\n" " ldconfig -l [-Dv] lib ...\n" " ldconfig -p\n" "\t-D:\t\tdebug mode, don't update links\n" "\t-v:\t\tverbose mode, print things as we go\n" "\t-q:\t\tquiet mode, don't print warnings\n" "\t-n:\t\tdon't process standard directories\n" "\t-N:\t\tdon't update the library cache\n" "\t-X:\t\tdon't update the library links\n" "\t-l:\t\tlibrary mode, manually link libraries\n" "\t-p:\t\tprint the current library cache\n" "\t-f conf :\tuse conf instead of %s\n" "\t-C cache:\tuse cache instead of %s\n" "\t-r root :\tfirst, do a chroot to the indicated directory\n" "\tdir ... :\tdirectories to process\n" "\tlib ... :\tlibraries to link\n" "\n" "Copyright 1994-2000 David Engel and Mitch D'Souza\n", LDSO_CONF, LDSO_CACHE ); exit(EXIT_FATAL);}int main(int argc, char **argv){ int i, c; int nodefault = 0; int printcache = 0; char *cp, *dir, *so; char *extpath; int libtype, islink; char *chroot_dir = NULL; prog = argv[0]; opterr = 0; while ((c = getopt(argc, argv, "DvqnNXlpf:C:r:")) != EOF) switch (c) { case 'D': debug = 1; /* debug mode */ nocache = 1; nolinks = 1; verbose = 1; break; case 'v': verbose = 1; /* verbose mode */ break; case 'q': if (verbose <= 0) verbose = -1; /* quiet mode */ break; case 'n': nodefault = 1; /* no default dirs */ nocache = 1; break; case 'N': nocache = 1; /* don't build cache */ break; case 'X': nolinks = 1; /* don't update links */ break; case 'l': libmode = 1; /* library mode */ break; case 'p': printcache = 1; /* print cache */ break; case 'f': conffile = optarg; /* alternate conf file */ break; case 'C': cachefile = optarg; /* alternate cache file */ break; case 'r': chroot_dir = optarg; break; default: usage(); break; /* THE REST OF THESE ARE UNDOCUMENTED AND MAY BE REMOVED IN FUTURE VERSIONS. */ } if (chroot_dir && *chroot_dir) { if (chroot(chroot_dir) < 0) error("couldn't chroot to %s (%s)", chroot_dir, strerror(errno)); if (chdir("/") < 0) error("couldn't chdir to / (%s)", strerror(errno)); } /* allow me to introduce myself, hi, my name is ... */ if (verbose > 0) printf("%s: uClibc version\n", argv[0]); if (printcache) { /* print the cache -- don't you trust me? */ cache_print(); exit(EXIT_OK); } else if (libmode) { /* so you want to do things manually, eh? */ /* ok, if you're so smart, which libraries do we link? */ for (i = optind; i < argc; i++) { /* split into directory and file parts */ if (!(cp = strrchr(argv[i], '/'))) { dir = "."; /* no dir, only a filename */ cp = argv[i]; } else { if (cp == argv[i]) dir = "/"; /* file in root directory */ else dir = argv[i]; *cp++ = '\0'; /* neither of the above */ } /* we'd better do a little bit of checking */ if ((so = is_shlib(dir, cp, &libtype, &islink, LIB_ANY)) == NULL) error("%s%s%s is not a shared library", dir, (*dir && strcmp(dir, "/")) ? "/" : "", cp); /* so far, so good, maybe he knows what he's doing */ link_shlib(dir, cp, so); } } else { /* the lazy bum want's us to do all the work for him */ /* don't cache dirs on the command line */ int nocache_save = nocache; nocache = 1; /* OK, which directories should we do? */ for (i = optind; i < argc; i++) scan_dir(argv[i]); /* restore the desired caching state */ nocache = nocache_save; /* look ma, no defaults */ if (!nodefault) { /* I guess the defaults aren't good enough */ if ((extpath = get_extpath())) { for (cp = strtok(extpath, DIR_SEP); cp; cp = strtok(NULL, DIR_SEP)) scan_dir(cp); free(extpath); } scan_dir(UCLIBC_TARGET_PREFIX "/usr/lib"); scan_dir(UCLIBC_TARGET_PREFIX "/lib"); } if (!nocache) cache_write(); } exit(EXIT_OK);}typedef struct liblist{ int flags; int sooffset; int liboffset; char *soname; char *libname; struct liblist *next;} liblist_t;static header_t magic = { LDSO_CACHE_MAGIC, LDSO_CACHE_VER, 0 };static liblist_t *lib_head = NULL;static int liblistcomp(liblist_t *x, liblist_t *y){ int res; if ((res = libcmp(x->soname, y->soname)) == 0) { res = libcmp(strrchr(x->libname, '/') + 1, strrchr(y->libname, '/') + 1); } return res;}void cache_dolib(const char *dir, const char *so, int libtype){ char fullpath[PATH_MAX]; liblist_t *new_lib, *cur_lib; magic.nlibs++; sprintf(fullpath, "%s/%s", dir, so); new_lib = xmalloc(sizeof (liblist_t)); new_lib->flags = libtype; new_lib->soname = xstrdup(so); new_lib->libname = xstrdup(fullpath); if (lib_head == NULL || liblistcomp(new_lib, lib_head) > 0) { new_lib->next = lib_head; lib_head = new_lib; } else { for (cur_lib = lib_head; cur_lib->next != NULL && liblistcomp(new_lib, cur_lib->next) <= 0; cur_lib = cur_lib->next) /* nothing */; new_lib->next = cur_lib->next; cur_lib->next = new_lib; }}void cache_write(void){ int cachefd; int stroffset = 0; char tempfile[4096]; liblist_t *cur_lib; if (!magic.nlibs) return; sprintf(tempfile, "%s~", cachefile); if (unlink(tempfile) && errno != ENOENT) error("can't unlink %s (%s)", tempfile, strerror(errno)); if ((cachefd = creat(tempfile, 0644)) < 0) error("can't create %s (%s)", tempfile, strerror(errno)); if (write(cachefd, &magic, sizeof (header_t)) != sizeof (header_t)) error("can't write %s (%s)", tempfile, strerror(errno)); for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next) { cur_lib->sooffset = stroffset; stroffset += strlen(cur_lib->soname) + 1; cur_lib->liboffset = stroffset; stroffset += strlen(cur_lib->libname) + 1; if (write(cachefd, cur_lib, sizeof (libentry_t)) != sizeof (libentry_t)) error("can't write %s (%s)", tempfile, strerror(errno)); } for (cur_lib = lib_head; cur_lib != NULL; cur_lib = cur_lib->next) { if (write(cachefd, cur_lib->soname, strlen(cur_lib->soname) + 1) != strlen(cur_lib->soname) + 1) error("can't write %s (%s)", tempfile, strerror(errno)); if (write(cachefd, cur_lib->libname, strlen(cur_lib->libname) + 1) != strlen(cur_lib->libname) + 1) error("can't write %s (%s)", tempfile, strerror(errno)); } if (close(cachefd)) error("can't close %s (%s)", tempfile, strerror(errno)); if (chmod(tempfile, 0644)) error("can't chmod %s (%s)", tempfile, strerror(errno)); if (rename(tempfile, cachefile)) error("can't rename %s (%s)", tempfile, strerror(errno));}void cache_print(void){ caddr_t c; struct stat st; int fd = 0; char *strs; header_t *header; libentry_t *libent; if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY))<0) error("can't read %s (%s)", cachefile, strerror(errno)); if ((c = mmap(0,st.st_size, PROT_READ, MAP_SHARED ,fd, 0)) == (caddr_t)-1) error("can't map %s (%s)", cachefile, strerror(errno)); close(fd); if (memcmp(((header_t *)c)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)) error("%s cache corrupt", cachefile); if (memcmp(((header_t *)c)->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)) error("wrong cache version - expected %s", LDSO_CACHE_VER); header = (header_t *)c; libent = (libentry_t *)(c + sizeof (header_t)); strs = (char *)&libent[header->nlibs]; printf("%d libs found in cache `%s' (version %s)\n", header->nlibs, cachefile, LDSO_CACHE_VER); for (fd = 0; fd < header->nlibs; fd++) { printf("\t%s ", strs + libent[fd].sooffset); switch (libent[fd].flags & ~LIB_ELF64) { case LIB_DLL: printf("(libc4)"); break; case LIB_ELF: printf("(ELF%s)", libent[fd].flags & LIB_ELF64 ? "/64" : ""); break; case LIB_ELF_LIBC5: case LIB_ELF_LIBC6: printf("(libc%d%s)", (libent[fd].flags & ~LIB_ELF64) + 3, libent[fd].flags & LIB_ELF64 ? "/64" : ""); break; default: printf("(unknown)"); break; } printf(" => %s\n", strs + libent[fd].liboffset); } munmap (c,st.st_size);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -