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