add changelog
[platform/upstream/gdbm.git] / src / util.c
1 /* This file is part of GDBM, the GNU data base manager.
2    Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
3    Inc.
4
5    GDBM is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9
10    GDBM is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with GDBM. If not, see <http://www.gnu.org/licenses/>.    */
17
18 #include "gdbmtool.h"
19 #include <pwd.h>
20
21 char *
22 mkfilename (const char *dir, const char *file, const char *suf)
23 {
24   char *tmp;
25   size_t dirlen = strlen (dir);
26   size_t suflen = suf ? strlen (suf) : 0;
27   size_t fillen = strlen (file);
28   size_t len;
29   
30   while (dirlen > 0 && dir[dirlen-1] == '/')
31     dirlen--;
32
33   len = dirlen + (dir[0] ? 1 : 0) + fillen + suflen;
34   tmp = emalloc (len + 1);
35   memcpy (tmp, dir, dirlen);
36   if (dir[0])
37     tmp[dirlen++] = '/';
38   memcpy (tmp + dirlen, file, fillen);
39   if (suf)
40     memcpy (tmp + dirlen + fillen, suf, suflen);
41   tmp[len] = 0;
42   return tmp;
43 }
44
45 char *
46 tildexpand (char *s)
47 {
48   if (s[0] == '~')
49     {
50       char *p = s + 1;
51       size_t len = strcspn (p, "/");
52       struct passwd *pw;
53
54       if (len == 0)
55         pw = getpwuid (getuid ());
56       else
57         {
58           char *user = emalloc (len + 1);
59           
60           memcpy (user, p, len);
61           user[len] = 0;
62           pw = getpwnam (user);
63           free (user);
64         }
65       if (pw)
66         return mkfilename (pw->pw_dir, p + len + 1, NULL);
67     }
68   return estrdup (s);
69 }
70
71 int
72 vgetyn (const char *prompt, va_list ap)
73 {
74   int state = 0;
75   int c, resp;
76
77   do
78     {
79       switch (state)
80         {
81         case 1:
82           if (c == ' ' || c == '\t')
83             continue;
84           resp = c;
85           state = 2;
86           /* fall through */
87         case 2:
88           if (c == '\n')
89             {
90               switch (resp)
91                 {
92                 case 'y':
93                 case 'Y':
94                   return 1;
95                 case 'n':
96                 case 'N':
97                   return 0;
98                 default:
99                   fprintf (stdout, "%s\n", _("Please, reply 'y' or 'n'"));
100                 }
101               state = 0;
102             } else
103             break;
104           
105         case 0:
106           vfprintf (stdout, prompt, ap);
107           fprintf (stdout, " [y/n]?");
108           fflush (stdout);
109           state = 1;
110           break;
111         }
112     } while ((c = getchar ()) != EOF);
113   exit (EXIT_USAGE);
114 }
115         
116 int
117 getyn (const char *prompt, ...)
118 {
119   va_list ap;
120   int rc;
121   
122   va_start (ap, prompt);
123   rc = vgetyn (prompt, ap);
124   va_end (ap);
125   return rc;
126 }
127