/* Copyright (C) 1993,1994 by the author(s).
 
 This software is published in the hope that it will be useful, but
 WITHOUT ANY WARRANTY for any part of this software to work correctly
 or as described in the manuals. See the ShapeTools Public License
 for details.

 Permission is granted to use, copy, modify, or distribute any part of
 this software but only under the conditions described in the ShapeTools 
 Public License. A copy of this license is supposed to have been given
 to you along with ShapeTools in a file named LICENSE. Among other
 things, this copyright notice and the Public License must be
 preserved on all copies.
 */
/*
 * AtFS -- Attribute Filesystem
 *
 * afcompar.c -- attribute comparison routines 
 *
 * Author: Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de)
 *
 * $Header: afcompar.c[7.0] Fri Jun 25 14:31:46 1993 andy@cs.tu-berlin.de frozen $
 */

#include "atfs.h"

/*================================================================
 *      af_cmpatime -- compare dates of last access
 *================================================================*/

EXPORT int af_cmpatime (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_atime - VATTR(key2).af_atime);
}

/*================================================================
 *      af_cmpauthor -- compare authors
 *================================================================*/

EXPORT int af_cmpauthor (key1, key2)
     Af_key *key1, *key2;
{
  register int res;

  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  if (!(res = strcmp (NOTNIL(VATTR(key1).af_auname),
		      NOTNIL(VATTR(key2).af_auname))))
    return (strcmp (NOTNIL(VATTR(key1).af_audomain),
		    NOTNIL(VATTR(key2).af_audomain)));
  else
    return (res);
}

/*================================================================
 *      af_cmpctime -- compare dates of last status change
 *================================================================*/

EXPORT int af_cmpctime (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_ctime - VATTR(key2).af_ctime);
}

/*================================================================
 *      af_cmpgen -- compare generation numbers
 *================================================================*/

EXPORT int af_cmpgen (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_gen - VATTR(key2).af_gen);
}

/*================================================================
 *      af_cmphost -- compare hostnames
 *================================================================*/

EXPORT int af_cmphost (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (strcmp (CATTR(key1).af_host, CATTR(key2).af_host));
}

/*================================================================
 *      af_cmpbound -- compare name, type, gen, rev
 *================================================================*/

EXPORT int af_cmpbound (key1, key2)
     Af_key *key1, *key2;
{
  register int diff;

  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  if (!(diff = strcmp (VATTR(key1).af_name, VATTR(key2).af_name)) &&
      !(diff = strcmp (NOTNIL(VATTR(key1).af_type),
		       NOTNIL(VATTR(key2).af_type))) &&
      !(diff = VATTR(key1).af_gen - VATTR(key2).af_gen) &&
      !(diff = VATTR(key1).af_rev - VATTR(key2).af_rev)) {
    return (0);
  }
  return (diff);
}

/*================================================================
 *      af_cmplocker -- compare lockers
 *================================================================*/

EXPORT int af_cmplocker (key1, key2)
     Af_key *key1, *key2;
{
  register int res;

  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  if (!(res = strcmp (NOTNIL(VATTR(key1).af_lckname),
		      NOTNIL(VATTR(key2).af_lckname))))
    return (strcmp (NOTNIL(VATTR(key1).af_lckdomain),
		    NOTNIL(VATTR(key2).af_lckdomain)));
  else
    return (res);
}

/*================================================================
 *      af_cmpltime -- compare dates of last lock change
 *================================================================*/

EXPORT int af_cmpltime (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_ltime - VATTR(key2).af_ltime);
}

/*================================================================
 *      af_cmpmode -- compare protections
 *================================================================*/

EXPORT int af_cmpmode (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_mode - VATTR(key2).af_mode);
}

/*================================================================
 *      af_cmpmtime -- compare dates of last modification
 *================================================================*/

EXPORT int af_cmpmtime (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_mtime - VATTR(key2).af_mtime);
}

/*================================================================
 *      af_cmpname -- compare names
 *================================================================*/

EXPORT int af_cmpname (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (strcmp (VATTR(key1).af_name, VATTR(key2).af_name));
}

/*================================================================
 *      af_cmpowner -- compare owners
 *================================================================*/

EXPORT int af_cmpowner (key1, key2)
     Af_key *key1, *key2;
{
  register int res;

  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  if (!(res = strcmp (CATTR(key1).af_ownname, CATTR(key2).af_ownname)))
    return (strcmp (CATTR(key1).af_owndomain, CATTR(key2).af_owndomain));
  else
    return (res);
}

/*================================================================
 *      af_cmprev -- compare revision numbers
 *================================================================*/

