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

📄 ifrename.c

📁 wireless tools: used to manipulate the Wireless Extensions. The Wireless Extensions is an interface
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Search if the filename already exist */  for(findex = 0; findex < sysfs_global.filenum; findex++)    {      if(!strcmp(extra->modif_pos, sysfs_global.filename[findex]))	break;    }  /* If filename does not exist, creates it */  if(findex == sysfs_global.filenum)    {      if(findex == SYSFS_MAX_FILE)	{	  fprintf(stderr, "Error: Too many SYSFS filenames at line %d\n", linenum);  	  return(-1);	}      sdup = strndup(extra->modif_pos, extra->modif_len);      if(sdup == NULL)	{	  fprintf(stderr, "Error: Can't allocate SYSFS file\n");  	  return(-1);	}      sysfs_global.filename[findex] = sdup;      sysfs_global.filenum++;    }  /* Store value */  sdup = strndup(string, len);  if(sdup == NULL)    {      fprintf(stderr, "Error: Can't allocate SYSFS value\n");        return(-1);    }  ifnode->sysfs[findex] = sdup;  /* Activate */  ifnode->active[SELECT_SYSFS] = 1;  active[SELECT_SYSFS] = 1;  if(verbose)    fprintf(stderr,	    "Parsing : Added SYSFS filename `%s' value `%s' from line %d.\n",	    sysfs_global.filename[findex], ifnode->sysfs[findex], linenum);  return(0);}/*------------------------------------------------------------------*//* * Compare all the sysfs values of two mappings */static intmapping_cmpsysfs(struct if_mapping *	ifnode,		 struct if_mapping *	target){  int		findex;	/* filename index */  int		match = 1;  /* Loop on all sysfs selector */  for(findex = 0; findex < sysfs_global.filenum; findex++)    {      /* If the mapping defines this sysfs selector.. */      if(ifnode->sysfs[findex] != NULL)	/* And if the sysfs values don't match */	if((target->sysfs[findex] == NULL) ||	   (fnmatch(ifnode->sysfs[findex], target->sysfs[findex],		    FNM_CASEFOLD)))	  /* Then the sysfs selector doesn't match */	  match = 0;    }  return(!match);}/*------------------------------------------------------------------*//* * Extract all the sysfs values of an interface */static intmapping_getsysfs(int			skfd,		 const char *		ifname,		 struct if_mapping *	target,		 int			flag){  FILE *	stream;  char *	fname;  int		fnsize;  char *	linebuf = NULL;  size_t	linelen = 0;   char *	sdup;  int		findex;	/* filename index */  /* Avoid "Unused parameter" warning */  skfd = skfd;  flag = flag;  /* Check if we know the devpath of this device */  if(target->sysfs_devpath == NULL)    {      /* Check if we know the root of the sysfs filesystem */      if(sysfs_global.root == NULL)	{	  /* Open the mount file for reading */	  stream = fopen("/proc/mounts", "r");	  if(!stream) 	    {	      fprintf(stderr, "Error: Can't open /proc/mounts file: %s\n",		      strerror(errno)); 	      return(-1);	    }	  /* Read each line of file	   * getline is a GNU extension :-( The buffer is recycled and	   * increased as needed by getline. */	  while(getline(&linebuf, &linelen, stream) > 0)	    {	      int		i;	      char *	p;	      size_t	n;	      char *	token[3];	      size_t	toklen[3];	      /* The format of /proc/mounts is similar to /etc/fstab (5).	       * The first argument is the device. For sysfs, there is no	       * associated device, so this argument is ignored.	       * The second argument is the mount point.	       * The third argument is the filesystem type.	       */	      /* Extract the first 3 tokens */	      p = linebuf;	      for(i = 0; i < 3; i++)		{		  while(isspace(*p))		    ++p; 		  token[i] = p;		  n = strcspn(p, " \t\n");		  toklen[i] = n;		  p += n;		}	      /* Get the filesystem which type is "sysfs" */	      if((n == 5) && (!strncasecmp(token[2], "sysfs", 5)))		{		  /* Get its mount point */		  n = toklen[1];		  sdup = strndup(token[1], n);		  if((n == 0) || (sdup == NULL))		    {		      fprintf(stderr,			      "Error: Can't parse /proc/mounts file: %s\n",			      strerror(errno)); 		      return(-1);		    }		  /* Store it */		  sysfs_global.root = sdup;		  sysfs_global.rlen = n;		  break;		}	      /* Finished -> next line */	    }	  /* Cleanup */	  fclose(stream);	  /* Check if we found it */	  if(sysfs_global.root == NULL)	    {	      fprintf(stderr,		      "Error: Can't find sysfs in /proc/mounts file\n");	      free(linebuf);	      return(-1);	    }	}      /* Construct devpath for this interface.       * Reserve enough space to replace name without realloc. */      fnsize = (sysfs_global.rlen + 11 + IFNAMSIZ + 1);      fname = malloc(fnsize);      if(fname == NULL)	{	  fprintf(stderr, "Error: Can't allocate SYSFS devpath\n");  	  return(-1);	}      /* Not true devpath for 2.6.20+, but this syslink should work */      target->sysfs_devplen = sprintf(fname, "%s/class/net/%s",				      sysfs_global.root, ifname);      target->sysfs_devpath = fname;    }  /* Loop on all sysfs selector */  for(findex = 0; findex < sysfs_global.filenum; findex++)    {      char *	p;      ssize_t	n;      /* Construct complete filename for the sysfs selector */      fnsize = (target->sysfs_devplen + 1 +		strlen(sysfs_global.filename[findex]) + 1);      fname = malloc(fnsize);      if(fname == NULL)	{	  fprintf(stderr, "Error: Can't allocate SYSFS filename\n");  	  free(linebuf);	  return(-1);	}      sprintf(fname, "%s/%s", target->sysfs_devpath,	      sysfs_global.filename[findex]);      /* Open the sysfs file for reading */      stream = fopen(fname, "r");      if(!stream) 	{	  /* Some sysfs attribute may no exist for some interface */	  if(verbose)	    fprintf(stderr, "Error: Can't open file `%s': %s\n", fname,		    strerror(errno)); 	  /* Next sysfs selector */	  continue;	}      /* Read file. Only one line in file. */      n = getline(&linebuf, &linelen, stream);      fclose(stream);      if(n <= 0)	{	  /* Some attributes are just symlinks to another directory.	   * We can read the attributes in that other directory	   * just fine, but sometimes the symlink itself gives a lot	   * of information.	   * Examples : SYSFS{device} and SYSFS{device/driver}	   * In such cases, get the name of the directory pointed to...	   */	  /*	   * I must note that the API for readlink() is very bad,	   * which force us to have this ugly code. Yuck !	   */	  int		allocsize = 128;	/* 256 = Good start */	  int		retry = 16;	  char *	linkpath = NULL;	  int		pathlen;	  /* Try reading the link with increased buffer size */	  do	    {	      allocsize *= 2;	      linkpath = realloc(linkpath, allocsize);	      pathlen = readlink(fname, linkpath, allocsize);	      /* If we did not hit the buffer limit, success */	      if(pathlen < allocsize)		break;	    }	  while(retry-- > 0);	  /* Check for error, most likely ENOENT */	  if(pathlen > 0)	    /* We have a symlink ;-) Terminate the string. */	    linkpath[pathlen] = '\0';	  else	    {	      /* Error ! */	      free(linkpath);	      /* A lot of information in the sysfs is implicit, given	       * by the position of a file in the tree. It is therefore	       * important to be able to read the various components	       * of a path. For this reason, we resolve '..' to the	       * real name of the parent directory... */	      /* We have at least 11 char, see above */	      if(!strcmp(fname + fnsize - 4, "/.."))		//if(!strcmp(fname + strlen(fname) - 3, "/.."))		{		  /* This procedure to get the realpath is not very		   * nice, but it's the "best practice". Hmm... */		  int	cwd_fd = open(".", O_RDONLY);		  linkpath = NULL;		  if(cwd_fd > 0)		    {		      int	ret = chdir(fname);		      if(ret == 0)			/* Using getcwd with NULL is a GNU extension. Nice. */			linkpath = getcwd(NULL, 0);		      /* This may fail, but it's not fatal */		      fchdir(cwd_fd);		    }		  /* Check if we suceeded */		  if(!linkpath)		    {		      free(linkpath);		      if(verbose)			fprintf(stderr, "Error: Can't read parent directory `%s'\n", fname);		      /* Next sysfs selector */		      continue;		    }		}	      else		{		  /* Some sysfs attribute are void for some interface,		   * we may have a real directory, or we may have permission		   * issues... */		  if(verbose)		    fprintf(stderr, "Error: Can't read file `%s'\n", fname);		  /* Next sysfs selector */		  continue;		}	    }	  /* Here, we have a link name or a parent directory name */	  /* Keep only the last component of path name, save it */	  p = basename(linkpath);	  sdup = strdup(p);	  free(linkpath);	}      else	{	  /* This is a regular file (well, pseudo file) */	  /* Get content, remove trailing '/n', save it */	  p = linebuf;	  if(p[n - 1] == '\n')	    n--;	  sdup = strndup(p, n);	}      if(sdup == NULL)	{	  fprintf(stderr, "Error: Can't allocate SYSFS value\n"); 	  free(linebuf);	  return(-1);	}      target->sysfs[findex] = sdup;      /* Activate */      target->active[SELECT_SYSFS] = 1;      if(verbose)	fprintf(stderr,		"Querying %s : Got SYSFS filename `%s' value `%s'.\n",		ifname, sysfs_global.filename[findex], target->sysfs[findex]);      /* Finished : Next sysfs selector */    }  /* Cleanup */  free(linebuf);  return(target->active[SELECT_SYSFS] ? 0 : -1);}/*------------------------------------------------------------------*//* * Add a Previous Interface Name selector to a mapping */static intmapping_addprevname(struct if_mapping *	ifnode,		   int *		active,		   char *		string,		   size_t		len,		   struct add_extra *	extra,		   int			linenum){  /* Avoid "Unused parameter" warning */  extra = extra;  /* Verify validity of string */  if(len >= sizeof(ifnode->prevname))    {       fprintf(stderr, "Old Interface Name too long at line %d\n", linenum);        return(-1);    }  /* Copy */  memcpy(ifnode->prevname, string, len + 1);   /* Activate */  ifnode->active[SELECT_PREVNAME] = 1;  active[SELECT_PREVNAME] = 1;  if(verbose)    fprintf(stderr,	    "Parsing : Added Old Interface Name `%s' from line %d.\n",	    ifnode->prevname, linenum);  return(0);}/*------------------------------------------------------------------*//* * Compare the Previous Interface Name of two mappings * Note : this one is special. */static intmapping_cmpprevname(struct if_mapping *	ifnode,		   struct if_mapping *	target){  /* Do wildcard matching, case insensitive */  return(fnmatch(ifnode->prevname, target->ifname, FNM_CASEFOLD));}/*------------------------------------------------------------------*//* * Extract the Previous Interface Name from a live interface */static intmapping_getprevname(int			skfd,		   const char *		ifname,		   struct if_mapping *	target,		   int			flag){  /* Avoid "Unused parameter" warning */  skfd = skfd; ifname = ifname; flag = flag;  /* Don't do anything, it's already in target->ifname ;-) */  /* Activate */  target->active[SELECT_PREVNAME] = 1;  return(0);}/*********************** MAPPING MANAGEMENTS ***********************//* * Manage interface mappings. * Each mapping tell us how to identify a specific interface name. * It is composed of a bunch of selector values. *//*------------------------------------------------------------------*//* * Create a new interface mapping and verify its name */static struct if_mapping *mapping_create(char *	pos,	       int	len,	       int	linenum){  struct if_mapping *	ifnode;  char *		star;  star = memchr(pos, '*', len);  /* Check overflow, need one extra char for wildcard */  if((len + (star != NULL)) > IFNAMSIZ)    {      fprintf(stderr, "Error: Interface name `%.*s' too long at line %d\n",	      (int) len, pos, linenum);        return(NULL);    }  /* Create mapping, zero it */  ifnode = calloc(1, sizeof(if_mapping));  if(!ifnode)    {      fprintf(stderr, "Error: Can't allocate interface mapping.\n");        return(NULL);    }  /* Set the name, terminates it */  memcpy(ifnode->ifname, pos, len);   ifnode->ifname[len] = '\0';   /* Check the interface name and issue various pedantic warnings.   * We assume people using takeover want to force interfaces to those   * names and know what they are doing, so don't bother them... */  if((!force_takeover) &&     ((!strcmp(ifnode->ifname, "eth0")) || (!strcmp(ifnode->ifname, "wlan0"))))    fprintf(stderr,	    "Warning: Interface name is `%s' at line %d, can't be mapped reliably.\n",	    ifnode->ifname, linenum);  if(strchr(ifnode->ifname, ':'))    fprintf(stderr, "Warning: Alias device `%s' at line %d probably can't be mapped.\n",	    ifnode->ifname, linenum);  if(verbose)    fprintf(stderr, "Parsing : Added Mapping `%s' from line %d.\n",	    ifnode->ifname, linenum);  /* Done */  return(ifnode);}/*------------------------------------------------------------------*//* * Find the most appropriate selector matching a given selector name */static inline const struct mapping_selector *selector_find(const char *	string,	      size_t		slen,	      int		linenum){  const struct mapping_selector *	found = NULL;  int			ambig = 0;  int			i;  /* Go through all selectors */  for(i = 0; selector_list[i].name != NULL; ++i)    {      /* No match -> next one */      if(strncasecmp(selector_list[i].name, string, slen) != 0)	continue;      /* Exact match -> perfect */

⌨️ 快捷键说明

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