diff options
Diffstat (limited to 'contrib/amd/libamu')
| -rw-r--r-- | contrib/amd/libamu/alloca.c | 504 | ||||
| -rw-r--r-- | contrib/amd/libamu/clnt_sperrno.c | 147 | ||||
| -rw-r--r-- | contrib/amd/libamu/util.c | 176 | 
3 files changed, 0 insertions, 827 deletions
diff --git a/contrib/amd/libamu/alloca.c b/contrib/amd/libamu/alloca.c deleted file mode 100644 index 31fb4e0d4e06..000000000000 --- a/contrib/amd/libamu/alloca.c +++ /dev/null @@ -1,504 +0,0 @@ -/* alloca.c -- allocate automatically reclaimed memory -   (Mostly) portable public-domain implementation -- D A Gwyn - -   This implementation of the PWB library alloca function, -   which is used to allocate space off the run-time stack so -   that it is automatically reclaimed upon procedure exit, -   was inspired by discussions with J. Q. Johnson of Cornell. -   J.Otto Tennant <jot@cray.com> contributed the Cray support. - -   There are some preprocessor constants that can -   be defined when compiling for your specific system, for -   improved efficiency; however, the defaults should be okay. - -   The general concept of this implementation is to keep -   track of all alloca-allocated blocks, and reclaim any -   that are found to be deeper in the stack than the current -   invocation.  This heuristic does not reclaim storage as -   soon as it becomes invalid, but it will do so eventually. - -   As a special case, alloca(0) reclaims storage without -   allocating any.  It is a good idea to use alloca(0) in -   your main control loop, etc. to force garbage collection.  */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#ifdef emacs -#include "blockinput.h" -#endif - -/* If compiling with GCC 2, this file's not needed.  */ -#if !defined (__GNUC__) || __GNUC__ < 2 - -/* If someone has defined alloca as a macro, -   there must be some other way alloca is supposed to work.  */ -#ifndef alloca - -#ifdef emacs -#ifdef static -/* actually, only want this if static is defined as "" -   -- this is for usg, in which emacs must undefine static -   in order to make unexec workable -   */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ - -/* If your stack is a linked list of frames, you have to -   provide an "address metric" ADDRESS_FUNCTION macro.  */ - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc (); -#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -#else -#define ADDRESS_FUNCTION(arg) &(arg) -#endif - -#if __STDC__ -typedef void *pointer; -#else -typedef char *pointer; -#endif - -#ifndef NULL -#define	NULL	0 -#endif - -/* Different portions of Emacs need to call different versions of -   malloc.  The Emacs executable needs alloca to call xmalloc, because -   ordinary malloc isn't protected from input signals.  On the other -   hand, the utilities in lib-src need alloca to call malloc; some of -   them are very simple, and don't have an xmalloc routine. - -   Non-Emacs programs expect this to call use xmalloc. - -   Callers below should use malloc.  */ - -#ifndef emacs -#define malloc xmalloc -#endif -extern pointer malloc (); - -/* Define STACK_DIRECTION if you know the direction of stack -   growth for your system; otherwise it will be automatically -   deduced at run-time. - -   STACK_DIRECTION > 0 => grows toward higher addresses -   STACK_DIRECTION < 0 => grows toward lower addresses -   STACK_DIRECTION = 0 => direction of growth unknown  */ - -#ifndef STACK_DIRECTION -#define	STACK_DIRECTION	0	/* Direction unknown.  */ -#endif - -#if STACK_DIRECTION != 0 - -#define	STACK_DIR	STACK_DIRECTION	/* Known at compile-time.  */ - -#else /* STACK_DIRECTION == 0; need run-time code.  */ - -static int stack_dir;		/* 1 or -1 once known.  */ -#define	STACK_DIR	stack_dir - -static void -find_stack_direction () -{ -  static char *addr = NULL;	/* Address of first `dummy', once known.  */ -  auto char dummy;		/* To get stack address.  */ - -  if (addr == NULL) -    {				/* Initial entry.  */ -      addr = ADDRESS_FUNCTION (dummy); - -      find_stack_direction ();	/* Recurse once.  */ -    } -  else -    { -      /* Second entry.  */ -      if (ADDRESS_FUNCTION (dummy) > addr) -	stack_dir = 1;		/* Stack grew upward.  */ -      else -	stack_dir = -1;		/* Stack grew downward.  */ -    } -} - -#endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: -   (a) chain together all alloca'ed blocks; -   (b) keep track of stack depth. - -   It is very important that sizeof(header) agree with malloc -   alignment chunk size.  The following default should work okay.  */ - -#ifndef	ALIGN_SIZE -#define	ALIGN_SIZE	sizeof(double) -#endif - -typedef union hdr -{ -  char align[ALIGN_SIZE];	/* To force sizeof(header).  */ -  struct -    { -      union hdr *next;		/* For chaining headers.  */ -      char *deep;		/* For stack depth measure.  */ -    } h; -} header; - -static header *last_alloca_header = NULL;	/* -> last alloca header.  */ - -/* Return a pointer to at least SIZE bytes of storage, -   which will be automatically reclaimed upon exit from -   the procedure that called alloca.  Originally, this space -   was supposed to be taken from the current stack frame of the -   caller, but that method cannot be made to work for some -   implementations of C, for example under Gould's UTX/32.  */ - -pointer -alloca (size) -     unsigned size; -{ -  auto char probe;		/* Probes stack depth: */ -  register char *depth = ADDRESS_FUNCTION (probe); - -#if STACK_DIRECTION == 0 -  if (STACK_DIR == 0)		/* Unknown growth direction.  */ -    find_stack_direction (); -#endif - -  /* Reclaim garbage, defined as all alloca'd storage that -     was allocated from deeper in the stack than currently. */ - -  { -    register header *hp;	/* Traverses linked list.  */ - -#ifdef emacs -    BLOCK_INPUT; -#endif - -    for (hp = last_alloca_header; hp != NULL;) -      if ((STACK_DIR > 0 && hp->h.deep > depth) -	  || (STACK_DIR < 0 && hp->h.deep < depth)) -	{ -	  register header *np = hp->h.next; - -	  free ((pointer) hp);	/* Collect garbage.  */ - -	  hp = np;		/* -> next header.  */ -	} -      else -	break;			/* Rest are not deeper.  */ - -    last_alloca_header = hp;	/* -> last valid storage.  */ - -#ifdef emacs -    UNBLOCK_INPUT; -#endif -  } - -  if (size == 0) -    return NULL;		/* No allocation required.  */ - -  /* Allocate combined header + user data storage.  */ - -  { -    register pointer new = malloc (sizeof (header) + size); -    /* Address of header.  */ - -    if (new == 0) -      abort(); - -    ((header *) new)->h.next = last_alloca_header; -    ((header *) new)->h.deep = depth; - -    last_alloca_header = (header *) new; - -    /* User storage begins just after header.  */ - -    return (pointer) ((char *) new + sizeof (header)); -  } -} - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) - -#ifdef DEBUG_I00AFUNC -#include <stdio.h> -#endif - -#ifndef CRAY_STACK -#define CRAY_STACK -#ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header -  { -    long shgrow:32;		/* Number of times stack has grown.  */ -    long shaseg:32;		/* Size of increments to stack.  */ -    long shhwm:32;		/* High water mark of stack.  */ -    long shsize:32;		/* Current size of stack (all segments).  */ -  }; - -/* The stack segment linkage control information occurs at -   the high-address end of a stack segment.  (The stack -   grows from low addresses to high addresses.)  The initial -   part of the stack segment linkage control information is -   0200 (octal) words.  This provides for register storage -   for the routine which overflows the stack.  */ - -struct stack_segment_linkage -  { -    long ss[0200];		/* 0200 overflow words.  */ -    long sssize:32;		/* Number of words in this segment.  */ -    long ssbase:32;		/* Offset to stack base.  */ -    long:32; -    long sspseg:32;		/* Offset to linkage control of previous -				   segment of stack.  */ -    long:32; -    long sstcpt:32;		/* Pointer to task common address block.  */ -    long sscsnm;		/* Private control structure number for -				   microtasking.  */ -    long ssusr1;		/* Reserved for user.  */ -    long ssusr2;		/* Reserved for user.  */ -    long sstpid;		/* Process ID for pid based multi-tasking.  */ -    long ssgvup;		/* Pointer to multitasking thread giveup.  */ -    long sscray[7];		/* Reserved for Cray Research.  */ -    long ssa0; -    long ssa1; -    long ssa2; -    long ssa3; -    long ssa4; -    long ssa5; -    long ssa6; -    long ssa7; -    long sss0; -    long sss1; -    long sss2; -    long sss3; -    long sss4; -    long sss5; -    long sss6; -    long sss7; -  }; - -#else /* CRAY2 */ -/* The following structure defines the vector of words -   returned by the STKSTAT library routine.  */ -struct stk_stat -  { -    long now;			/* Current total stack size.  */ -    long maxc;			/* Amount of contiguous space which would -				   be required to satisfy the maximum -				   stack demand to date.  */ -    long high_water;		/* Stack high-water mark.  */ -    long overflows;		/* Number of stack overflow ($STKOFEN) calls.  */ -    long hits;			/* Number of internal buffer hits.  */ -    long extends;		/* Number of block extensions.  */ -    long stko_mallocs;		/* Block allocations by $STKOFEN.  */ -    long underflows;		/* Number of stack underflow calls ($STKRETN).  */ -    long stko_free;		/* Number of deallocations by $STKRETN.  */ -    long stkm_free;		/* Number of deallocations by $STKMRET.  */ -    long segments;		/* Current number of stack segments.  */ -    long maxs;			/* Maximum number of stack segments so far.  */ -    long pad_size;		/* Stack pad size.  */ -    long current_address;	/* Current stack segment address.  */ -    long current_size;		/* Current stack segment size.  This -				   number is actually corrupted by STKSTAT to -				   include the fifteen word trailer area.  */ -    long initial_address;	/* Address of initial segment.  */ -    long initial_size;		/* Size of initial segment.  */ -  }; - -/* The following structure describes the data structure which trails -   any stack segment.  I think that the description in 'asdef' is -   out of date.  I only describe the parts that I am sure about.  */ - -struct stk_trailer -  { -    long this_address;		/* Address of this block.  */ -    long this_size;		/* Size of this block (does not include -				   this trailer).  */ -    long unknown2; -    long unknown3; -    long link;			/* Address of trailer block of previous -				   segment.  */ -    long unknown5; -    long unknown6; -    long unknown7; -    long unknown8; -    long unknown9; -    long unknown10; -    long unknown11; -    long unknown12; -    long unknown13; -    long unknown14; -  }; - -#endif /* CRAY2 */ -#endif /* not CRAY_STACK */ - -#ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. -   I doubt that "lint" will like this much. */ - -static long -i00afunc (long *address) -{ -  struct stk_stat status; -  struct stk_trailer *trailer; -  long *block, size; -  long result = 0; - -  /* We want to iterate through all of the segments.  The first -     step is to get the stack status structure.  We could do this -     more quickly and more directly, perhaps, by referencing the -     $LM00 common block, but I know that this works.  */ - -  STKSTAT (&status); - -  /* Set up the iteration.  */ - -  trailer = (struct stk_trailer *) (status.current_address -				    + status.current_size -				    - 15); - -  /* There must be at least one stack segment.  Therefore it is -     a fatal error if "trailer" is null.  */ - -  if (trailer == 0) -    abort (); - -  /* Discard segments that do not contain our argument address.  */ - -  while (trailer != 0) -    { -      block = (long *) trailer->this_address; -      size = trailer->this_size; -      if (block == 0 || size == 0) -	abort (); -      trailer = (struct stk_trailer *) trailer->link; -      if ((block <= address) && (address < (block + size))) -	break; -    } - -  /* Set the result to the offset in this segment and add the sizes -     of all predecessor segments.  */ - -  result = address - block; - -  if (trailer == 0) -    { -      return result; -    } - -  do -    { -      if (trailer->this_size <= 0) -	abort (); -      result += trailer->this_size; -      trailer = (struct stk_trailer *) trailer->link; -    } -  while (trailer != 0); - -  /* We are done.  Note that if you present a bogus address (one -     not in any segment), you will get a different number back, formed -     from subtracting the address of the first block.  This is probably -     not what you want.  */ - -  return (result); -} - -#else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. -   Determine the number of the cell within the stack, -   given the address of the cell.  The purpose of this -   routine is to linearize, in some sense, stack addresses -   for alloca.  */ - -static long -i00afunc (long address) -{ -  long stkl = 0; - -  long size, pseg, this_segment, stack; -  long result = 0; - -  struct stack_segment_linkage *ssptr; - -  /* Register B67 contains the address of the end of the -     current stack segment.  If you (as a subprogram) store -     your registers on the stack and find that you are past -     the contents of B67, you have overflowed the segment. - -     B67 also points to the stack segment linkage control -     area, which is what we are really interested in.  */ - -  stkl = CRAY_STACKSEG_END (); -  ssptr = (struct stack_segment_linkage *) stkl; - -  /* If one subtracts 'size' from the end of the segment, -     one has the address of the first word of the segment. - -     If this is not the first segment, 'pseg' will be -     nonzero.  */ - -  pseg = ssptr->sspseg; -  size = ssptr->sssize; - -  this_segment = stkl - size; - -  /* It is possible that calling this routine itself caused -     a stack overflow.  Discard stack segments which do not -     contain the target address.  */ - -  while (!(this_segment <= address && address <= stkl)) -    { -#ifdef DEBUG_I00AFUNC -      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); -#endif -      if (pseg == 0) -	break; -      stkl = stkl - pseg; -      ssptr = (struct stack_segment_linkage *) stkl; -      size = ssptr->sssize; -      pseg = ssptr->sspseg; -      this_segment = stkl - size; -    } - -  result = address - this_segment; - -  /* If you subtract pseg from the current end of the stack, -     you get the address of the previous stack segment's end. -     This seems a little convoluted to me, but I'll bet you save -     a cycle somewhere.  */ - -  while (pseg != 0) -    { -#ifdef DEBUG_I00AFUNC -      fprintf (stderr, "%011o %011o\n", pseg, size); -#endif -      stkl = stkl - pseg; -      ssptr = (struct stack_segment_linkage *) stkl; -      size = ssptr->sssize; -      pseg = ssptr->sspseg; -      result += size; -    } -  return (result); -} - -#endif /* not CRAY2 */ -#endif /* CRAY */ - -#endif /* no alloca */ -#endif /* not GCC version 2 */ diff --git a/contrib/amd/libamu/clnt_sperrno.c b/contrib/amd/libamu/clnt_sperrno.c deleted file mode 100644 index d3b48d1cd405..000000000000 --- a/contrib/amd/libamu/clnt_sperrno.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 1997-1998 Erez Zadok - * Copyright (c) 1990 Jan-Simon Pendry - * Copyright (c) 1990 Imperial College of Science, Technology & Medicine - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry at Imperial College, London. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - *    must display the following acknowledgement: - *      This product includes software developed by the University of - *      California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *      %W% (Berkeley) %G% - * - * $Id: clnt_sperrno.c,v 5.2.2.1 1992/02/09 15:08:40 jsp beta $ - * - */ - -/* - * Early RPC seems to be missing these.. - * Extracted from the RPC 3.9 sources as indicated - */ - -/* @(#)clnt_perror.c    1.1 87/11/04 3.9 RPCSRC */ -/* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part.  Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California  94043 - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif /* HAVE_CONFIG_H */ -#include <am_defs.h> -#include <amu.h> - - -struct rpc_errtab { -  enum clnt_stat status; -  char *message; -}; - -static struct rpc_errtab rpc_errlist[] = -{ -  {RPC_SUCCESS, -   "RPC: Success"}, -  {RPC_CANTENCODEARGS, -   "RPC: Can't encode arguments"}, -  {RPC_CANTDECODERES, -   "RPC: Can't decode result"}, -  {RPC_CANTSEND, -   "RPC: Unable to send"}, -  {RPC_CANTRECV, -   "RPC: Unable to receive"}, -  {RPC_TIMEDOUT, -   "RPC: Timed out"}, -  {RPC_VERSMISMATCH, -   "RPC: Incompatible versions of RPC"}, -  {RPC_AUTHERROR, -   "RPC: Authentication error"}, -  {RPC_PROGUNAVAIL, -   "RPC: Program unavailable"}, -  {RPC_PROGVERSMISMATCH, -   "RPC: Program/version mismatch"}, -  {RPC_PROCUNAVAIL, -   "RPC: Procedure unavailable"}, -  {RPC_CANTDECODEARGS, -   "RPC: Server can't decode arguments"}, -  {RPC_SYSTEMERROR, -   "RPC: Remote system error"}, -  {RPC_UNKNOWNHOST, -   "RPC: Unknown host"}, -/*      { RPC_UNKNOWNPROTO, - * "RPC: Unknown protocol" }, */ -  {RPC_PMAPFAILURE, -   "RPC: Port mapper failure"}, -  {RPC_PROGNOTREGISTERED, -   "RPC: Program not registered"}, -  {RPC_FAILED, -   "RPC: Failed (unspecified error)"} -}; - - -/* - * This interface for use by clntrpc - */ -char * -clnt_sperrno(enum clnt_stat stat) -{ -  int i; - -  for (i = 0; i < sizeof(rpc_errlist) / sizeof(struct rpc_errtab); i++) { -    if (rpc_errlist[i].status == stat) { -      return (rpc_errlist[i].message); -    } -  } -  return ("RPC: (unknown error code)"); -} diff --git a/contrib/amd/libamu/util.c b/contrib/amd/libamu/util.c deleted file mode 100644 index ad16b15eb9df..000000000000 --- a/contrib/amd/libamu/util.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 1997-2004 Erez Zadok - * Copyright (c) 1990 Jan-Simon Pendry - * Copyright (c) 1990 Imperial College of Science, Technology & Medicine - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry at Imperial College, London. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - *    must display the following acknowledgment: - *      This product includes software developed by the University of - *      California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - *      %W% (Berkeley) %G% - * - * $Id: util.c,v 1.3.2.4 2004/01/06 03:15:24 ezk Exp $ - * - */ - -/* - * General Utilities. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif /* HAVE_CONFIG_H */ -#include <am_defs.h> -#include <amu.h> - - -char * -strnsave(const char *str, int len) -{ -  char *sp = (char *) xmalloc(len + 1); -  memmove(sp, str, len); -  sp[len] = 0; - -  return sp; -} - - -/* - * Concatenate three strings and store in buffer pointed to - * by p, making p large enough to hold the strings - */ -char * -str3cat(char *p, char *s1, char *s2, char *s3) -{ -  int l1 = strlen(s1); -  int l2 = strlen(s2); -  int l3 = strlen(s3); - -  p = (char *) xrealloc(p, l1 + l2 + l3 + 1); -  memmove(p, s1, l1); -  memmove(p + l1, s2, l2); -  memmove(p + l1 + l2, s3, l3 + 1); -  return p; -} - - -/* - * Make all the directories in the path. - */ -int -mkdirs(char *path, int mode) -{ -  /* -   * take a copy in case path is in readonly store -   */ -  char *p2 = strdup(path); -  char *sp = p2; -  struct stat stb; -  int error_so_far = 0; - -  /* -   * Skip through the string make the directories. -   * Mostly ignore errors - the result is tested at the end. -   * -   * This assumes we are root so that we can do mkdir in a -   * mode 555 directory... -   */ -  while ((sp = strchr(sp + 1, '/'))) { -    *sp = '\0'; -    if (mkdir(p2, mode) < 0) { -      error_so_far = errno; -    } else { -#ifdef DEBUG -      dlog("mkdir(%s)", p2); -#endif /* DEBUG */ -    } -    *sp = '/'; -  } - -  if (mkdir(p2, mode) < 0) { -    error_so_far = errno; -  } else { -#ifdef DEBUG -    dlog("mkdir(%s)", p2); -#endif /* DEBUG */ -  } - -  XFREE(p2); - -  return stat(path, &stb) == 0 && -    (stb.st_mode & S_IFMT) == S_IFDIR ? 0 : error_so_far; -} - - -/* - * Remove as many directories in the path as possible. - * Give up if the directory doesn't appear to have - * been created by Amd (not mode dr-x) or an rmdir - * fails for any reason. - */ -void -rmdirs(char *dir) -{ -  char *xdp = strdup(dir); -  char *dp; - -  do { -    struct stat stb; -    /* -     * Try to find out whether this was -     * created by amd.  Do this by checking -     * for owner write permission. -     */ -    if (stat(xdp, &stb) == 0 && (stb.st_mode & 0200) == 0) { -      if (rmdir(xdp) < 0) { -	if (errno != ENOTEMPTY && -	    errno != EBUSY && -	    errno != EEXIST && -	    errno != EINVAL) -	  plog(XLOG_ERROR, "rmdir(%s): %m", xdp); -	break; -      } else { -#ifdef DEBUG -	dlog("rmdir(%s)", xdp); -#endif /* DEBUG */ -      } -    } else { -      break; -    } - -    dp = strrchr(xdp, '/'); -    if (dp) -      *dp = '\0'; -  } while (dp && dp > xdp); - -  XFREE(xdp); -}  | 
