rpm  4.5
misc.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 /* just to put a marker in librpm.a */
8 const char * RPMVERSION = VERSION;
9 
10 #include "rpmio_internal.h"
11 #include <rpmurl.h>
12 #include <rpmmacro.h> /* XXX for rpmGetPath */
13 #include <rpmlib.h>
14 #include "legacy.h"
15 #include "misc.h"
16 #include "debug.h"
17 
18 rpmRC rpmMkdirPath (const char * dpath, const char * dname)
19 {
20  struct stat st;
21  int rc;
22 
23  if ((rc = Stat(dpath, &st)) < 0) {
24  int ut = urlPath(dpath, NULL);
25  switch (ut) {
26  case URL_IS_PATH:
27  case URL_IS_UNKNOWN:
28  if (errno != ENOENT)
29  break;
30  /*@fallthrough@*/
31  case URL_IS_HTTPS:
32  case URL_IS_HTTP:
33  case URL_IS_FTP:
34  rc = Mkdir(dpath, 0755);
35  break;
36  case URL_IS_DASH:
37  case URL_IS_HKP:
38  break;
39  }
40  if (rc < 0) {
41  rpmError(RPMERR_CREATE, _("cannot create %%%s %s\n"), dname, dpath);
42  return RPMRC_FAIL;
43  }
44  }
45  return RPMRC_OK;
46 }
47 
48 /*@-bounds@*/
49 char ** splitString(const char * str, int length, char sep)
50 {
51  const char * source;
52  char * s, * dest;
53  char ** list;
54  int i;
55  int fields;
56 
57  s = xmalloc(length + 1);
58 
59  fields = 1;
60  for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) {
61  *dest = *source;
62  if (*dest == sep) fields++;
63  }
64 
65  *dest = '\0';
66 
67  list = xmalloc(sizeof(*list) * (fields + 1));
68 
69  dest = s;
70  list[0] = dest;
71  i = 1;
72  while (i < fields) {
73  if (*dest == sep) {
74  list[i++] = dest + 1;
75  *dest = 0;
76  }
77  dest++;
78  }
79 
80  list[i] = NULL;
81 
82 /*@-nullret@*/ /* FIX: list[i] is NULL */
83  return list;
84 /*@=nullret@*/
85 }
86 /*@=bounds@*/
87 
88 void freeSplitString(char ** list)
89 {
90  /*@-unqualifiedtrans@*/
91  list[0] = _free(list[0]);
92  /*@=unqualifiedtrans@*/
93  list = _free(list);
94 }
95 
96 int doputenv(const char *str)
97 {
98  char * a;
99 
100  /* FIXME: this leaks memory! */
101  a = xmalloc(strlen(str) + 1);
102  strcpy(a, str);
103  return putenv(a);
104 }
105 
106 int dosetenv(const char * name, const char * value, int overwrite)
107 {
108  char * a;
109 
110  if (!overwrite && getenv(name)) return 0;
111 
112  /* FIXME: this leaks memory! */
113  a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
114  (void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
115  return putenv(a);
116 }
117 
118 int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr)
119 {
120  const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:/var/tmp}";
121  const char * tempfn = NULL;
122  const char * tfn = NULL;
123  static int _initialized = 0;
124  int temput;
125  FD_t fd = NULL;
126  int ran;
127 
128  /*@-branchstate@*/
129  if (!prefix) prefix = "";
130  /*@=branchstate@*/
131 
132  /* Create the temp directory if it doesn't already exist. */
133  /*@-branchstate@*/
134  if (!_initialized) {
135  _initialized = 1;
136  tempfn = rpmGenPath(prefix, tpmacro, NULL);
137  if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
138  goto errxit;
139  }
140  /*@=branchstate@*/
141 
142  /* XXX should probably use mkstemp here */
143  srand(time(NULL));
144  ran = rand() % 100000;
145 
146  /* maybe this should use link/stat? */
147 
148  do {
149  char tfnbuf[64];
150 #ifndef NOTYET
151  sprintf(tfnbuf, "rpm-tmp.%d", ran++);
152  tempfn = _free(tempfn);
153  tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
154 #else
155  strcpy(tfnbuf, "rpm-tmp.XXXXXX");
156  tempfn = _free(tempfn);
157  tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
158 #endif
159 
160  temput = urlPath(tempfn, &tfn);
161  if (*tfn == '\0') goto errxit;
162 
163  switch (temput) {
164  case URL_IS_DASH:
165  case URL_IS_HKP:
166  goto errxit;
167  /*@notreached@*/ /*@switchbreak@*/ break;
168  case URL_IS_HTTPS:
169  case URL_IS_HTTP:
170  case URL_IS_FTP:
171  default:
172  /*@switchbreak@*/ break;
173  }
174 
175  fd = Fopen(tempfn, "w+x");
176  /* XXX FIXME: errno may not be correct for ufdio */
177  } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
178 
179  if (fd == NULL || Ferror(fd)) {
180  rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tempfn);
181  goto errxit;
182  }
183 
184  switch(temput) {
185  case URL_IS_PATH:
186  case URL_IS_UNKNOWN:
187  { struct stat sb, sb2;
188  if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
189  rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
190  goto errxit;
191  }
192 
193  if (sb.st_nlink != 1) {
194  rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
195  goto errxit;
196  }
197 
198  if (fstat(Fileno(fd), &sb2) == 0) {
199  if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
200  rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
201  goto errxit;
202  }
203  }
204  } break;
205  default:
206  break;
207  }
208 
209  /*@-branchstate@*/
210  if (fnptr)
211  *fnptr = tempfn;
212  else
213  tempfn = _free(tempfn);
214  /*@=branchstate@*/
215  *fdptr = fd;
216 
217  return 0;
218 
219 errxit:
220  tempfn = _free(tempfn);
221  if (fnptr)
222  *fnptr = NULL;
223  /*@-usereleased@*/
224  if (fd != NULL) (void) Fclose(fd);
225  /*@=usereleased@*/
226  return 1;
227 }
228 
229 char * currentDirectory(void)
230 {
231  int currDirLen = 0;
232  char * currDir = NULL;
233 
234  do {
235  currDirLen += 128;
236  currDir = xrealloc(currDir, currDirLen);
237  memset(currDir, 0, currDirLen);
238  } while (getcwd(currDir, currDirLen) == NULL && errno == ERANGE);
239 
240  return currDir;
241 }