Beispiel #1
0
/* This function constructs a root inode with no name and
   no data.  The inode is then written to the filesystem
   image.  */
int
make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, int depth)
{
  struct jffs_file f;
  struct stat st;
  __u16 chksum;

  if (stat(root_dir_path, &st) < 0)
  {
    perror("stat");
    exit(1);
  }

  f.inode.magic = JFFS_MAGIC;
  f.inode.ino = first_ino;
  f.inode.pino = 0;
  f.inode.version = 1;
  f.inode.mode = st.st_mode;
  f.inode.uid = 0; /* root */
  f.inode.gid = 0; /* root */
  f.inode.atime = st.st_atime;
  f.inode.mtime = st.st_mtime;
  f.inode.ctime = st.st_ctime;
  f.inode.offset = 0;
  f.inode.dsize = 0;
  f.inode.rsize = 0;
  f.inode.nsize = 0;
  /*f.inode.nlink = st.st_nlink;*/
  f.inode.nlink = 1;
  f.inode.spare = 0;
  f.inode.rename = 0;
  f.inode.deleted = 0;
  f.inode.accurate = 0;
  f.inode.dchksum = 0;
  f.inode.nchksum = 0;
  f.inode.chksum = 0;
  f.name = 0;
  f.data = 0;
  jffs_swap_inode(&f.inode);
  chksum = jffs_checksum(&f.inode, sizeof(struct jffs_raw_inode));
  jffs_swap_inode(&f.inode);
  f.inode.chksum = chksum;
  f.inode.accurate = 0xff;
  write_file(&f, fs, st);
  if (verbose >= 1)
  {
    jffs_print_trace(root_dir_path, depth);
  }
  if (verbose >= 2)
  {
    jffs_print_raw_inode(&f.inode);
  }
  return first_ino;
}
Beispiel #2
0
/* This function constructs a root inode with no name and
   no data.  The inode is then written to the filesystem
   image.  */
int
make_root_dir(FILE *fs, int first_ino, const char *root_dir_path, int depth)
{
  struct jffs_file f;
  struct stat st;

  if (stat(root_dir_path, &st) < 0)
  {
    perror("stat");
    exit(1);
  }

  write_val32(&f.inode.magic, JFFS_MAGIC);
  write_val32(&f.inode.ino, first_ino);
  write_val32(&f.inode.pino, 0);
  write_val32(&f.inode.version, 1);
  write_val32(&f.inode.mode, st.st_mode);
  write_val16(&f.inode.uid, 0); /* root */
  write_val16(&f.inode.gid, 0); /* root */
  write_val32(&f.inode.atime, st.st_atime);
  write_val32(&f.inode.mtime, st.st_mtime);
  write_val32(&f.inode.ctime, st.st_ctime);
  write_val32(&f.inode.offset, 0);
  write_val32(&f.inode.dsize, 0);
  write_val32(&f.inode.rsize,0);
  f.inode.nsize = 0;
  /*f.inode.nlink = st.st_nlink;*/
  f.inode.nlink = 1;
  f.inode.spare = 0;
  f.inode.rename = 0;
  f.inode.deleted = 0;
  f.inode.accurate = 0;
  write_val32(&f.inode.dchksum, 0);
  write_val16(&f.inode.nchksum, 0);
  write_val16(&f.inode.chksum, 0);
  f.name = 0;
  f.data = 0;
  write_val16(&f.inode.chksum, jffs_checksum(&f.inode, sizeof(struct jffs_raw_inode)));
  f.inode.accurate = 0xff;
  write_file(&f, fs, st);
  if (verbose >= 1)
  {
    jffs_print_trace(root_dir_path, depth);
  }
  if (verbose >= 2)
  {
    jffs_print_raw_inode(&f.inode);
  }
  return first_ino;
}
Beispiel #3
0
/* This is the routine that constructs the filesystem image.  */
int
mkfs(FILE *fs, const char *path, int ino, int parent, int depth)
{
  struct dirent *dir_entry;
  DIR *dir;
  struct stat st;
  struct jffs_file f;
  int name_len;
  int pos = 0;
  int new_ino = ino;
  char *filename;
  int path_len = strlen(path);

  if (verbose >= 2)
  {
    fprintf(stderr, "***mkfs(): path: \"%s\"\r\n", path);
  }

  if (!(dir = opendir(path)))
  {
    perror("opendir");
    fprintf(stderr, "mkfs(): opendir() failed! (%s)\n", path);
    exit(1);
  }

  while ((dir_entry = readdir(dir)))
  {
    if (verbose >= 2)
    {
     fprintf(stderr, "mkfs(): name: %s\n", dir_entry->d_name);
    }
    name_len = strlen(dir_entry->d_name);

    if (((name_len == 1)
         && (dir_entry->d_name[0] == '.'))
        || ((name_len == 2)
            && (dir_entry->d_name[0] == '.')
            && (dir_entry->d_name[1] == '.')))
    {
      continue;
    }

    if (!(filename = (char *)alloca(path_len + name_len + 1)))
    {
      fprintf(stderr, "mkfs(): Allocation failed!\n");
      exit(0);
    }
    strcpy(filename, path);
    strcat(filename, dir_entry->d_name);

    if (verbose >= 2)
    {
      fprintf(stderr, "mkfs(): filename: %s\n", filename);
    }

    if (lstat(filename, &st) < 0)
    {
      perror("lstat");
      exit(1);
    }

    if (verbose >= 2)
    {
      fprintf(stderr, "mkfs(): filename: \"%s\", ino: %d, parent: %d\n",
              filename, new_ino, parent);
    }

    if (S_ISREG(st.st_mode) && st.st_size == 0)
    {
      char devname[32];
      char type;
      int major;
      int minor;

      if (sscanf(dir_entry->d_name, "@%31[-a-zA-Z0-9_+],%c,%d,%d",
          devname, &type, &major, &minor) == 4)
      {
        strcpy(dir_entry->d_name, devname);
        st.st_rdev = makedev(major, minor);
        st.st_mode &= ~S_IFMT;
        switch (type) {
        case 'c':
        case 'u':
          st.st_mode |= S_IFCHR;
          break;
        case 'b':
          st.st_mode |= S_IFBLK;
          break;
        case 'p':
          st.st_mode |= S_IFIFO;
          break;
        default:
          fprintf(stderr, "mkfs(): invalid special device type '%c' for file %s\n", type, filename);
		  exit(1);
        }
      }
    }

    if (squash) {
      st.st_uid = 0;
      st.st_gid = 0;
    }

    write_val32(&f.inode.magic, JFFS_MAGIC);
    write_val32(&f.inode.ino, new_ino);
    write_val32(&f.inode.pino, parent);
    write_val32(&f.inode.version, 1);
    write_val32(&f.inode.mode, st.st_mode);
    write_val16(&f.inode.uid, st.st_uid);
    write_val16(&f.inode.gid, st.st_gid);
    write_val32(&f.inode.atime, st.st_atime);
    write_val32(&f.inode.mtime, st.st_mtime);
    write_val32(&f.inode.ctime, st.st_ctime);
    write_val32(&f.inode.dsize, 0);
    write_val32(&f.inode.rsize, 0);
    f.inode.nsize = name_len;
    /*f.inode.nlink = st.st_nlink;*/
    f.inode.nlink = 1;
    f.inode.spare = 0;
    f.inode.rename = 0;
    f.inode.deleted = 0;
    f.inode.accurate = 0;
    write_val32(&f.inode.dchksum, 0);
    write_val16(&f.inode.nchksum, 0);
    write_val16(&f.inode.chksum, 0);
    if (dir_entry->d_name)
    {
      f.name = strdup(dir_entry->d_name);
    }
    else
    {
      f.name = 0;
    }

  repeat:
    write_val32(&f.inode.offset, pos);
    f.data = 0;
    f.inode.accurate = 0;
    if (S_ISREG(st.st_mode) && st.st_size)
    {
      if (st.st_size - pos < MAX_CHUNK_SIZE)
      {
	write_val32(&f.inode.dsize, st.st_size - pos);
      }
      else
      {
	write_val32(&f.inode.dsize, MAX_CHUNK_SIZE);
      }

      read_data(&f, path, pos);
      pos += read_val32(&f.inode.dsize);
    }
    else if (S_ISLNK(st.st_mode))
    {
      int linklen;
      unsigned char *linkdata = (unsigned char *)malloc(1000);
      if (!linkdata)
      {
        fprintf(stderr, "mkfs(): malloc() failed! (linkdata)\n");
        exit(1);
      }
      if ((linklen = readlink(filename, linkdata, 1000)) < 0)
      {
        free(linkdata);
        fprintf(stderr, "mkfs(): readlink() failed! f.name = \"%s\"\n",
                f.name);
        exit(1);
      }

      write_val32(&f.inode.dsize, linklen);
      f.data = linkdata;
      f.data[linklen] = '\0';
    }
    else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
    {
      write_val32(&f.inode.dsize, sizeof(st.st_rdev) / 4);
    }

    write_val16(&f.inode.chksum, 0);
    if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
    {
      write_val32(&f.inode.dchksum, jffs_checksum((void *)f.data, read_val32(&f.inode.dsize)));
    }
    else
    {
      write_val32(&f.inode.dchksum, jffs_checksum((void *)&st.st_rdev, sizeof(st.st_rdev) / 4));
    }

    write_val16(&f.inode.nchksum, jffs_checksum((void *)f.name, f.inode.nsize));
    write_val16(&f.inode.chksum, jffs_checksum((void *)&f.inode, sizeof(struct jffs_raw_inode)));
    f.inode.accurate = 0xff;

    write_file(&f, fs, st);
    if (S_ISREG(st.st_mode) && st.st_size)
    {
      if (pos < st.st_size)
      {
	write_val32(&f.inode.version, read_val32(&f.inode.version) + 1);
	goto repeat;
      }
    }

    new_ino++;
    pos = 0;
    if (verbose >= 1)
    {
      jffs_print_trace(f.name, depth);
    }
    if (verbose >= 2)
    {
      jffs_print_raw_inode(&f.inode);
    }

    if (S_ISDIR(st.st_mode))
    {
      char *new_path;

      if (!(new_path = (char *)alloca(strlen(path) + name_len + 1 + 1)))
      {
        fprintf(stderr, "mkfs(): alloca() failed! (new_path)\n");
        exit(1);
      }
      strcpy(new_path, path);
      strncat(new_path, f.name, f.inode.nsize);
      strcat(new_path, "/");

      if (verbose >= 2)
      {
        fprintf(stderr, "mkfs(): new_path: \"%s\"\n", new_path);
      }
      new_ino = mkfs(fs, new_path, new_ino, new_ino - 1, depth + 1);
    }
    if (f.name)
    {
      free(f.name);
    }
    if (f.data)
    {
      free(f.data);
    }
  }

  closedir(dir);
  return new_ino;
}
Beispiel #4
0
int
main(int argc, char **argv)
{
	int fs;
	struct stat sb;
	uint32_t wordbuf;
	off_t pos = 0;
	off_t end;
	struct jffs_raw_inode ino;
	unsigned char namebuf[4096];
	int myino = -1;

	if (argc < 2) {
		printf("no filesystem given\n");
		exit(1);
	}

	fs = open(argv[1], O_RDONLY);
	if (fs < 0) {
		perror("open");
		exit(1);
	}

	if (argc > 2) {
	  myino = atol(argv[2]);
	  printf("Printing ino #%d\n" , myino);
	}

	if (fstat(fs, &sb) < 0) {
		perror("stat");
		close(fs);
		exit(1);
	}
	end = sb.st_size;

	while (pos < end) {
		if (pread(fs, &wordbuf, 4, pos) < 0) {
			perror("pread");
			exit(1);
		}

		switch(wordbuf) {
		case JFFS_EMPTY_BITMASK:
		  //			printf("0xff started at 0x%lx\n", pos);
			for (; pos < end && wordbuf == JFFS_EMPTY_BITMASK; pos += 4) {
				if (pread(fs, &wordbuf, 4, pos) < 0) {
					perror("pread");
					exit(1);
				}
			}
			if (pos < end)
			  pos -= 4;
			//			printf("0xff ended at 0x%lx\n", pos);
			continue;

		case JFFS_DIRTY_BITMASK:
		  //			printf("0x00 started at 0x%lx\n", pos);
			for (; pos < end && wordbuf == JFFS_DIRTY_BITMASK; pos += 4) {
				if (pread(fs, &wordbuf, 4, pos) < 0) {
					perror("pread");
					exit(1);
				}
			}
			if (pos < end)
			  pos -=4;
			//			printf("0x00 ended at 0x%lx\n", pos);
			continue;

		default:
			printf("Argh. Dirty memory at 0x%lx\n", pos);
			//			file_hexdump(fs, pos, 128);
			for (pos += 4; pos < end; pos += 4) {
				if (pread(fs, &wordbuf, 4, pos) < 0) {
					perror("pread");
					exit(1);
				}
				if (wordbuf == JFFS_MAGIC_BITMASK)
					break;
                        }

		case JFFS_MAGIC_BITMASK:
			if (pread(fs, &ino, sizeof(ino), pos) < 0) {
				perror("pread");
				exit(1);
			}
			if (myino == -1 || ino.ino == myino) {
				printf("Magic found at 0x%lx\n", pos);
				jffs_print_raw_inode(&ino);
			}
			pos += sizeof(ino);

			if (myino == -1 || ino.ino == myino) {
				if (ino.nsize) {
					if (pread(fs, namebuf, min(ino.nsize, 4095), pos) < 0) {
						perror("pread");
						exit(1);
					}
					if (ino.nsize < 4095)
						namebuf[ino.nsize] = 0;
					else
						namebuf[4095] = 0;
					printf("Name: \"%s\"\n", namebuf);
				} else {
					printf("No Name\n");
				}
			}
			pos += (ino.nsize + 3) & ~3;

			pos += (ino.dsize + 3) & ~3;
		}



	}
}
Beispiel #5
0
/* This is the routine that constructs the filesystem image.  */
int
mkfs(FILE *fs, const char *path, int ino, int parent, int depth)
{
  struct dirent *dir_entry;
  DIR *dir;
  struct stat st;
  struct jffs_file f;
  int name_len;
  int pos = 0;
  int new_ino = ino;
  char *filename;
  int path_len = strlen(path);
  __u16 chksum;

  if (verbose >= 2)
  {
    fprintf(stderr, "***mkfs(): path: \"%s\"\r\n", path);
  }

  if (!(dir = opendir(path)))
  {
    perror("opendir");
    fprintf(stderr, "mkfs(): opendir() failed! (%s)\n", path);
    exit(1);
  }

  while ((dir_entry = readdir(dir)))
  {
    if (verbose >= 2)
    {
     fprintf(stderr, "mkfs(): name: %s\n", dir_entry->d_name);
    }
    name_len = strlen(dir_entry->d_name);

    if (((name_len == 1)
         && (dir_entry->d_name[0] == '.'))
        || ((name_len == 2)
            && (dir_entry->d_name[0] == '.')
            && (dir_entry->d_name[1] == '.')))
    {
      continue;
    }

    if (!(filename = (char *)alloca(path_len + name_len + 1)))
    {
      fprintf(stderr, "mkfs(): Allocation failed!\n");
      exit(0);
    }
    strcpy(filename, path);
    strcat(filename, dir_entry->d_name);

    if (verbose >= 2)
    {
      fprintf(stderr, "mkfs(): filename: %s\n", filename);
    }

    if (lstat(filename, &st) < 0)
    {
      perror("lstat");
      exit(1);
    }

    if (verbose >= 2)
    {
      fprintf(stderr, "mkfs(): filename: \"%s\", ino: %d, parent: %d\n",
              filename, new_ino, parent);
    }

    f.inode.magic = JFFS_MAGIC;
    f.inode.ino = new_ino;
    f.inode.pino = parent;
    f.inode.version = 1;
    f.inode.mode = st.st_mode;
    f.inode.uid = st.st_uid;
    f.inode.gid = st.st_gid;
    f.inode.atime = st.st_atime;
    f.inode.mtime = st.st_mtime;
    f.inode.ctime = st.st_ctime;
    f.inode.dsize = 0;
    f.inode.rsize = 0;
    f.inode.nsize = name_len;
    /*f.inode.nlink = st.st_nlink;*/
    f.inode.nlink = 1;
    f.inode.spare = 0;
    f.inode.rename = 0;
    f.inode.deleted = 0;
    f.inode.accurate = 0;
    f.inode.dchksum = 0;
    f.inode.nchksum = 0;
    f.inode.chksum = 0;
    if (dir_entry->d_name)
    {
      f.name = strdup(dir_entry->d_name);
    }
    else
    {
      f.name = 0;
    }

  repeat:
    f.inode.offset = pos;
    f.data = 0;
    f.inode.accurate = 0;
    if (S_ISREG(st.st_mode) && st.st_size)
    {
      if (st.st_size - pos < MAX_CHUNK_SIZE)
      {
	f.inode.dsize = st.st_size - pos;
      }
      else
      {
	f.inode.dsize = MAX_CHUNK_SIZE;
      }

      read_data(&f, path, pos);
      pos += f.inode.dsize;
    }
    else if (S_ISLNK(st.st_mode))
    {
      int linklen;
      unsigned char *linkdata = (unsigned char *)malloc(1000);
      if (!linkdata)
      {
        fprintf(stderr, "mkfs(): malloc() failed! (linkdata)\n");
        exit(1);
      }
      if ((linklen = readlink(filename, linkdata, 1000)) < 0)
      {
        free(linkdata);
        fprintf(stderr, "mkfs(): readlink() failed! f.name = \"%s\"\n",
                f.name);
        exit(1);
      }

      f.inode.dsize = linklen;
      f.data = linkdata;
      f.data[linklen] = '\0';
    }
    else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
    {
      f.inode.dsize = sizeof(st.st_rdev) / 4;
    }

    f.inode.chksum = 0;
    if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
    {
      f.inode.dchksum = jffs_checksum((void *)f.data, f.inode.dsize);
    }
    else
    {
      f.inode.dchksum
	= jffs_checksum((void *)&st.st_rdev, sizeof(st.st_rdev) / 4);
    }

    f.inode.nchksum = jffs_checksum((void *)f.name, f.inode.nsize);
	jffs_swap_inode(&f.inode);
    chksum = jffs_checksum((void *)&f.inode, sizeof(struct jffs_raw_inode));
	jffs_swap_inode(&f.inode);
    f.inode.chksum = chksum;
    f.inode.accurate = 0xff;

    write_file(&f, fs, st);
    if (S_ISREG(st.st_mode) && st.st_size)
    {
      if (pos < st.st_size)
      {
	f.inode.version++;
	goto repeat;
      }
    }

    new_ino++;
    pos = 0;
    if (verbose >= 1)
    {
      jffs_print_trace(f.name, depth);
    }
    if (verbose >= 2)
    {
      jffs_print_raw_inode(&f.inode);
    }

    if (S_ISDIR(st.st_mode))
    {
      char *new_path;

      if (!(new_path = (char *)alloca(strlen(path) + name_len + 1 + 1)))
      {
        fprintf(stderr, "mkfs(): alloca() failed! (new_path)\n");
        exit(1);
      }
      strcpy(new_path, path);
      strncat(new_path, f.name, f.inode.nsize);
      strcat(new_path, "/");

      if (verbose >= 2)
      {
        fprintf(stderr, "mkfs(): new_path: \"%s\"\n", new_path);
      }
      new_ino = mkfs(fs, new_path, new_ino, new_ino - 1, depth + 1);
    }
    if (f.name)
    {
      free(f.name);
    }
    if (f.data)
    {
      free(f.data);
    }
  }

  closedir(dir);
  return new_ino;
}