00001
00005 #include "system.h"
00006
00007
00008 static int _debug = 0;
00009
00010
00011 const char * RPMVERSION = VERSION;
00012
00013 #include "rpmio_internal.h"
00014 #include <rpmurl.h>
00015 #include <rpmmacro.h>
00016 #include <rpmlib.h>
00017
00018 #include "misc.h"
00019 #include "debug.h"
00020
00021
00022
00023
00024 rpmRC rpmMkdirPath (const char * dpath, const char * dname)
00025 {
00026 struct stat st;
00027 int rc;
00028
00029 if ((rc = Stat(dpath, &st)) < 0) {
00030 int ut = urlPath(dpath, NULL);
00031 switch (ut) {
00032 case URL_IS_PATH:
00033 case URL_IS_UNKNOWN:
00034 if (errno != ENOENT)
00035 break;
00036
00037 case URL_IS_FTP:
00038 case URL_IS_HTTP:
00039 rc = Mkdir(dpath, 0755);
00040 break;
00041 case URL_IS_DASH:
00042 break;
00043 }
00044 if (rc < 0) {
00045 rpmError(RPMERR_CREATE, _("cannot create %%%s %s\n"), dname, dpath);
00046 return RPMRC_FAIL;
00047 }
00048 }
00049 if ((rc = Access(dpath, W_OK))) {
00050 rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"), dname, dpath);
00051 return RPMRC_FAIL;
00052 }
00053 return RPMRC_OK;
00054 }
00055
00056
00057 char ** splitString(const char * str, int length, char sep)
00058 {
00059 const char * source;
00060 char * s, * dest;
00061 char ** list;
00062 int i;
00063 int fields;
00064
00065 s = xmalloc(length + 1);
00066
00067 fields = 1;
00068 for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) {
00069 *dest = *source;
00070 if (*dest == sep) fields++;
00071 }
00072
00073 *dest = '\0';
00074
00075 list = xmalloc(sizeof(*list) * (fields + 1));
00076
00077 dest = s;
00078 list[0] = dest;
00079 i = 1;
00080 while (i < fields) {
00081 if (*dest == sep) {
00082 list[i++] = dest + 1;
00083 *dest = 0;
00084 }
00085 dest++;
00086 }
00087
00088 list[i] = NULL;
00089
00090 return list;
00091 }
00092
00093
00094 void freeSplitString(char ** list)
00095 {
00096
00097 list[0] = _free(list[0]);
00098
00099 list = _free(list);
00100 }
00101
00102 int doputenv(const char *str)
00103 {
00104 char * a;
00105
00106
00107 a = xmalloc(strlen(str) + 1);
00108 strcpy(a, str);
00109 return putenv(a);
00110 }
00111
00112 int dosetenv(const char * name, const char * value, int overwrite)
00113 {
00114 char * a;
00115
00116 if (!overwrite && getenv(name)) return 0;
00117
00118
00119 a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
00120 (void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
00121 return putenv(a);
00122 }
00123
00124 int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr)
00125 {
00126 const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:/var/tmp}";
00127 const char * tempfn = NULL;
00128 const char * tfn = NULL;
00129 static int _initialized = 0;
00130 int temput;
00131 FD_t fd = NULL;
00132 int ran;
00133
00134
00135 if (!prefix) prefix = "";
00136
00137
00138
00139
00140 if (!_initialized) {
00141 _initialized = 1;
00142 tempfn = rpmGenPath(prefix, tpmacro, NULL);
00143 if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
00144 goto errxit;
00145 }
00146
00147
00148
00149 srand(time(NULL));
00150 ran = rand() % 100000;
00151
00152
00153
00154 do {
00155 char tfnbuf[64];
00156 #ifndef NOTYET
00157 sprintf(tfnbuf, "rpm-tmp.%d", ran++);
00158 tempfn = _free(tempfn);
00159 tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
00160 #else
00161 strcpy(tfnbuf, "rpm-tmp.XXXXXX");
00162 tempfn = _free(tempfn);
00163 tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
00164 #endif
00165
00166 temput = urlPath(tempfn, &tfn);
00167 if (*tfn == '\0') goto errxit;
00168
00169 switch (temput) {
00170 case URL_IS_HTTP:
00171 case URL_IS_DASH:
00172 goto errxit;
00173 break;
00174 default:
00175 break;
00176 }
00177
00178 fd = Fopen(tempfn, "w+x.ufdio");
00179
00180 } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
00181
00182 if (fd == NULL || Ferror(fd))
00183 goto errxit;
00184
00185 switch(temput) {
00186 case URL_IS_PATH:
00187 case URL_IS_UNKNOWN:
00188 { struct stat sb, sb2;
00189 if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
00190 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00191 goto errxit;
00192 }
00193
00194 if (sb.st_nlink != 1) {
00195 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00196 goto errxit;
00197 }
00198
00199 if (fstat(Fileno(fd), &sb2) == 0) {
00200 if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
00201 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00202 goto errxit;
00203 }
00204 }
00205 } break;
00206 default:
00207 break;
00208 }
00209
00210
00211 if (fnptr)
00212 *fnptr = tempfn;
00213 else
00214 tempfn = _free(tempfn);
00215
00216 *fdptr = fd;
00217
00218 return 0;
00219
00220 errxit:
00221 tempfn = _free(tempfn);
00222
00223 if (fd) (void) Fclose(fd);
00224
00225 return 1;
00226 }
00227
00228 char * currentDirectory(void)
00229 {
00230 int currDirLen;
00231 char * currDir;
00232
00233 currDirLen = 50;
00234 currDir = xmalloc(currDirLen);
00235 while (!getcwd(currDir, currDirLen) && errno == ERANGE) {
00236 currDirLen += 50;
00237 currDir = xrealloc(currDir, currDirLen);
00238 }
00239
00240 return currDir;
00241 }
00242
00243
00244
00245
00246
00247
00248 int myGlobPatternP (const char *patternURL)
00249 {
00250 const char *p;
00251 char c;
00252 int open = 0;
00253
00254 (void) urlPath(patternURL, &p);
00255 while ((c = *p++) != '\0')
00256 switch (c) {
00257 case '+':
00258 case '@':
00259 case '!':
00260 if (*p == '(')
00261 return (1);
00262 continue;
00263 case '?':
00264 case '*':
00265 return (1);
00266 case '[':
00267 open++;
00268 continue;
00269 case ']':
00270 if (open)
00271 return (1);
00272 continue;
00273 case '\\':
00274 if (*p++ == '\0')
00275 return (0);
00276 }
00277
00278 return (0);
00279 }
00280
00281 static int glob_error(const char *foo, int bar)
00282 {
00283 return 1;
00284 }
00285
00286 int rpmGlob(const char * patterns, int * argcPtr, const char *** argvPtr)
00287 {
00288 int ac = 0;
00289 const char ** av = NULL;
00290 int argc = 0;
00291 const char ** argv = NULL;
00292 const char * path;
00293 const char * globURL;
00294 char * globRoot = NULL;
00295 size_t maxb, nb;
00296 glob_t gl;
00297 int ut;
00298 int i, j;
00299 int rc;
00300
00301 rc = poptParseArgvString(patterns, &ac, &av);
00302 if (rc)
00303 return rc;
00304
00305 for (j = 0; j < ac; j++) {
00306 if (!myGlobPatternP(av[j])) {
00307 if (argc == 0)
00308 argv = xmalloc((argc+2) * sizeof(*argv));
00309 else
00310 argv = xrealloc(argv, (argc+2) * sizeof(*argv));
00311 argv[argc] = xstrdup(av[j]);
00312 if (_debug)
00313 fprintf(stderr, "*** rpmGlob argv[%d] \"%s\"\n", argc, argv[argc]);
00314 argc++;
00315 continue;
00316 }
00317
00318 gl.gl_pathc = 0;
00319 gl.gl_pathv = NULL;
00320 rc = Glob(av[j], 0, glob_error, &gl);
00321 if (rc)
00322 goto exit;
00323
00324
00325 maxb = 0;
00326 for (i = 0; i < gl.gl_pathc; i++) {
00327 if ((nb = strlen(&(gl.gl_pathv[i][0]))) > maxb)
00328 maxb = nb;
00329 }
00330
00331 ut = urlPath(av[j], &path);
00332 nb = ((ut > URL_IS_DASH && ut != URL_IS_FTP) ? (path - av[j]) : 0);
00333 maxb += nb;
00334 maxb += 1;
00335 globURL = globRoot = xmalloc(maxb);
00336
00337 switch (ut) {
00338 case URL_IS_HTTP:
00339 case URL_IS_PATH:
00340 case URL_IS_DASH:
00341 strncpy(globRoot, av[j], nb);
00342 break;
00343 case URL_IS_FTP:
00344 case URL_IS_UNKNOWN:
00345 break;
00346 }
00347 globRoot += nb;
00348 *globRoot = '\0';
00349 if (_debug)
00350 fprintf(stderr, "*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", (int)maxb, (int)nb, (int)nb, av[j], globURL, globURL);
00351
00352
00353 if (argc == 0)
00354 argv = xmalloc((gl.gl_pathc+1) * sizeof(*argv));
00355 else if (gl.gl_pathc > 0)
00356 argv = xrealloc(argv, (argc+gl.gl_pathc+1) * sizeof(*argv));
00357
00358 for (i = 0; i < gl.gl_pathc; i++) {
00359 const char * globFile = &(gl.gl_pathv[i][0]);
00360 if (globRoot > globURL && globRoot[-1] == '/')
00361 while (*globFile == '/') globFile++;
00362 strcpy(globRoot, globFile);
00363 if (_debug)
00364 fprintf(stderr, "*** rpmGlob argv[%d] \"%s\"\n", argc, globURL);
00365 argv[argc++] = xstrdup(globURL);
00366 }
00367
00368 Globfree(&gl);
00369
00370 globURL = _free(globURL);
00371 }
00372 if (argv != NULL && argc > 0) {
00373 argv[argc] = NULL;
00374 if (argvPtr)
00375 *argvPtr = argv;
00376 if (argcPtr)
00377 *argcPtr = argc;
00378 rc = 0;
00379 } else
00380 rc = 1;
00381
00382
00383 exit:
00384 av = _free(av);
00385 if (rc || argvPtr == NULL) {
00386 if (argv != NULL)
00387 for (i = 0; i < argc; i++)
00388 argv[i] = _free(argv[i]);
00389 argv = _free(argv);
00390 }
00391 return rc;
00392 }
00393
00394
00395
00396
00397
00398
00399 int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
00400 void **p, int_32 *c)
00401 {
00402 switch (tag) {
00403 case RPMTAG_OLDFILENAMES:
00404 { const char ** fl = NULL;
00405 int count;
00406 rpmBuildFileList(h, &fl, &count);
00407 if (count > 0) {
00408 *p = fl;
00409 if (c) *c = count;
00410 if (type) *type = RPM_STRING_ARRAY_TYPE;
00411 return 1;
00412 }
00413 if (c) *c = 0;
00414 return 0;
00415 } break;
00416
00417 case RPMTAG_GROUP:
00418 case RPMTAG_DESCRIPTION:
00419 case RPMTAG_SUMMARY:
00420 { char fmt[128];
00421 const char * msgstr;
00422 const char * errstr;
00423
00424 fmt[0] = '\0';
00425 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n");
00426
00427
00428 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00429 if (msgstr) {
00430 *p = (void *) msgstr;
00431 if (type) *type = RPM_STRING_TYPE;
00432 if (c) *c = 1;
00433 return 1;
00434 } else {
00435 if (c) *c = 0;
00436 return 0;
00437 }
00438 } break;
00439
00440 default:
00441 return headerGetEntry(h, tag, type, p, c);
00442 break;
00443 }
00444
00445 }