lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

/*
**	Posix tar object in LPC. Zellski, zell@alyx.com, 1996.
**
**	Written for Igor Mud, a DGD-based 2.4.5. Should be fairly
**	portable -- does need mutable, non-zero-sensitive strings.
**
**	Anybody is free to do anything with this code as far as I
**	am concerned. Of course, I also consider myself free to call
**	people bloody bastards when they are.
**
**      MudOS port by Beek
*/

# define FILES_PER_SECOND	10

# define LF_DIR			5
# define LF_NORMAL		0


/* change these any way your lil' hearts desire */

# define UID			1701
# define GID			2261
# define UNAME			to_buffer("zell")
# define GNAME			to_buffer("alyx")

buffer to_buffer(mixed arg) {
    buffer ret;
    
    if (intp(arg))
	arg = arg + "";

    if (stringp(arg)) {
	ret = allocate_buffer(strlen(arg));
	write_buffer(ret, 0, arg);
    } 

    return ret;
}

void header_insert(buffer what, int offset, int size);

#define null_record	allocate_buffer(0x200)

buffer	header_record;


void tar(string dir, string archive) {
   rm(archive);
   call_out("add_next_files", 0, ({ dir }), archive);
}


buffer octal(int num, int width) {
   buffer	result;
   int		i;

   result = null_record;
   i = width;

   result[-- i] = ' ';

   do {
      result[-- i] = '0' + (num & 0x07);
      num >>= 3;
   } while (num != 0);

   while (i > 0) result[-- i] = ' ';

   return result[0 .. width-1];
}


void header_insert(buffer what, int offset, int size) {
   int	i, mid, end;

   if (sizeof(what) > size) {
      what = what[0 .. size-1];
   }
   mid = offset + sizeof(what);
   end = offset + size;
   header_record[offset..mid-1] = what;
   if (end - mid)
       header_record[mid..end-1] = allocate_buffer(end - mid);
}

void write_header(string archive, string name, int size, int type) {
   buffer	str;
   int		sum;
   int		i;

   header_insert(to_buffer(name),	0x00, 0x64);
   header_insert(octal(size, 12),	0x7C, 0x0C);
   header_insert(octal(time(), 12),	0x88, 0x0C);
   header_insert(to_buffer(type),	0x9C, 0x01);
   header_insert(to_buffer("        "),	0x94, 0x08);

   for (i = 0; i < 0x200; i ++) {
      sum += header_record[i];
   }
   str = octal(sum, 7)[0..<2] + allocate_buffer(2);
   str[7] = ' '; /* tar SUCKS */

   header_insert(str, 			0x94, 0x08);

   write_buffer(archive, file_size(archive), header_record);
}

void add_next_files(string *files, string archive) {
   int	count;

   for (count = 0; count < FILES_PER_SECOND; count ++) {
      if (file_size(files[0]) == -2) {
	 /* a directory: descend and push contents onto stackish thing */
	 int		i;
	 string	       *contents;

	 contents = get_dir(files[0] + "/");

	 for (i = 0; i < sizeof(contents); i ++) {
	    contents[i] = files[0] + "/" + contents[i];
	 }
	 write_header(archive, files[0] + "/", 0, LF_DIR);

	 files = contents + files[1 ..];
      } else {
	 if (files[0] != archive) {
	    int	i, size;

	    /* don't include archive in archive :) */

	    size = file_size(files[0]);

	    write(files[0] + "\t (" + size + ") : ");

	    if (size > 0) {

	       write_header(archive, files[0], size, LF_NORMAL);

	       /* write all full records first */
	       for (i = 0; i < (size & 0xFFFE00); i += 0x200) {
		  string	data;

		  data = read_buffer(files[0], i, 0x200);
		  if (!data) {
		     error("failed to read 512 bytes from " + files[0]);
		  }
		  write_buffer(archive, file_size(archive), data);
	       }
	       /* pad last record, if anything left to write */
	       if (size % 0x200) {
		  buffer	data;

		  data = read_buffer(files[0], i, size % 0x200) + null_record;
		  if (!data) {
		     error("failed to read " + (size % 0x200) +
			   "  bytes from " + files[0]);
		  }
		  write_buffer(archive, file_size(archive), data[0 .. 0x1FF]); /* write 512 bytes */
	       }
	       write("done.\n");
	    } else {
	       write("skipped.\n");
	    }
	 }
	 files = files[1 ..];
	 if (!sizeof(files)) {
	    write("DONE.\n");
	    return;
	 }
      }
   }
   call_out("add_next_files", 1, files, archive);
}


void create() {
      header_record = null_record;

      header_insert(to_buffer("ustar  "), 0x101, 0x08);	/* POSIX-tar magic */
      header_insert(to_buffer(" 40755 "), 0x64, 0x08);
      header_insert(octal(UID, 7),0x6C, 0x08);
      header_insert(octal(GID, 7),0x74, 0x08);
      header_insert(UNAME, 0x109, 0x20);
      header_insert(GNAME, 0x129, 0x20);
}