Logo Search packages:      
Sourcecode: ksh version File versions

ar-local.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 2002-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                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
/*
 * local archive format method
 */

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

#define SYMDIR_local    "(._|_.|__.|___|*/)*"

typedef struct State_s              /* method state               */
{
      Sfio_t*           sp;         /* sfpopen() stream           */
      unsigned long     count;            /* member count               */
} State_t;

/*
 * closef
 */

static int
localclose(Ardir_t* ar)
{
      State_t*    state;
      int         r;

      if (!ar || !(state = (State_t*)ar->data))
            r = -1;
      else
      {
            if (!state->sp || sfclose(state->sp))
                  r = -1;
            else
                  r = 0;
            free(state);
      }
      return r;
}

/*
 * openf
 */

static int
localopen(Ardir_t* ar, char* buf, size_t n)
{
      State_t*    state;
      char*       cmd;
      int         c;

      if (!(ar->flags & ARDIR_LOCAL))
            return -1;
      if (!(state = newof(0, State_t, 1, 0)))
            return -1;
      ar->data = (void*)state;
      cmd = sfprints("${ARDIR:-ar} ${ARDIRFLAGS:-tv} '%s' 2>/dev/null", ar->path);
      if (!(state->sp = sfpopen(NiL, cmd, "r")) || (c = sfgetc(state->sp)) == EOF || sfungetc(state->sp, c) == EOF)
      {
            localclose(ar);
            return -1;
      }
      return 0;
}

/*
 * nextf
 */

static Ardirent_t*
localnext(Ardir_t* ar)
{
      State_t*    state = (State_t*)ar->data;
      register char*    s;
      register char*    t;
      char*       e;
      int         n;

      while (s = sfgetr(state->sp, '\n', 1))
      {
            /*
             * assume ``junk Mmm ... member''
             */

            if (!(t = strrchr(s, ' ')))
                  continue;
            *t++ = 0;
            if (state->count++ || !strmatch(t, SYMDIR_local))
                  while (s = strchr(s, ' '))
                  {
                        if (isupper(*++s) && islower(s[1]) && islower(s[2]) && s[3] == ' ')
                        {
                              ar->dirent.mtime = tmdate(s, &e, NiL);
                              if (!*e)
                              {
                                    if ((n = strlen(t)) > ar->truncate)
                                          ar->truncate = n;
                                    break;
                              }
                        }
                        else
                              ar->dirent.size = strtoul(s, NiL, 10);
                  }
            ar->dirent.name = t;
            ar->dirent.uid = ar->st.st_uid;
            ar->dirent.gid = ar->st.st_gid;
            ar->dirent.mode = ar->st.st_mode;
            ar->dirent.offset = -1;
            return &ar->dirent;
      }
      if (sferror(state->sp))
            ar->error = errno;
      return 0;
}

Ardirmeth_t ar_local =
{
      "local",
      "local ar archive",
      localopen,
      localnext,
      0,
      0,
      0,
      localclose,
      ar_local_next
};

Generated by  Doxygen 1.6.0   Back to index