Beispiel #1
0
static int i2cdetect_dash_l(struct dirtree *node)
{
  int suffix_len = strlen("/name");
  int bus;
  char *fname, *p;
  unsigned long funcs;

  if (!node->parent) return DIRTREE_RECURSE; // Skip the directory itself.

  if (sscanf(node->name, "i2c-%d", &bus) != 1) return 0;
  funcs = i2c_get_funcs(bus);

  fname = dirtree_path(node, &suffix_len);
  strcat(fname, "/name");
  xreadfile(fname, toybuf, sizeof(toybuf));
  free(fname);
  if ((p = strchr(toybuf, '\n'))) *p = 0;

  // "i2c-1	i2c       	Synopsys DesignWare I2C adapter 	I2C adapter"
  printf("%s\t%-10s\t%-32s\t%s\n", node->name,
         (funcs & I2C_FUNC_I2C) ? "i2c" : "?",
         toybuf,
         (funcs & I2C_FUNC_I2C) ? "I2C Adapter" : "?");

  return 0;
}
Beispiel #2
0
// Get directory information.
static int retell_dir(struct dirtree *root)
{
  char *fpath = NULL;
  
  if (root->again) {
    xputc('\n');
    return 0;
  }
  if (S_ISDIR(root->st.st_mode) && !root->parent) 
    return (DIRTREE_RECURSE | DIRTREE_COMEAGAIN);

  fpath = dirtree_path(root, NULL);
  //Special case: with '-a' option and '.'/'..' also included in printing list.
  if ((root->name[0] != '.') || (toys.optflags & FLAG_a)) {
    print_file_attr(fpath);
    if (S_ISDIR(root->st.st_mode) && (toys.optflags & FLAG_R)
        && dirtree_notdotdot(root)) {
      xprintf("\n%s:\n", fpath);
      free(fpath);
      return (DIRTREE_RECURSE | DIRTREE_COMEAGAIN);
    }
  }
  free(fpath);
  return 0;
}
Beispiel #3
0
// Update attribute of given file.
static int update_attr(struct dirtree *root)
{
  unsigned long fval = 0;
  char *fpath = NULL;
  int fd;

  if (!dirtree_notdotdot(root)) return 0;

  /*
   * if file is a link and recursive is set or file is not regular+link+dir
   * (like fifo or dev file) then escape the file.
   */
  if ((S_ISLNK(root->st.st_mode) && chattr.recursive)
    || (!S_ISREG(root->st.st_mode) && !S_ISLNK(root->st.st_mode)
      && !S_ISDIR(root->st.st_mode)))
    return 0;

  fpath = dirtree_path(root, NULL);
  if (-1 == (fd=open(fpath, O_RDONLY | O_NONBLOCK))) {
    free(fpath);
    return DIRTREE_ABORT;
  }
  // Get current attr of file.
  if (ext2_getflag(fd, &(root->st), &fval) < 0) {
    perror_msg("read flags of '%s'", fpath);
    free(fpath);
    xclose(fd);
    return DIRTREE_ABORT;
  }
  if (chattr.set) { // for '=' operator.
    if (ext2_setflag(fd, &(root->st), chattr.set) < 0)
      perror_msg("setting flags '%s'", fpath);
  } else { // for '-' / '+' operator.
    fval &= ~(chattr.rm);
    fval |= chattr.add;
    if (!S_ISDIR(root->st.st_mode)) fval &= ~FS_DIRSYNC_FL;
    if (ext2_setflag(fd, &(root->st), fval) < 0)
      perror_msg("setting flags '%s'", fpath);
  }
  if (chattr.vflag) { // set file version
    if (ioctl(fd, FS_IOC_SETVERSION, (void*)&chattr.version) < 0)
      perror_msg("while setting version on '%s'", fpath);
  }
  free(fpath);
  xclose(fd);

  if (S_ISDIR(root->st.st_mode) && chattr.recursive) return DIRTREE_RECURSE;
  return 0;
}
Beispiel #4
0
char *dirtree_path(struct dirtree *node, int *plen)
{
  char *path;
  int len;

  if (!node) {
    path = xmalloc(*plen);
    *plen = 0;
    return path;
  }

  len = (plen ? *plen : 0)+strlen(node->name)+1;
  path = dirtree_path(node->parent, &len);
  if (len && path[len-1] != '/') path[len++]='/';
  len = (stpcpy(path+len, node->name) - path);
  if (plen) *plen = len;

  return path;
}
Beispiel #5
0
struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags)
{
  struct dirtree *dt = NULL;
  struct stat st;
  int len = 0, linklen = 0;

  if (name) {
    // open code this because haven't got node to call dirtree_parentfd() on yet
    int fd = parent ? parent->data : AT_FDCWD;

    if (xfstatat(fd, name, &st, AT_SYMLINK_NOFOLLOW*!(flags&DIRTREE_SYMFOLLOW)))
      goto error;
    if (S_ISLNK(st.st_mode)) {
      if (0>(linklen = xreadlinkat(fd, name, libbuf, 4095))) goto error;
      libbuf[linklen++]=0;
    }
    len = strlen(name);
  }
  dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen);
  dt->parent = parent;
  if (name) {
    memcpy(&(dt->st), &st, sizeof(struct stat));
    strcpy(dt->name, name);

    if (linklen) {
      dt->symlink = memcpy(len+(char *)dt, libbuf, linklen);
      dt->data = --linklen;
    }
  }

  return dt;

error:
  if (!(flags&DIRTREE_SHUTUP) && notdotdot(name)) {
    char *path = parent ? dirtree_path(parent, 0) : "";

    perror_msg("%s%s%s", path, parent ? "/" : "", name);
    if (parent) free(path);
  }
  if (parent) parent->symlink = (char *)1;
  free(dt);
  return 0;
}
Beispiel #6
0
static int callback(struct dirtree *node)
{
  // Entries in /sys/class/block aren't char devices, so skip 'em.  (We'll
  // get block devices out of /sys/block.)
  if(!strcmp(node->name, "block")) return 0;

  // Does this directory have a "dev" entry in it?
  // This is path based because the hotplug callbacks are
  if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) {
    int len=4;
    char *dev = dirtree_path(node, &len);
    strcpy(dev+len, "/dev");
    if (!access(dev, R_OK)) make_device(dev);
    free(dev);
  }

  // Circa 2.6.25 the entries more than 2 deep are all either redundant
  // (mouse#, event#) or unnamed (every usb_* entry is called "device").

  return (node->parent && node->parent->parent) ? 0 : DIRTREE_RECURSE;
}