1d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
2d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
3d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * All rights reserved.
4d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
5d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Redistribution and use in source and binary forms, with or without
6d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * modification, are permitted provided that the following conditions
7d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * are met:
8d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 1. Redistributions of source code must retain the above copyright
9d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer.
10d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 2. Redistributions in binary form must reproduce the above copyright
11d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer in the
12d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    documentation and/or other materials provided with the distribution.
13d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 3. The name of the author may not be used to endorse or promote products
14d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    derived from this software without specific prior written permission.
15d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
16d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
19d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
27d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * $Id: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
28d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
29d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
30d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * All rights reserved.
31d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
32d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * This code is derived from software contributed to The NetBSD Foundation
33d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * by Klaus Klein and Jason R. Thorpe.
34d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
35d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Redistribution and use in source and binary forms, with or without
36d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * modification, are permitted provided that the following conditions
37d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * are met:
38d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 1. Redistributions of source code must retain the above copyright
39d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer.
40d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 2. Redistributions in binary form must reproduce the above copyright
41d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer in the
42d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    documentation and/or other materials provided with the distribution.
43d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 3. All advertising materials mentioning features or use of this software
44d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    must display the following acknowledgement:
45d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *        This product includes software developed by the NetBSD
46d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *        Foundation, Inc. and its contributors.
47d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 4. Neither the name of The NetBSD Foundation nor the names of its
48d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    contributors may be used to endorse or promote products derived
49d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    from this software without specific prior written permission.
50d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
51d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
52d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
54d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
55d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * POSSIBILITY OF SUCH DAMAGE.
62d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
63d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *  $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
64d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
65d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright (c) 1987, 1993
66d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *  The Regents of the University of California.  All rights reserved.
67d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
68d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Redistribution and use in source and binary forms, with or without
69d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * modification, are permitted provided that the following conditions
70d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * are met:
71d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 1. Redistributions of source code must retain the above copyright
72d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer.
73d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 2. Redistributions in binary form must reproduce the above copyright
74d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer in the
75d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    documentation and/or other materials provided with the distribution.
76d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 3. Neither the name of the University nor the names of its contributors
77d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    may be used to endorse or promote products derived from this software
78d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    without specific prior written permission.
79d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
80d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
81d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
83d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
84d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
87d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
88d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
89d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SUCH DAMAGE.
91d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
92d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *  $NetBSD: compat.c,v 1.1.1.1 2008/08/24 05:33:08 gmcgarry Exp $
93d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
94d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include  <LibConfig.h>
95d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include  <string.h>
96d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include  <fcntl.h>
9741b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm#include  <sys/syslimits.h>
98d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
99d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifndef HAVE_GETOPT
100d7ce700605e1af0e455e31ec11f19ff21d26b525darylmchar *optarg;
101d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint optind = 1;
102d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
103d7ce700605e1af0e455e31ec11f19ff21d26b525darylmgetopt(int argc, char **argv, char *args)
104d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
105d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        size_t n;
106d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  size_t nlen = strlen(args);
107d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        char cmd;
108d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        char rv;
109d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
110d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (argv[optind] && *argv[optind] == '-') {
111d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                cmd = *(argv[optind] + 1);
112d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
113d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                for (n = 0; n < nlen; n++) {
114d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        if (args[n] == ':')
115d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        continue;
116d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        if (args[n] == cmd) {
117d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                rv = *(argv[optind] + 1);
118d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                if (args[n+1] == ':') {
119d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          if (*(argv[optind] + 2) != '\0') {
120d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          optarg = argv[optind] + 2;
121d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            optind += 1;
122d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          } else {
123d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          optarg = argv[optind + 1];
124d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          optind += 2;
125d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          }
126d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                        if (!optarg)
127d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             optarg="";
128d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                        return rv;
129d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                } else {
130d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                        optarg = NULL;
131d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                        optind += 1;
132d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                        return rv;
133d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                }
134d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        }
135d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                }
136d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
137d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return -1;
138d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
139d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
140d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
141d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define ISPATHSEPARATOR(x) ((x == '/') || (x == '\\'))
142d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
1435c5e4a12de6b568c1f460b71b6d2399069bf12f1darylm#ifdef HAVE_BASENAME
144d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifndef PATH_MAX
1455c5e4a12de6b568c1f460b71b6d2399069bf12f1darylm  #define PATH_MAX 5000
146d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
147d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
148d7ce700605e1af0e455e31ec11f19ff21d26b525darylmchar *
149d7ce700605e1af0e455e31ec11f19ff21d26b525darylmbasename(char *path)
150d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
151d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  static char singledot[] = ".";
152d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  static char result[PATH_MAX];
153d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  char *p, *lastp;
154d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  size_t len;
155d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
156d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /*
157d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * If `path' is a null pointer or points to an empty string,
158d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * return a pointer to the string ".".
159d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   */
160d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if ((path == NULL) || (*path == '\0'))
161d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    return (singledot);
162d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
163d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Strip trailing slashes, if any. */
164d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  lastp = path + strlen(path) - 1;
165d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (lastp != path && ISPATHSEPARATOR(*lastp))
166d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    lastp--;
167d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
168d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Now find the beginning of this (final) component. */
169d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  p = lastp;
170d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (p != path && !ISPATHSEPARATOR(*(p - 1)))
171d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    p--;
172d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
173d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* ...and copy the result into the result buffer. */
174d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  len = (lastp - p) + 1 /* last char */;
175d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (len > (PATH_MAX - 1))
176d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    len = PATH_MAX - 1;
177d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
178d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  memcpy(result, p, len);
179d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  result[len] = '\0';
180d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
181d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return (result);
182d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
183d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
184d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
185d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#if !defined(HAVE_MKSTEMP) && !defined(WIN32)
186d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
187d7ce700605e1af0e455e31ec11f19ff21d26b525darylmmkstemp(char *path)
188d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
189d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  char *start, *trv;
190d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  unsigned int pid;
191d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
192d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* To guarantee multiple calls generate unique names even if
193d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     the file is not created. 676 different possibilities with 7
194d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     or more X's, 26 with 6 or less. */
195d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  static char xtra[2] = "aa";
196d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int xcnt = 0;
197d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
198d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  pid = getpid();
199d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
200d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Move to end of path and count trailing X's. */
201d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  for (trv = path; *trv; ++trv)
202d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (*trv == 'X')
203d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      xcnt++;
204d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    else
205d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      xcnt = 0;
206d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
207d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Use at least one from xtra.  Use 2 if more than 6 X's. */
208d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (*(trv - 1) == 'X')
209d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    *--trv = xtra[0];
210d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (xcnt > 6 && *(trv - 1) == 'X')
211d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    *--trv = xtra[1];
212d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
213d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Set remaining X's to pid digits with 0's to the left. */
214d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (*--trv == 'X') {
215d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    *trv = (pid % 10) + '0';
216d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pid /= 10;
217d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
218d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
219d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* update xtra for next call. */
220d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (xtra[0] != 'z')
221d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    xtra[0]++;
222d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else {
223d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    xtra[0] = 'a';
224d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (xtra[1] != 'z')
225d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      xtra[1]++;
226d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    else
227d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      xtra[1] = 'a';
228d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
229d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
230d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return open(path, O_CREAT | O_EXCL | O_RDWR, 0600);
231d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
232d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
233d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
2345c5e4a12de6b568c1f460b71b6d2399069bf12f1darylm#ifdef HAVE_FFS
235d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
236d7ce700605e1af0e455e31ec11f19ff21d26b525darylmffs(int x)
237d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
238d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int r = 1;
239d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!x) return 0;
240d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(x & 0xffff)) { x >>= 16; r += 16; }
241d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(x &   0xff)) { x >>= 8;  r += 8;  }
242d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(x &    0xf)) { x >>= 4;  r += 4;  }
243d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(x &      3)) { x >>= 2;  r += 2;  }
244d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(x &      1)) { x >>= 1;  r += 1;  }
245d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
246d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return r;
247d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
248d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
249d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
250d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
251d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright Patrick Powell 1995
252d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * This code is based on code written by Patrick Powell (papowell@astart.com)
253d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * It may be used for any purpose as long as this notice remains intact
254d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * on all source code distributions
255d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
256d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
257d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
258d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
259d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
260d7ce700605e1af0e455e31ec11f19ff21d26b525darylmdopr(char *buffer, size_t maxlen, const char *format, va_list args);
261d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
262d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
263d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
264d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int min, int max);
265d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
266d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
267d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
268d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int min, int max, int flags);
269d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
270d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
271d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,
272d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int min, int max, int flags);
273d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
274d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
275d7ce700605e1af0e455e31ec11f19ff21d26b525darylmdopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
276d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
277d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
278d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * dopr(): poor man's version of doprintf
279d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
280d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
281d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* format read states */
282d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_DEFAULT 0
283d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_FLAGS   1
284d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_MIN     2
285d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_DOT     3
286d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_MAX     4
287d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_MOD     5
288d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_CONV    6
289d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_S_DONE    7
290d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
291d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* format flags - Bits */
292d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_MINUS  (1 << 0)
293d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_PLUS   (1 << 1)
294d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_SPACE  (1 << 2)
295d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_NUM    (1 << 3)
296d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_ZERO   (1 << 4)
297d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_UP     (1 << 5)
298d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_F_UNSIGNED   (1 << 6)
299d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
300d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Conversion Flags */
301d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_C_SHORT     1
302d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_C_LONG      2
303d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_C_LDOUBLE   3
304d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define DP_C_LONG_LONG 4
305d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
306d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define char_to_int(p) (p - '0')
307d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define abs_val(p) (p < 0 ? -p : p)
308d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
309d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
310d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
311d7ce700605e1af0e455e31ec11f19ff21d26b525darylmdopr(char *buffer, size_t maxlen, const char *format, va_list args)
312d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
313d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  char *strvalue, ch;
314d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long value;
315d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long double fvalue;
316d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0;
317d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  size_t currlen = 0;
318d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
319d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  ch = *format++;
320d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
321d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (state != DP_S_DONE) {
322d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if ((ch == '\0') || (currlen >= maxlen))
323d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      state = DP_S_DONE;
324d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
325d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    switch(state) {
326d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_DEFAULT:
327d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (ch == '%')
328d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_FLAGS;
329d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      else
330d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        dopr_outch(buffer, &currlen, maxlen, ch);
331d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      ch = *format++;
332d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
333d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_FLAGS:
334d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      switch (ch) {
335d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case '-':
336d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_MINUS;
337d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
338d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
339d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case '+':
340d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_PLUS;
341d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
342d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
343d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case ' ':
344d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_SPACE;
345d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
346d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
347d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case '#':
348d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_NUM;
349d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
350d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
351d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case '0':
352d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_ZERO;
353d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
354d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
355d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      default:
356d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_MIN;
357d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
358d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      }
359d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
360d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_MIN:
361d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (isdigit((unsigned char)ch)) {
362d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        min = 10 * min + char_to_int (ch);
363d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
364d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      } else if (ch == '*') {
365d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        min = va_arg (args, int);
366d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
367d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_DOT;
368d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      } else
369d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_DOT;
370d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
371d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_DOT:
372d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (ch == '.') {
373d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_MAX;
374d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
375d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      } else
376d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_MOD;
377d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
378d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_MAX:
379d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      if (isdigit((unsigned char)ch)) {
380d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (max < 0)
381d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          max = 0;
382d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        max = 10 * max + char_to_int(ch);
383d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
384d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      } else if (ch == '*') {
385d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        max = va_arg (args, int);
386d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
387d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_MOD;
388d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      } else
389d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        state = DP_S_MOD;
390d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
391d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_MOD:
392d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      switch (ch) {
393d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'h':
394d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        cflags = DP_C_SHORT;
395d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
396d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
397d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'l':
398d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        cflags = DP_C_LONG;
399d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
400d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (ch == 'l') {
401d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          cflags = DP_C_LONG_LONG;
402d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          ch = *format++;
403d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
404d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
405d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'q':
406d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        cflags = DP_C_LONG_LONG;
407d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
408d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
409d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'L':
410d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        cflags = DP_C_LDOUBLE;
411d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
412d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
413d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      default:
414d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
415d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      }
416d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      state = DP_S_CONV;
417d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
418d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_CONV:
419d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      switch (ch) {
420d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'd':
421d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'i':
422d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_SHORT)
423d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, int);
424d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG)
425d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, long int);
426d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG_LONG)
427d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg (args, long long);
428d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
429d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg (args, int);
430d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
431d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
432d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'o':
433d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UNSIGNED;
434d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_SHORT)
435d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
436d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG)
437d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long int);
438d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG_LONG)
439d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long long);
440d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
441d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
442d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
443d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
444d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'u':
445d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UNSIGNED;
446d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_SHORT)
447d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
448d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG)
449d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long int);
450d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG_LONG)
451d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long long);
452d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
453d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
454d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
455d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
456d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'X':
457d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UP;
458d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'x':
459d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UNSIGNED;
460d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_SHORT)
461d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
462d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG)
463d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long int);
464d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else if (cflags == DP_C_LONG_LONG)
465d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned long long);
466d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
467d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          value = va_arg(args, unsigned int);
468d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
469d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
470d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'f':
471d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_LDOUBLE)
472d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, long double);
473d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
474d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, double);
475d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        /* um, floating point? */
476d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
477d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
478d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'E':
479d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UP;
480d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'e':
481d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_LDOUBLE)
482d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, long double);
483d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
484d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, double);
485d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
486d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'G':
487d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        flags |= DP_F_UP;
488d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'g':
489d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_LDOUBLE)
490d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, long double);
491d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        else
492d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          fvalue = va_arg(args, double);
493d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
494d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'c':
495d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
496d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
497d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 's':
498d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        strvalue = va_arg(args, char *);
499d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (max < 0)
500d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          max = maxlen; /* ie, no max */
501d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
502d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
503d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'p':
504d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        strvalue = va_arg(args, void *);
505d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
506d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
507d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'n':
508d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (cflags == DP_C_SHORT) {
509d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          short int *num;
510d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          num = va_arg(args, short int *);
511d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          *num = currlen;
512d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        } else if (cflags == DP_C_LONG) {
513d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          long int *num;
514d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          num = va_arg(args, long int *);
515d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          *num = currlen;
516d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        } else if (cflags == DP_C_LONG_LONG) {
517d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          long long *num;
518d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          num = va_arg(args, long long *);
519d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          *num = currlen;
520d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        } else {
521d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          int *num;
522d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          num = va_arg(args, int *);
523d7ce700605e1af0e455e31ec11f19ff21d26b525darylm          *num = currlen;
524d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
525d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
526d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case '%':
527d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        dopr_outch(buffer, &currlen, maxlen, ch);
528d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
529d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      case 'w': /* not supported yet, treat as next char */
530d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ch = *format++;
531d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        break;
532d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      default: /* Unknown, skip */
533d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
534d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      }
535d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      ch = *format++;
536d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      state = DP_S_DEFAULT;
537d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      flags = cflags = min = 0;
538d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      max = -1;
539d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
540d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    case DP_S_DONE:
541d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break;
542d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    default: /* hmm? */
543d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      break; /* some picky compilers need this */
544d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
545d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
546d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (currlen < maxlen - 1)
547d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    buffer[currlen] = '\0';
548d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else
549d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    buffer[maxlen - 1] = '\0';
550d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
551d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
552d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
553d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtstr(char *buffer, size_t *currlen, size_t maxlen,
554d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    char *value, int flags, int min, int max)
555d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
556d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int cnt = 0, padlen, strln;     /* amount to pad */
557d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
558d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (value == 0)
559d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    value = "<NULL>";
560d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
561d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  for (strln = 0; value[strln]; ++strln); /* strlen */
562d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  padlen = min - strln;
563d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (padlen < 0)
564d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    padlen = 0;
565d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (flags & DP_F_MINUS)
566d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    padlen = -padlen; /* Left Justify */
567d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
568d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while ((padlen > 0) && (cnt < max)) {
569d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, ' ');
570d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    --padlen;
571d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++cnt;
572d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
573d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (*value && (cnt < max)) {
574d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, *value++);
575d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++cnt;
576d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
577d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while ((padlen < 0) && (cnt < max)) {
578d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, ' ');
579d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++padlen;
580d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++cnt;
581d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
582d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
583d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
584d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
585d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
586d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
587d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtint(char *buffer, size_t *currlen, size_t maxlen,
588d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    long value, int base, int min, int max, int flags)
589d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
590d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  unsigned long uvalue;
591d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  char convert[20];
592d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int signvalue = 0, place = 0, caps = 0;
593d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int spadlen = 0; /* amount to space pad */
594d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int zpadlen = 0; /* amount to zero pad */
595d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
596d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define PADMAX(x,y) ((x) > (y) ? (x) : (y))
597d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
598d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (max < 0)
599d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    max = 0;
600d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
601d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  uvalue = value;
602d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
603d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (!(flags & DP_F_UNSIGNED)) {
604d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (value < 0) {
605d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      signvalue = '-';
606d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      uvalue = -value;
607d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    } else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
608d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      signvalue = '+';
609d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    else if (flags & DP_F_SPACE)
610d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      signvalue = ' ';
611d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
612d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
613d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (flags & DP_F_UP)
614d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    caps = 1; /* Should characters be upper case? */
615d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  do {
616d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    convert[place++] =
617d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        (caps ? "0123456789ABCDEF" : "0123456789abcdef")
618d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        [uvalue % (unsigned)base];
619d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    uvalue = (uvalue / (unsigned)base );
620d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  } while (uvalue && (place < 20));
621d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (place == 20)
622d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    place--;
623d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  convert[place] = 0;
624d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
625d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  zpadlen = max - place;
626d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  spadlen = min - PADMAX(max, place) - (signvalue ? 1 : 0);
627d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (zpadlen < 0)
628d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    zpadlen = 0;
629d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (spadlen < 0)
630d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    spadlen = 0;
631d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (flags & DP_F_ZERO) {
632d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    zpadlen = PADMAX(zpadlen, spadlen);
633d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    spadlen = 0;
634d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
635d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (flags & DP_F_MINUS)
636d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    spadlen = -spadlen; /* Left Justifty */
637d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
638d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Spaces */
639d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (spadlen > 0) {
640d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, ' ');
641d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    --spadlen;
642d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
643d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
644d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Sign */
645d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (signvalue)
646d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, signvalue);
647d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
648d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Zeros */
649d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (zpadlen > 0) {
650d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    while (zpadlen > 0) {
651d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      dopr_outch(buffer, currlen, maxlen, '0');
652d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      --zpadlen;
653d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
654d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
655d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
656d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Digits */
657d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (place > 0)
658d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, convert[--place]);
659d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
660d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Left Justified spaces */
661d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (spadlen < 0) {
662d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch (buffer, currlen, maxlen, ' ');
663d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++spadlen;
664d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
665d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
666d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
667d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic long double
668d7ce700605e1af0e455e31ec11f19ff21d26b525darylmpow10(int exp)
669d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
670d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long double result = 1;
671d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
672d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (exp) {
673d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    result *= 10;
674d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    exp--;
675d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
676d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
677d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return result;
678d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
679d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
680d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic long
681d7ce700605e1af0e455e31ec11f19ff21d26b525darylmround(long double value)
682d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
683d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long intpart = value;
684d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
685d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  value -= intpart;
686d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (value >= 0.5)
687d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    intpart++;
688d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
689d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return intpart;
690d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
691d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
692d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
693d7ce700605e1af0e455e31ec11f19ff21d26b525darylmfmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue,
694d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      int min, int max, int flags)
695d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
696d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  char iconvert[20], fconvert[20];
697d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int signvalue = 0, iplace = 0, fplace = 0;
698d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int padlen = 0; /* amount to pad */
699d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int zpadlen = 0, caps = 0;
700d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long intpart, fracpart;
701d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  long double ufvalue;
702d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
703d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /*
704d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * AIX manpage says the default is 0, but Solaris says the default
705d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * is 6, and sprintf on AIX defaults to 6
706d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   */
707d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (max < 0)
708d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    max = 6;
709d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
710d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  ufvalue = abs_val(fvalue);
711d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
712d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (fvalue < 0)
713d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    signvalue = '-';
714d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
715d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    signvalue = '+';
716d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else if (flags & DP_F_SPACE)
717d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    signvalue = ' ';
718d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
719d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  intpart = ufvalue;
720d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
721d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /*
722d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * Sorry, we only support 9 digits past the decimal because of our
723d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * conversion method
724d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   */
725d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (max > 9)
726d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    max = 9;
727d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
728d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* We "cheat" by converting the fractional part to integer by
729d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * multiplying by a factor of 10
730d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   */
731d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fracpart = round((pow10 (max)) * (ufvalue - intpart));
732d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
733d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (fracpart >= pow10 (max)) {
734d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    intpart++;
735d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    fracpart -= pow10 (max);
736d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
737d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
738d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Convert integer part */
739d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  do {
740d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    iconvert[iplace++] =
741d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        (caps ? "0123456789ABCDEF" : "0123456789abcdef")
742d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        [intpart % 10];
743d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    intpart = (intpart / 10);
744d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  } while(intpart && (iplace < 20));
745d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (iplace == 20)
746d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    iplace--;
747d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  iconvert[iplace] = 0;
748d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
749d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* Convert fractional part */
750d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  do {
751d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    fconvert[fplace++] =
752d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        (caps ? "0123456789ABCDEF" : "0123456789abcdef")
753d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        [fracpart % 10];
754d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    fracpart = (fracpart / 10);
755d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  } while(fracpart && (fplace < 20));
756d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (fplace == 20)
757d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    fplace--;
758d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fconvert[fplace] = 0;
759d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
760d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /* -1 for decimal point, another -1 if we are printing a sign */
761d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
762d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  zpadlen = max - fplace;
763d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (zpadlen < 0)
764d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    zpadlen = 0;
765d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (padlen < 0)
766d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    padlen = 0;
767d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (flags & DP_F_MINUS)
768d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    padlen = -padlen; /* Left Justifty */
769d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
770d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if ((flags & DP_F_ZERO) && (padlen > 0)) {
771d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (signvalue) {
772d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      dopr_outch(buffer, currlen, maxlen, signvalue);
773d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      --padlen;
774d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      signvalue = 0;
775d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
776d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    while (padlen > 0) {
777d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      dopr_outch(buffer, currlen, maxlen, '0');
778d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      --padlen;
779d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
780d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
781d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (padlen > 0) {
782d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, ' ');
783d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    --padlen;
784d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
785d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (signvalue)
786d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, signvalue);
787d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
788d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (iplace > 0)
789d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
790d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
791d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  /*
792d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * Decimal point.  This should probably use locale to find the
793d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   * correct char to print out.
794d7ce700605e1af0e455e31ec11f19ff21d26b525darylm   */
795d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  dopr_outch(buffer, currlen, maxlen, '.');
796d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
797d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (fplace > 0)
798d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
799d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
800d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (zpadlen > 0) {
801d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, '0');
802d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    --zpadlen;
803d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
804d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
805d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  while (padlen < 0) {
806d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dopr_outch(buffer, currlen, maxlen, ' ');
807d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    ++padlen;
808d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
809d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
810d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
811d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic void
812d7ce700605e1af0e455e31ec11f19ff21d26b525darylmdopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
813d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
814d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if (*currlen < maxlen)
815d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    buffer[(*currlen)++] = c;
816d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
817d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
818d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
819d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifndef HAVE_VSNPRINTF
820d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
821d7ce700605e1af0e455e31ec11f19ff21d26b525darylmvsnprintf(char *str, size_t count, const char *fmt, va_list args)
822d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
823d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  str[0] = 0;
824d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  dopr(str, count, fmt, args);
825d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
826d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return(strlen(str));
827d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
828d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif /* !HAVE_VSNPRINTF */
829d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
830d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifndef HAVE_SNPRINTF
831d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
832d7ce700605e1af0e455e31ec11f19ff21d26b525darylmsnprintf(char *str,size_t count,const char *fmt,...)
833d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
834d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  va_list ap;
835d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
836d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  va_start(ap, fmt);
837d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  (void) vsnprintf(str, count, fmt, ap);
838d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  va_end(ap);
839d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
840d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return(strlen(str));
841d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
842d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
843d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif /* !HAVE_SNPRINTF */
844