EXPORT int af_cmprev (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_rev - VATTR(key2).af_rev);
}

/*================================================================
 *      af_cmpsize -- compare file size
 *================================================================*/

EXPORT int af_cmpsize (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_fsize - VATTR(key2).af_fsize);
}

/*================================================================
 *      af_cmpstate -- compare states
 *================================================================*/

EXPORT int af_cmpstate (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_state - VATTR(key2).af_state);
}

/*================================================================
 *      af_cmpsvtime -- compare dates of saving
 *================================================================*/

EXPORT int af_cmpsvtime (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (VATTR(key1).af_stime - VATTR(key2).af_stime);
}

/*================================================================
 *      af_cmpspath -- compare syspaths
 *================================================================*/

EXPORT int af_cmpspath (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (strcmp (CATTR(key1).af_syspath, CATTR(key2).af_syspath));
}

/*================================================================
 *      af_cmptype -- compare types
 *================================================================*/

EXPORT int af_cmptype (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  return (strcmp (NOTNIL(VATTR(key1).af_type),
		  NOTNIL(VATTR(key2).af_type)));
}

/*================================================================
 *      af_cmpversion -- compare version numbers (gen.rev)
 *================================================================*/

EXPORT int af_cmpversion (key1, key2)
     Af_key *key1, *key2;
{
  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);
  if (VATTR(key1).af_gen == VATTR(key2).af_gen)
    return (VATTR(key1).af_rev - VATTR(key2).af_rev);
  else
    return (VATTR(key1).af_gen - VATTR(key2).af_gen);
}

/*===============================================================
 *      af_cmpfuncts -- array of comparison functions
 *===============================================================*/

struct cmpfun { int (*func) (); };

EXPORT struct cmpfun af_cmpfuncts[] = { {af_cmpatime},
					  {af_cmpauthor},
					  {af_cmpbound},
					  {af_cmpctime},
					  {af_cmpgen},
					  {af_cmphost},
					  {af_cmplocker},
					  {af_cmpltime},
					  {af_cmpmode},
					  {af_cmpmtime},
					  {af_cmpname},
					  {af_cmpowner},
					  {af_cmprev},
					  {af_cmpsize},
					  {af_cmpstate},
					  {af_cmpsvtime},
					  {af_cmpspath},
					  {af_cmptype},
					  {af_cmpversion},
					};


/*===============================================================
 *      af_attrlist -- list of attribute names
 *                     (in alphabetical order)
 *===============================================================*/

EXPORT char *af_attrlist[] = { AF_ATTATIME,
				 AF_ATTAUTHOR,
				 AF_ATTBOUND,
				 AF_ATTCTIME,
				 AF_ATTGEN,
				 AF_ATTHOST,
				 AF_ATTLOCKER,
				 AF_ATTLTIME,
				 AF_ATTMODE,
				 AF_ATTMTIME,
				 AF_ATTNAME,
				 AF_ATTOWNER,
				 AF_ATTREV,
				 AF_ATTSIZE,
				 AF_ATTSTATE,
				 AF_ATTSTIME,
				 AF_ATTSPATH,
				 AF_ATTTYPE,
				 AF_ATTVERSION,
				};

/*================================================================
 *      af_cmpuda -- compare user defined attributes
 *================================================================*/

EXPORT char af_udaname[AF_UDANAMLEN];

EXPORT int af_cmpuda (key1, key2)
     Af_key *key1, *key2;
{
  register char *uda1, *uda2;
  char          *vallist1, *vallist2;

  afAccessAso (key1, AF_ATTRS);
  afAccessAso (key2, AF_ATTRS);

  uda1 = afLookupUda (key1, af_udaname);
  uda2 = afLookupUda (key2, af_udaname);

  if (uda1 == NULL) {
    if (uda2 == NULL)
      return (0); /* equal */
    else
      return (1); /* key1 is "greater" than key2 */
  }
  else {
    if (uda2 == NULL)
      return (-1); /* key2 is "greater" than key1 */
  }

  /* see if ther are values */
  vallist1 = strchr (uda1, AF_UDANAMDEL);
  vallist2 = strchr (uda2, AF_UDANAMDEL);

  if (vallist1 == NULL) {
    if (vallist2 == NULL)
      return (0); /* equal */
    else
      return (1); /* key1 is "greater" than key2 */
  }
  else {
    if (vallist2 == NULL)
      return (-1); /* key2 is "greater" than key1 */
  }

  /* compare values of user defined attributes */
  /* this is a simple textual comparison up to now */
  return (strcmp (vallist1, vallist2));
}
