Logo Search packages:      
Sourcecode: ksh version File versions  Download package

ar-s5r0.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 2002-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                                                                      *
***********************************************************************/
#pragma prototyped
/*
 * s5r0 archive format method
 */

#include <ardirlib.h>
#include <swap.h>
#include <tm.h>

#define MAGIC           "<ar>"
#define MAGIC_SIZE      4

typedef struct Header_s
{
      char  ar_magic[MAGIC_SIZE];   /* MAGIC                */
      char  ar_name[16];
      char  ar_date[4];       /* swapget() accessed         */
      char  ar_syms[4];       /*    "                 */
} Header_t;

typedef struct Member_s
{
      char  arf_name[16];
      char  arf_date[4];            /* swapget() accessed         */
      char  arf_uid[4];       /*    "                 */
      char  arf_gid[4];       /*    "                 */
      char  arf_mode[4];            /*    "                 */
      char  arf_size[4];            /*    "                 */
} Member_t;

typedef struct Symbol_s
{
      char  sym_name[8];            /* ' ' terminated       */
      char  sym_ptr[4];       /* swapget() accessed         */
} Symbol_t;

typedef struct State_s              /* method state               */
{
      off_t       current;    /* current dirent offset      */
      off_t       offset;           /* next dirent offset         */
      off_t       patch;            /* symdir time patch offset   */
      int         swap;       /* swapget() op if necessary  */
      int         touch;            /* touch symbol table time    */
      Member_t    member;           /* current member       */
} State_t;

/*
 * closef
 */

static int
s5r0close(Ardir_t* ar)
{
      State_t*    state;
      int         r;
      Header_t    header;

      if (!ar || !(state = (State_t*)ar->data))
            r = -1;
      else
      {
            r = 0;
            if (state->touch && state->patch >= 0)
            {
                  if (lseek(ar->fd, state->patch, SEEK_SET) != state->patch)
                        r = -1;
                  else
                  {
                        swapput(0, (char*)&header.ar_date, sizeof(header.ar_date), (intmax_t)((unsigned long)time((time_t*)0) + 5));
                        if (write(ar->fd, &header.ar_date, sizeof(header.ar_date)) != sizeof(header.ar_date))
                              r = -1;
                  }
            }
            free(state);
      }
      return r;
}

/*
 * openf
 */

static int
s5r0open(Ardir_t* ar, char* buf, size_t n)
{
      Header_t*   hdr;
      State_t*    state;

      if (n <= sizeof(Header_t))
            return -1;
      hdr = (Header_t*)buf;
      if (memcmp(hdr->ar_magic, MAGIC, MAGIC_SIZE))
            return -1;
      if (!(state = newof(0, State_t, 1, 0)))
            return -1;
      ar->data = (void*)state;
      state->patch = offsetof(Header_t, ar_date);
      state->offset = sizeof(Header_t) + swapget(0, hdr->ar_syms, sizeof(hdr->ar_syms)) * sizeof(Symbol_t);
      ar->truncate = 15;
      return 0;
}

/*
 * nextf
 */

static Ardirent_t*
s5r0next(Ardir_t* ar)
{
      State_t*    state = (State_t*)ar->data;
      ssize_t           z;

      state->current = state->offset;
      if (lseek(ar->fd, state->offset, SEEK_SET) != state->offset)
      {
            ar->error = errno;
            return 0;
      }
      if (read(ar->fd, (char*)&state->member, sizeof(state->member)) != sizeof(state->member))
      {
            if ((z = read(ar->fd, (char*)&state->member, 1)) < 0)
                  ar->error = errno;
            else if (z > 0)
                  ar->error = EINVAL;
            return 0;
            
      }
      ar->dirent.name = state->member.arf_name;
      ar->dirent.mtime = swapget(0, (char*)&state->member.arf_date, sizeof(state->member.arf_date));
      ar->dirent.uid = swapget(0, (char*)&state->member.arf_uid, sizeof(state->member.arf_uid));
      ar->dirent.gid = swapget(0, (char*)&state->member.arf_gid, sizeof(state->member.arf_gid));
      ar->dirent.mode = swapget(0, (char*)&state->member.arf_mode, sizeof(state->member.arf_mode));
      ar->dirent.offset = state->offset += sizeof(state->member);
      ar->dirent.size = swapget(0, (char*)&state->member.arf_size, sizeof(state->member.arf_size));
      state->offset += ar->dirent.size + (ar->dirent.size & 01);
      return &ar->dirent;
}

/*
 * changef
 */

static int
s5r0change(Ardir_t* ar, Ardirent_t* ent)
{
      State_t*    state = (State_t*)ar->data;
      off_t       o;

      o = state->current + offsetof(Member_t, arf_date);
      if (lseek(ar->fd, o, SEEK_SET) != o)
      {
            ar->error = errno;
            return -1;
      }
      swapput(0, (char*)&state->member.arf_date, sizeof(state->member.arf_date), (intmax_t)ent->mtime);
      if (write(ar->fd, &state->member.arf_date, sizeof(state->member.arf_date)) != sizeof(state->member.arf_date))
      {
            ar->error = errno;
            return -1;
      }
      state->touch = 1;
      return 0;
}

Ardirmeth_t ar_s5r0 =
{
      "s5r0",
      "system V release 0 archive",
      s5r0open,
      s5r0next,
      s5r0change,
      0,
      0,
      s5r0close,
      ar_s5r0_next
};

Generated by  Doxygen 1.6.0   Back to index