tests: Emulate mkdtemp when not available
[openafs.git] / tests / common / config.c
1 /*
2  * Copyright (c) 2010 Your File System Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 /*!
26  * Common functions for building a configuration directory
27  */
28
29 #include <afsconfig.h>
30 #include <afs/param.h>
31 #include <roken.h>
32
33 #include <afs/cellconfig.h>
34 #include <afs/afsutil.h>
35
36 #include <hcrypto/des.h>
37
38 #include <tests/tap/basic.h>
39 #include "common.h"
40
41 static FILE *
42 openConfigFile(char *dirname, char *filename) {
43     char *path = NULL;
44     FILE *file;
45
46     if (asprintf(&path, "%s/%s", dirname, filename) == -1)
47         return NULL;
48
49     file = fopen(path, "w");
50     free(path);
51     return file;
52 }
53
54 static void
55 unlinkConfigFile(char *dirname, char *filename) {
56     char *path;
57
58     if (asprintf(&path, "%s/%s", dirname, filename) != -1) {
59         unlink(path);
60         free(path);
61     }
62 }
63
64 /*!
65  *  Wrapper for mkdtemp
66  */
67
68 char *
69 afstest_mkdtemp(char *template)
70 {
71 #if defined(HAVE_MKDTEMP)
72     return mkdtemp(template);
73 #else
74     /*
75      * Note that using the following is not a robust replacement
76      * for mkdtemp as there is a possible race condition between
77      * creating the name and creating the directory itself.  The
78      * use of this routine is limited to running tests.
79      */
80     if (mktemp(template) == NULL)
81         return NULL;
82     if (mkdir(template, 0700))
83         return NULL;
84     return template;
85 #endif
86 }
87
88 /*!
89  * Build a test configuration directory, containing a CellServDB and ThisCell
90  * file for the "example.org" cell
91  *
92  * @return
93  * The path to the configuration directory. This should be freed by the caller
94  * using free()
95  *
96  */
97
98 char *
99 afstest_BuildTestConfig(void) {
100     char *dir = NULL;
101     FILE *file;
102     struct hostent *host;
103     char hostname[255];
104     struct in_addr iaddr;
105
106     if (asprintf(&dir, "%s/afs_XXXXXX", gettmpdir()) == -1)
107         goto fail;
108
109     if (afstest_mkdtemp(dir) == NULL)
110         goto fail;
111
112     /* Work out which IP address to use in our CellServDB. We figure this out
113      * according to the IP address which ubik is most likely to pick for one of
114      * our db servers */
115
116     gethostname(hostname, sizeof(hostname));
117     host = gethostbyname(hostname);
118     if (!host)
119         return NULL;
120
121     memcpy(&iaddr, host->h_addr, 4);
122
123     file = openConfigFile(dir, "CellServDB");
124     fprintf(file, ">example.org # An example cell\n");
125     fprintf(file, "%s #test.example.org\n", inet_ntoa(iaddr));
126     fclose(file);
127
128     /* Create a ThisCell file */
129     file = openConfigFile(dir, "ThisCell");
130     fprintf(file, "example.org");
131     fclose(file);
132
133     return dir;
134
135 fail:
136     if (dir)
137         free(dir);
138     return NULL;
139 }
140
141 /*!
142  * Delete at test configuration directory
143  */
144
145 void
146 afstest_UnlinkTestConfig(char *dir)
147 {
148     DIR *dirp;
149     struct dirent *de;
150
151     /* Sanity check, only zap directories that look like ours */
152     if (!strstr(dir, "afs_"))
153         return;
154     if (getenv("MAKECHECK") != NULL) {
155         dirp = opendir(dir);
156         if (!dirp)
157             return;
158         while ((de = readdir(dirp)))
159             unlinkConfigFile(dir, de->d_name);
160         rmdir(dir);
161     }
162 }
163
164 int
165 afstest_AddDESKeyFile(struct afsconf_dir *dir)
166 {
167     char keymaterial[]="\x19\x17\xff\xe6\xbb\x77\x2e\xfc";
168
169     /* Make sure that it is actually a valid key */
170     DES_set_odd_parity((DES_cblock *)keymaterial);
171
172     return afsconf_AddKey(dir, 1, keymaterial, 1);
173 }