agent: New option --pinentry-timeout
[gnupg.git] / doc / mkdefsinc.c
1 /* mkdefsinc.c - Tool to create defs.inc
2  * Copyright (C) 2015 g10 Code GmbH
3  *
4  * This file is free software; as a special exception the author gives
5  * unlimited permission to copy and/or distribute it, with or without
6  * modifications, as long as this notice is preserved.
7  *
8  * This file is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
10  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  */
12
13 /* This tool needs to be build with command line supplied -D options
14    for the various directory variables.  See ../am/cmacros.am.  It is
15    easier to do this in build file than to use fragile make rules and
16    a template file.  */
17
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <time.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27
28 #define PGM "mkdefsinc"
29
30 /* We include config.h after all include files because the config.h
31    values are not valid for the build platform but we need some values
32    nevertheless.  */
33 #include "config.h"
34 /* When building for Windows the -D macros do not have appropriate
35    values.  We provide replacements here.  */
36 #ifdef HAVE_W32_SYSTEM
37 # undef  GNUPG_BINDIR
38 # undef  GNUPG_LIBEXECDIR
39 # undef  GNUPG_LIBDIR
40 # undef  GNUPG_DATADIR
41 # undef  GNUPG_SYSCONFDIR
42 # undef  GNUPG_LOCALSTATEDIR
43 # define GNUPG_BINDIR        "INSTDIR/bin"
44 # define GNUPG_LIBEXECDIR    "INSTDIR/bin"
45 # define GNUPG_LIBDIR        "INSTDIR/lib/" PACKAGE_NAME
46 # define GNUPG_DATADIR       "INSTDIR/share/" PACKAGE_NAME
47 # define GNUPG_SYSCONFDIR    "APPDATA/GNU/etc/" PACKAGE_NAME
48 # define GNUPG_LOCALSTATEDIR "APPDATA/GNU"
49 #endif /*HAVE_W32_SYSTEM*/
50
51
52 static int verbose;
53
54
55 /* The usual free wrapper.  */
56 static void
57 xfree (void *a)
58 {
59   if (a)
60     free (a);
61 }
62
63
64 static char *
65 xmalloc (size_t n)
66 {
67   char *p;
68
69   p = malloc (n);
70   if (!p)
71     {
72       fputs (PGM ": out of core\n", stderr);
73       exit (1);
74     }
75   return p;
76 }
77
78
79 static char *
80 xstrdup (const char *string)
81 {
82   char *p;
83
84   p = xmalloc (strlen (string)+1);
85   strcpy (p, string);
86   return p;
87 }
88
89
90 /* Return a malloced string with the last modification date of the
91    FILES.  Returns NULL on error.  */
92 static char *
93 get_date_from_files (char **files)
94 {
95   const char *file;
96   const char *usedfile = NULL;
97   struct stat sb;
98   struct tm *tp;
99   int errors = 0;
100   time_t stamp = 0;
101   char *result;
102
103   for (; (file = *files); files++)
104     {
105       if (!*file || !strcmp (file, ".") || !strcmp (file, ".."))
106         continue;
107       if (stat (file, &sb))
108         {
109           fprintf (stderr, PGM ": stat failed for '%s': %s\n",
110                    file, strerror (errno));
111           errors = 1;
112           continue;
113         }
114       if (sb.st_mtime > stamp)
115         {
116           stamp = sb.st_mtime;
117           usedfile = file;
118         }
119     }
120   if (errors)
121     exit (1);
122
123   if (usedfile)
124     fprintf (stderr, PGM ": taking date from '%s'\n", usedfile);
125
126   tp = gmtime (&stamp);
127   if (!tp)
128     return NULL;
129   result = xmalloc (4+1+2+1+2+1);
130   snprintf (result, 4+1+2+1+2+1, "%04d-%02d-%02d",
131             tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday);
132   return result;
133 }
134
135
136
137 int
138 main (int argc, char **argv)
139 {
140   int last_argc = -1;
141   char *opt_date = NULL;
142   int monthoff;
143   char *p, *pend;
144   size_t n;
145
146   /* Option parsing.  */
147   if (argc)
148     {
149       argc--; argv++;
150     }
151   while (argc && last_argc != argc )
152     {
153       last_argc = argc;
154       if (!strcmp (*argv, "--"))
155         {
156           argc--; argv++;
157           break;
158         }
159       else if (!strcmp (*argv, "--help"))
160         {
161           fputs ("Usage: " PGM " [OPTION] [FILES]\n"
162                  "Create defs.inc file.\nOptions:\n"
163                  "  -C DIR         Change to DIR before doing anything\n"
164                  "  --date STRING  Take publication date from STRING\n"
165                  "  --verbose      Enable extra informational output\n"
166                  "  --help         Display this help and exit\n"
167                  , stdout);
168           exit (0);
169         }
170       else if (!strcmp (*argv, "--verbose"))
171         {
172           verbose = 1;
173           argc--; argv++;
174         }
175       else if (!strcmp (*argv, "-C"))
176         {
177           argc--; argv++;
178           if (argc)
179             {
180               if (chdir (*argv))
181                 {
182                   fprintf (stderr, PGM ": chdir to '%s' failed: %s\n",
183                            *argv, strerror (errno));
184                   exit (1);
185                 }
186               argc--; argv++;
187             }
188         }
189       else if (!strcmp (*argv, "--date"))
190         {
191           argc--; argv++;
192           if (argc)
193             {
194               opt_date = xstrdup (*argv);
195               argc--; argv++;
196             }
197         }
198       else if (!strncmp (*argv, "--", 2))
199         {
200           fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
201           exit (1);
202         }
203     }
204
205   if (opt_date && *opt_date)
206     {
207       time_t stamp;
208       struct tm *tp;
209
210       if (*opt_date == '2' && strlen (opt_date) >= 10
211           && opt_date[4] == '-' && opt_date[7] == '-')
212         {
213           opt_date[10] = 0;
214         }
215       else if ((stamp = strtoul (opt_date, NULL, 10)) > 0
216                && (tp = gmtime (&stamp)))
217         {
218           p = xmalloc (4+1+2+1+2+1);
219           snprintf (p, 4+1+2+1+2+1, "%04d-%02d-%02d",
220                     tp->tm_year + 1900, tp->tm_mon+1, tp->tm_mday);
221           xfree (opt_date);
222           opt_date = p;
223         }
224       else
225         {
226           fprintf (stderr, PGM ": bad date '%s'\n", opt_date);
227           exit (1);
228         }
229     }
230   else
231     {
232       xfree (opt_date);
233       opt_date = argc? get_date_from_files (argv) : NULL;
234     }
235   if (!opt_date)
236     {
237       opt_date = xstrdup ("unknown");
238       monthoff = 0;
239     }
240   else
241     {
242       const char *month = "?";
243
244       switch (atoi (opt_date+5))
245         {
246         case  1: month = "January"; break;
247         case  2: month = "February"; break;
248         case  3: month = "March"; break;
249         case  4: month = "April"; break;
250         case  5: month = "May"; break;
251         case  6: month = "June"; break;
252         case  7: month = "July"; break;
253         case  8: month = "August"; break;
254         case  9: month = "September"; break;
255         case 10: month = "October"; break;
256         case 11: month = "November"; break;
257         case 12: month = "December"; break;
258         }
259       n = strlen (opt_date) + strlen (month) + 2 + 1;
260       p = xmalloc (n);
261       snprintf (p, n, "%d %n%s %d",
262                 atoi (opt_date+8), &monthoff, month, atoi (opt_date));
263       xfree (opt_date);
264       opt_date = p;
265     }
266
267
268   fputs ("@c defs.inc                         -*- texinfo -*-\n"
269          "@c Common and build specific constants for the manuals.\n"
270          "@c This file has been created by " PGM ".\n", stdout);
271
272   fputs ("\n@c Directories\n\n", stdout);
273
274   fputs ("@set BINDIR         " GNUPG_BINDIR        "\n"
275          "@set LIBEXECDIR     " GNUPG_LIBEXECDIR    "\n"
276          "@set LIBDIR         " GNUPG_LIBDIR        "\n"
277          "@set DATADIR        " GNUPG_DATADIR       "\n"
278          "@set SYSCONFDIR     " GNUPG_SYSCONFDIR    "\n"
279          "@set LOCALSTATEDIR  " GNUPG_LOCALSTATEDIR "\n"
280          "@set LOCALCACHEDIR  " GNUPG_LOCALSTATEDIR
281          /*                  */ "/cache/" PACKAGE_NAME "\n"
282          "@set LOCALRUNDIR    " GNUPG_LOCALSTATEDIR
283          /*                  */ "/run/"  PACKAGE_NAME "\n"
284          , stdout);
285
286   p = xstrdup (GNUPG_SYSCONFDIR);
287   pend = strrchr (p, '/');
288   fputs ("@set SYSCONFSKELDIR ", stdout);
289   if (pend)
290     {
291       *pend = 0;
292       fputs (p, stdout);
293     }
294   fputs ("/skel/." PACKAGE_NAME "\n", stdout);
295   xfree (p);
296
297   fputs ("\n@c Version information a la version.texi\n\n", stdout);
298
299   printf ("@set UPDATED %s\n", opt_date);
300   printf ("@set UPDATED-MONTH %s\n", opt_date + monthoff);
301   printf ("@set EDITION %s\n", PACKAGE_VERSION);
302   printf ("@set VERSION %s\n", PACKAGE_VERSION);
303
304   fputs ("\n@c Algorithm defaults\n\n", stdout);
305
306   /* Fixme: Use a config.h macro here:  */
307   fputs ("@set GPGSYMENCALGO AES-128\n", stdout);
308
309
310   fputs ("\n"
311          "@c Loc" "al Variables:\n"
312          "@c buffer-read-only: t\n"
313          "@c End:\n", stdout);
314
315   if (ferror (stdout))
316     {
317       fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno));
318       return 1;
319     }
320
321   return 0;
322 }