lib/misc.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 /* just to put a marker in librpm.a */
00008 const char * RPMVERSION = VERSION;
00009 
00010 #include "rpmio_internal.h"
00011 #include <rpmurl.h>
00012 #include <rpmmacro.h>   /* XXX for rpmGetPath */
00013 #include <rpmlib.h>
00014 #include "legacy.h"
00015 #include "misc.h"
00016 #include "debug.h"
00017 
00018 rpmRC rpmMkdirPath (const char * dpath, const char * dname)
00019 {
00020     struct stat st;
00021     int rc;
00022 
00023     if ((rc = Stat(dpath, &st)) < 0) {
00024         int ut = urlPath(dpath, NULL);
00025         switch (ut) {
00026         case URL_IS_PATH:
00027         case URL_IS_UNKNOWN:
00028             if (errno != ENOENT)
00029                 break;
00030             /*@fallthrough@*/
00031         case URL_IS_HTTPS:
00032         case URL_IS_HTTP:
00033         case URL_IS_FTP:
00034             rc = Mkdir(dpath, 0755);
00035             break;
00036         case URL_IS_DASH:
00037         case URL_IS_HKP:
00038             break;
00039         }
00040         if (rc < 0) {
00041             rpmError(RPMERR_CREATE, _("cannot create %%%s %s\n"), dname, dpath);
00042             return RPMRC_FAIL;
00043         }
00044     }
00045     if ((rc = Access(dpath, W_OK))) {
00046         rpmError(RPMERR_CREATE, _("cannot write to %%%s %s\n"), dname, dpath);
00047         return RPMRC_FAIL;
00048     }
00049     return RPMRC_OK;
00050 }
00051 
00052 /*@-bounds@*/
00053 char ** splitString(const char * str, int length, char sep)
00054 {
00055     const char * source;
00056     char * s, * dest;
00057     char ** list;
00058     int i;
00059     int fields;
00060 
00061     s = xmalloc(length + 1);
00062 
00063     fields = 1;
00064     for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) {
00065         *dest = *source;
00066         if (*dest == sep) fields++;
00067     }
00068 
00069     *dest = '\0';
00070 
00071     list = xmalloc(sizeof(*list) * (fields + 1));
00072 
00073     dest = s;
00074     list[0] = dest;
00075     i = 1;
00076     while (i < fields) {
00077         if (*dest == sep) {
00078             list[i++] = dest + 1;
00079             *dest = 0;
00080         }
00081         dest++;
00082     }
00083 
00084     list[i] = NULL;
00085 
00086 /*@-nullret@*/ /* FIX: list[i] is NULL */
00087     return list;
00088 /*@=nullret@*/
00089 }
00090 /*@=bounds@*/
00091 
00092 void freeSplitString(char ** list)
00093 {
00094     /*@-unqualifiedtrans@*/
00095     list[0] = _free(list[0]);
00096     /*@=unqualifiedtrans@*/
00097     list = _free(list);
00098 }
00099 
00100 int doputenv(const char *str)
00101 {
00102     char * a;
00103 
00104     /* FIXME: this leaks memory! */
00105     a = xmalloc(strlen(str) + 1);
00106     strcpy(a, str);
00107     return putenv(a);
00108 }
00109 
00110 int dosetenv(const char * name, const char * value, int overwrite)
00111 {
00112     char * a;
00113 
00114     if (!overwrite && getenv(name)) return 0;
00115 
00116     /* FIXME: this leaks memory! */
00117     a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
00118     (void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
00119     return putenv(a);
00120 }
00121 
00122 int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr)
00123 {
00124     const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:/var/tmp}";
00125     const char * tempfn = NULL;
00126     const char * tfn = NULL;
00127     static int _initialized = 0;
00128     int temput;
00129     FD_t fd = NULL;
00130     int ran;
00131 
00132     /*@-branchstate@*/
00133     if (!prefix) prefix = "";
00134     /*@=branchstate@*/
00135 
00136     /* Create the temp directory if it doesn't already exist. */
00137     /*@-branchstate@*/
00138     if (!_initialized) {
00139         _initialized = 1;
00140         tempfn = rpmGenPath(prefix, tpmacro, NULL);
00141         if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
00142             goto errxit;
00143     }
00144     /*@=branchstate@*/
00145 
00146     /* XXX should probably use mkstemp here */
00147     srand(time(NULL));
00148     ran = rand() % 100000;
00149 
00150     /* maybe this should use link/stat? */
00151 
00152     do {
00153         char tfnbuf[64];
00154 #ifndef NOTYET
00155         sprintf(tfnbuf, "rpm-tmp.%d", ran++);
00156         tempfn = _free(tempfn);
00157         tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
00158 #else
00159         strcpy(tfnbuf, "rpm-tmp.XXXXXX");
00160         tempfn = _free(tempfn);
00161         tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
00162 #endif
00163 
00164         temput = urlPath(tempfn, &tfn);
00165         if (*tfn == '\0') goto errxit;
00166 
00167         switch (temput) {
00168         case URL_IS_DASH:
00169         case URL_IS_HKP:
00170             goto errxit;
00171             /*@notreached@*/ /*@switchbreak@*/ break;
00172         case URL_IS_HTTPS:
00173         case URL_IS_HTTP:
00174         case URL_IS_FTP:
00175         default:
00176             /*@switchbreak@*/ break;
00177         }
00178 
00179         fd = Fopen(tempfn, "w+x.ufdio");
00180         /* XXX FIXME: errno may not be correct for ufdio */
00181     } while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
00182 
00183     if (fd == NULL || Ferror(fd))
00184         goto errxit;
00185 
00186     switch(temput) {
00187     case URL_IS_PATH:
00188     case URL_IS_UNKNOWN:
00189       { struct stat sb, sb2;
00190         if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
00191             rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00192             goto errxit;
00193         }
00194 
00195         if (sb.st_nlink != 1) {
00196             rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00197             goto errxit;
00198         }
00199 
00200         if (fstat(Fileno(fd), &sb2) == 0) {
00201             if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
00202                 rpmError(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
00203                 goto errxit;
00204             }
00205         }
00206       } break;
00207     default:
00208         break;
00209     }
00210 
00211     /*@-branchstate@*/
00212     if (fnptr)
00213         *fnptr = tempfn;
00214     else 
00215         tempfn = _free(tempfn);
00216     /*@=branchstate@*/
00217     *fdptr = fd;
00218 
00219     return 0;
00220 
00221 errxit:
00222     tempfn = _free(tempfn);
00223     /*@-usereleased@*/
00224     if (fd != NULL) (void) Fclose(fd);
00225     /*@=usereleased@*/
00226     return 1;
00227 }
00228 
00229 char * currentDirectory(void)
00230 {
00231     int currDirLen = 0;
00232     char * currDir = NULL;
00233 
00234     do {
00235         currDirLen += 128;
00236         currDir = xrealloc(currDir, currDirLen);
00237         memset(currDir, 0, currDirLen);
00238     } while (getcwd(currDir, currDirLen) == NULL && errno == ERANGE);
00239 
00240     return currDir;
00241 }
00242 
00243 /*
00244  * XXX This is a "dressed" entry to headerGetEntry to do:
00245  *      1) DIRNAME/BASENAME/DIRINDICES -> FILENAMES tag conversions.
00246  *      2) i18n lookaside (if enabled).
00247  */
00248 int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
00249         void **p, int_32 *c)
00250 {
00251     switch (tag) {
00252     case RPMTAG_OLDFILENAMES:
00253     {   const char ** fl = NULL;
00254         int count;
00255         rpmfiBuildFNames(h, RPMTAG_BASENAMES, &fl, &count);
00256         if (count > 0) {
00257             *p = fl;
00258             if (c)      *c = count;
00259             if (type)   *type = RPM_STRING_ARRAY_TYPE;
00260             return 1;
00261         }
00262         if (c)  *c = 0;
00263         return 0;
00264     }   /*@notreached@*/ break;
00265 
00266     case RPMTAG_GROUP:
00267     case RPMTAG_DESCRIPTION:
00268     case RPMTAG_SUMMARY:
00269     {   char fmt[128];
00270         const char * msgstr;
00271         const char * errstr;
00272 
00273         fmt[0] = '\0';
00274         (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tagName(tag)), "}\n");
00275 
00276         /* XXX FIXME: memory leak. */
00277         msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00278         if (msgstr) {
00279             *p = (void *) msgstr;
00280             if (type)   *type = RPM_STRING_TYPE;
00281             if (c)      *c = 1;
00282             return 1;
00283         } else {
00284             if (c)      *c = 0;
00285             return 0;
00286         }
00287     }   /*@notreached@*/ break;
00288 
00289     default:
00290         return headerGetEntry(h, tag, type, p, c);
00291         /*@notreached@*/ break;
00292     }
00293     /*@notreached@*/
00294 }

Generated on Fri Oct 12 08:44:53 2007 for rpm by  doxygen 1.5.2