⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldconfig.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ldconfig - update shared library symlinks * * usage: ldconfig [-DvqnNX] [-f conf] [-C cache] [-r root] dir ... *        ldconfig -l [-Dv] lib ... *        ldconfig -p *        -D: debug mode, don't update links *        -v: verbose mode, print things as we go *        -q: quiet mode, don't print warnings *        -n: don't process standard directories *        -N: don't update the library cache *        -X: don't update the library links *        -l: library mode, manually link libraries *        -p: print the current library cache *        -f conf: use conf instead of /etc/ld.so.conf *        -C cache: use cache instead of /etc/ld.so.cache *        -r root: first, do a chroot to the indicated directory *        dir ...: directories to process *        lib ...: libraries to link * * Copyright 1994-2000 David Engel and Mitch D'Souza * * This program may be used for any purpose as long as this * copyright notice is kept. */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <getopt.h>#include <dirent.h>#include <unistd.h>#include <link.h>#include <elf.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <errno.h>#include "../config.h"#include "readsoname.h"struct exec{  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */  unsigned a_text;		/* length of text, in bytes */  unsigned a_data;		/* length of data, in bytes */  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */  unsigned a_syms;		/* length of symbol table data in file, in bytes */  unsigned a_entry;		/* start address */  unsigned a_trsize;		/* length of relocation info for text, in bytes */  unsigned a_drsize;		/* length of relocation info for data, in bytes */};#if !defined (N_MAGIC)#define N_MAGIC(exec) ((exec).a_info & 0xffff)#endif/* Code indicating object file or impure executable.  */#define OMAGIC 0407/* Code indicating pure executable.  */#define NMAGIC 0410/* Code indicating demand-paged executable.  */#define ZMAGIC 0413/* This indicates a demand-paged executable with the header in the text.    The first page is unmapped to help trap NULL pointer references */#define QMAGIC 0314/* Code indicating core file.  */#define CMAGIC 0421#ifdef __GNUC__void warn(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));void error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));#endifchar *___strtok = NULL;/* For SunOS */#ifndef PATH_MAX#include <limits.h>#define PATH_MAX _POSIX_PATH_MAX#endif/* For SunOS */#ifndef N_MAGIC#define N_MAGIC(exec) ((exec).a_magic & 0xffff)#endif#define EXIT_OK    0#define EXIT_FATAL 128char *prog = NULL;int debug = 0;			/* debug mode */int verbose = 0;		/* verbose mode */int libmode = 0;		/* library mode */int nocache = 0;		/* don't build cache */int nolinks = 0;		/* don't update links */char *conffile = LDSO_CONF;	/* default conf file */char *cachefile = LDSO_CACHE;	/* default cache file */void cache_print(void);void cache_dolib(const char *dir, const char *so, int libtype);void cache_write(void);void warn(const char *fmt, ...){    va_list ap;    if (verbose < 0)        return;    fflush(stdout);    /* don't mix output and error messages */    fprintf(stderr, "%s: warning: ", prog);    va_start(ap, fmt);    vfprintf(stderr, fmt, ap);    va_end(ap);    fprintf(stderr, "\n");    return;}void error(const char *fmt, ...){    va_list ap;    fflush(stdout);    /* don't mix output and error messages */    fprintf(stderr, "%s: ", prog);    va_start(ap, fmt);    vfprintf(stderr, fmt, ap);    va_end(ap);    fprintf(stderr, "\n");    exit(EXIT_FATAL);}void *xmalloc(size_t size){    void *ptr;    if ((ptr = malloc(size)) == NULL)	error("out of memory");    return ptr;}char *xstrdup(const char *str){    char *ptr;    if ((ptr = strdup(str)) == NULL)	error("out of memory");    return ptr;}/* If shared library, return a malloced copy of the soname and set the   type, else return NULL.   expected_type should be either LIB_ANY or one of the following:-   LIB_DLL   LIB_ELF   LIB_ELF_LIBC5   LIB_ELF_LIBC6   If the lib is ELF and we can not deduce the type the type will   be set based on expected_type.   If the expected, actual/deduced types missmatch we display a warning   and use the actual/deduced type.*/char *is_shlib(const char *dir, const char *name, int *type,	int *islink, int expected_type){    char *good = NULL;    char *cp, *cp2;    FILE *file;    struct exec exec;    ElfW(Ehdr) *elf_hdr;    struct stat statbuf;    char buff[4096];    /* see if name is of the form libZ.so* */    if ((strncmp(name, "lib", 3) == 0 || strncmp(name, "ld-", 3) == 0) && \	name[strlen(name)-1] != '~' && (cp = strstr(name, ".so")))    {	/* find the start of the Vminor part, if any */	if (cp[3] == '.' && (cp2 = strchr(cp + 4, '.')))	    cp = cp2;	else	    cp = cp + strlen(cp);	/* construct the full path name */	sprintf(buff, "%s%s%s", dir, (*dir && strcmp(dir, "/")) ?		"/" : "", name);	/* first, make sure it's a regular file */	if (lstat(buff, &statbuf))	    warn("can't lstat %s (%s), skipping", buff, strerror(errno));	else if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))	    warn("%s is not a regular file or symlink, skipping", buff);	else	{	    /* is it a regular file or a symlink */	    *islink = S_ISLNK(statbuf.st_mode);	    /* then try opening it */	    if (!(file = fopen(buff, "rb")))		warn("can't open %s (%s), skipping", buff, strerror(errno));	    else	    {		/* now make sure it's a shared library */		if (fread(&exec, sizeof exec, 1, file) < 1)		    warn("can't read header from %s, skipping", buff);		else if (N_MAGIC(exec) != ZMAGIC && N_MAGIC(exec) != QMAGIC)		{		    elf_hdr = (ElfW(Ehdr) *) &exec;		    if (elf_hdr->e_ident[0] != 0x7f ||			strncmp(&elf_hdr->e_ident[1], "ELF",3) != 0)		    {		        /* silently ignore linker scripts */		        if (strncmp((char *)&exec, "/* GNU ld", 9) != 0)			    warn("%s is not a shared library, skipping", buff);		    }		    else		    {		        /* always call readsoname to update type */			if(expected_type == LIB_DLL){			    warn("%s is not an a.out library, its ELF!\n", buff);			    expected_type=LIB_ANY;			}		        *type = LIB_ELF;		        good = readsoname(buff, file, expected_type, type, 					  elf_hdr->e_ident[EI_CLASS]);			if (good == NULL || *islink)			{			    if (good != NULL)			        free(good);			    good = xstrdup(name);			}			else			{			    /* if the soname does not match the filename,			       issue a warning, but only in debug mode. */			    int len = strlen(good);			    if (debug && (strncmp(good, name, len) != 0 ||				(name[len] != '\0' && name[len] != '.')))			        warn("%s has inconsistent soname (%s)",				     buff, good);			}		    }		}		else		{		    if (*islink)		        good = xstrdup(name);		    else		    {		        good = xmalloc(cp - name + 1);			strncpy(good, name, cp - name);			good[cp - name] = '\0';		    }		    if(expected_type != LIB_ANY && expected_type != LIB_DLL)		    {			warn("%s is not an ELF library, its an a.out DLL!", buff);			expected_type=LIB_ANY;		    }		    		    *type = LIB_DLL;		}		fclose(file);	    }	}    }    return good;}/* update the symlink to new library */void link_shlib(const char *dir, const char *file, const char *so){    int change = 1;    char libname[4096];    char linkname[4096];    struct stat libstat;    struct stat linkstat;    /* construct the full path names */    sprintf(libname, "%s/%s", dir, file);    sprintf(linkname, "%s/%s", dir, so);    /* see if a link already exists */    if (!stat(linkname, &linkstat))    {	/* now see if it's the one we want */	if (stat(libname, &libstat))	    warn("can't stat %s (%s)", libname, strerror(errno));	else if (libstat.st_dev == linkstat.st_dev &&	    libstat.st_ino == linkstat.st_ino)	    change = 0;    }    /* then update the link, if required */    if (change > 0 && !nolinks)    {	if (!lstat(linkname, &linkstat))	{	  if (!S_ISLNK(linkstat.st_mode))	  {	    warn("%s is not a symlink", linkname);	    change = -1;	  }	  else if (remove(linkname))	  {	    warn("can't unlink %s (%s)", linkname, strerror(errno));	    change = -1;	  }	}	if (change > 0)	{	  if (symlink(file, linkname))	  {	    warn("can't link %s to %s (%s)", linkname, file, strerror(errno));	    change = -1;	  }	}    }    /* some people like to know what we're doing */    if (verbose > 0)	printf("\t%s => %s%s\n", so, file,	       change < 0 ? " (SKIPPED)" :	       (change > 0 ? " (changed)" : ""));    return;}/* figure out which library is greater */int libcmp(char *p1, char *p2){    while (*p1)    {	if (isdigit(*p1) && isdigit(*p2))	{	    /* must compare this numerically */	    int v1, v2;	    v1 = strtoul(p1, &p1, 10);	    v2 = strtoul(p2, &p2, 10);	    if (v1 != v2)		return v1 - v2;	}	else if (isdigit(*p1) && !isdigit(*p2))	    return 1;	else if (!isdigit(*p1) && isdigit(*p2))	    return -1;	else if (*p1 != *p2)	    return *p1 - *p2;	else	    p1++, p2++;    }    return *p1 - *p2;}struct lib{    char *so;			/* soname of a library */    char *name;			/* name of a library */    int libtype;		/* type of a library */    int islink;			/* is it a symlink */    struct lib *next;		/* next library in list */};/* update all shared library links in a directory */void scan_dir(const char *name){    DIR *dir;    struct dirent *ent;    char *so;    struct lib *lp, *libs = NULL;    int libtype, islink;    int expected_type = LIB_ANY;    char *t;    /* Check for an embedded expected type */    t=strrchr(name, '=');    if( t )    {	*t++ = '\0'; /* Skip = char */	if(strcasecmp(t, "libc4") == 0)	{	    expected_type = LIB_DLL;	} 	else	{	    if(strcasecmp(t, "libc5") == 0)	    {		expected_type = LIB_ELF_LIBC5; 	    }	    else	    {		if(strcasecmp(t, "libc6") == 0)		{		    expected_type = LIB_ELF_LIBC6;		}		else		{		    warn("Unknown type field '%s' for dir '%s' - ignored\n", t, name);		    expected_type = LIB_ANY;		}	    }	}    }    /* let 'em know what's going on */    if (verbose > 0)	printf("%s:\n", name);    /* if we can't open it, we can't do anything */    if ((dir = opendir(name)) == NULL)    {	warn("can't open %s (%s), skipping", name, strerror(errno));	return;    }    /* yes, we have to look at every single file */    while ((ent = readdir(dir)) != NULL)    {	/* if it's not a shared library, don't bother */	if ((so = is_shlib(name, ent->d_name, &libtype, &islink, expected_type)) == NULL)	    continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -