I've finally gotten 'cpio' into a shape where it could be useable.
This version can archive and extract directories, sockets, FIFOs, devices, 
symlinks, and regular files.
Supported options are -iot, -H FMT (which is a dummy right now).
It only writes newc, and could read newc or newcrc.

This does NOT implement -d, which essentially is equivalent to 
mkdir -p $(dirname $FILE)
for every file that needs it.
Hard links are not supported, though it would be easy to add them given
a hash table or something like that.
I also have not implemented the "<n> blocks" output on stderr.
If desired, I can add it pretty simply.

There is one assumption this makes: that the mode of a file, as mode_t,
is bitwise equivalent to the mode as defined for the cpio format.
This is true of Linux, but is not mandated by POSIX.
If it is compiled for a system where that is false, the archives will
not be portable.

I still haven't cleaned up loopfiles_stdin.


If you see any holes in what it covers, let me know.



Thanks,
Isaac Dunham
/* cpio.c - a basic cpio
 *
 * Written 2013 AD by Isaac Dunham; this code is placed under the 
 * same license as toybox or as CC0, at your option.
USE_CPIO(NEWTOY(cpio, "H:iot", TOYFLAG_BIN))

config CPIO
  bool "cpio"
  default n
  help
    usage: cpio { -i | -o | -t } [-H fmt] 

    copy files into and out of an archive
    -i  extract from archive into file system (stdin is an archive)
    -o  create archive (stdin is a list of files, stdout is an archive)
    -t  list files (stdin is an archive, stdout is a list of files)
    -H fmt   Write archive in specified format:
    newc  new character format
*/
#define FOR_cpio
#include "toys.h"

GLOBALS(
char * fmt;
)

/* Iterate through a list of files, read from stdin.
 * No users need rw.
 */
void stdin_loopfiles(void (*function)(int fd, char *name))
{
  int fd;
  char *name = toybuf;

  while (name != NULL){
    memset(toybuf, 0, sizeof(toybuf));
    name = fgets(toybuf, sizeof(toybuf) - 1, stdin);
    if (name != NULL) {
      if (toybuf[strlen(name)] == '\n') { //if a line didn't fit, ignore.
        toybuf[strlen(name)] = '\0';
	fd = open(name, O_RDONLY);
	if (fd > 0) {
          function(fd, name);
	  close(fd);
	}
      }
    }
  }
}

struct cpio_newc_header {
  char    c_magic[6];
  char    c_ino[8];
  char    c_mode[8];
  char    c_uid[8];
  char    c_gid[8];
  char    c_nlink[8];
  char    c_mtime[8];
  char    c_filesize[8];
  char    c_devmajor[8];
  char    c_devminor[8];
  char    c_rdevmajor[8];
  char    c_rdevminor[8];
  char    c_namesize[8];
  char    c_check[8];
};

void write_cpio_member(int fd, char *name)
{
  struct cpio_newc_header hdr;
  memset(&hdr, 0, sizeof(hdr));
  struct stat buf;
  if (stat(name, &buf) == -1) return;
  //strcpy(hdr.c_magic, "070701");
  snprintf(&hdr, sizeof(hdr), "070701%08o%08o%08o%08o",
	   buf.st_ino, buf.st_mode, buf.st_uid, buf.st_gid, buf.st_nlink);
  
}

void cpio_main(void)
{
  error_exit("Sorry, cpio isn't implemented yet");
}
_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to