/* $VER: ar contents.c V0.1 (31.01.98)
 *
 * This file is part of ar, a portable archive maintanance
 * utility for normal and BSD-style archives.
 * Copyright (c) 1999  Frank Wille
 *
 * ar is freeware and part of the portable and retargetable ANSI C
 * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
 * ar may be freely redistributed as long as no modifications are
 * made and nothing is charged for it. Non-commercial usage is allowed
 * without any restrictions.
 * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
 * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
 *
 *
 * v0.1  (31.01.99) phx
 *       First working version, which only supports 'q' (quick append)
 *       and 't' (table of contents), reads and writes normals and
 *       BSD-style archives. Symbol table will not be created!
 * v0.0  (29.01.99) phx
 *       File created.
 */

#include <stdio.h>
#include <string.h>
#include "ar.h"
#include "archive.h"
#include "errors.h"


static bool print_contents(struct Args *,struct Archive *,char *);



void ar_contents(struct Args *args)
{
  struct Archive *ar;
  uint32 i;

  if (ar = ar_read(args->arname)) {
    if (args->filecnt) {
      for (i=0; i<args->filecnt; i++)
        if (!print_contents(args,ar,args->files[i]))
          error(ENOTFOUND,args->files[i]);
    }
    else
      print_contents(args,ar,NULL);
  }
}


#ifdef AMIGA
static char *genmode(char *s,uint16 mode)
{
  if (mode & 4)
    *s++ = 'r';
  else
    *s++ = '-';
  if (mode & 2)
    *s++ = 'w';
  else
    *s++ = '-';
  if (mode & 1)
    *s++ = 'x';
  else
    *s++ = '-';
  return (s);
}

static void modestr(char *s,uint16 mode)
/* create a unix-style permission string */
/* @@@ very simple implementation... */
{
  s = genmode(s,(mode>>6)&7);
  s = genmode(s,(mode>>3)&7);
  s = genmode(s,mode&7);
  *s = '\0';
}
#endif


static bool print_contents(struct Args *args,struct Archive *ar,char *name)
{
  struct ArObject *obj = (struct ArObject *)ar->l.first;
  struct ArObject *next;
  bool found = FALSE;

  while (next = (struct ArObject *)obj->n.next) {
    if (name)
      if (strcmp(obj->name,name))
        goto nextobj;
    found = TRUE;

    if (args->modifier & AR_VERBOSE) {
      struct tm *tp;
      char buf[32];

#ifdef AMIGA
      modestr(buf,obj->mode);
#else
      strmode((mode_t)obj->mode,buf);
#endif
      printf("%s %6u/%-6u %8lu ",buf,(unsigned)obj->uid,
             (unsigned)obj->gid,obj->size);
      tp = localtime(&obj->time);
      strftime(buf,sizeof(buf),"%b %e %H:%M %Y",tp);
      printf("%s %s\n",buf,obj->name);
    }
    else
      printf("%s\n",obj->name);
nextobj:
    obj = next;
  }
  return (found);
}
