Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

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

Generated on Tue Dec 28 15:13:22 2004 for rpm by doxygen 1.3.6