2000-08-28 03:27:03 +08:00
|
|
|
/**
|
|
|
|
* \file lib/misc.c
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-05-07 22:56:06 +08:00
|
|
|
|
2002-02-08 00:55:01 +08:00
|
|
|
/* just to put a marker in librpm.a */
|
|
|
|
const char * RPMVERSION = VERSION;
|
|
|
|
|
2007-10-28 13:05:12 +08:00
|
|
|
#include "rpmurl.h"
|
2007-10-28 13:32:05 +08:00
|
|
|
#include "rpmmacro.h" /* XXX for rpmGetPath */
|
2007-10-28 13:47:31 +08:00
|
|
|
#include "rpmlib.h"
|
2007-10-09 20:33:49 +08:00
|
|
|
#include "rpmerr.h"
|
1995-11-28 06:31:21 +08:00
|
|
|
#include "misc.h"
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1995-11-28 06:31:21 +08:00
|
|
|
|
2002-07-05 05:08:05 +08:00
|
|
|
rpmRC rpmMkdirPath (const char * dpath, const char * dname)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if ((rc = Stat(dpath, &st)) < 0) {
|
|
|
|
int ut = urlPath(dpath, NULL);
|
|
|
|
switch (ut) {
|
|
|
|
case URL_IS_PATH:
|
|
|
|
case URL_IS_UNKNOWN:
|
|
|
|
if (errno != ENOENT)
|
|
|
|
break;
|
2004-11-04 21:29:11 +08:00
|
|
|
case URL_IS_HTTPS:
|
2002-07-05 05:08:05 +08:00
|
|
|
case URL_IS_HTTP:
|
2004-11-04 21:29:11 +08:00
|
|
|
case URL_IS_FTP:
|
2002-07-05 05:08:05 +08:00
|
|
|
rc = Mkdir(dpath, 0755);
|
|
|
|
break;
|
|
|
|
case URL_IS_DASH:
|
2004-11-29 05:14:41 +08:00
|
|
|
case URL_IS_HKP:
|
2002-07-05 05:08:05 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rc < 0) {
|
2007-10-09 19:06:06 +08:00
|
|
|
rpmlog(RPMERR_CREATE, _("cannot create %%%s %s\n"), dname, dpath);
|
2002-07-05 05:08:05 +08:00
|
|
|
return RPMRC_FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((rc = Access(dpath, W_OK))) {
|
2007-10-09 19:06:06 +08:00
|
|
|
rpmlog(RPMERR_CREATE, _("cannot write to %%%s %s\n"), dname, dpath);
|
2002-07-05 05:08:05 +08:00
|
|
|
return RPMRC_FAIL;
|
|
|
|
}
|
|
|
|
return RPMRC_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
char ** splitString(const char * str, int length, char sep)
|
|
|
|
{
|
1999-01-07 01:33:50 +08:00
|
|
|
const char * source;
|
|
|
|
char * s, * dest;
|
1995-11-28 06:31:21 +08:00
|
|
|
char ** list;
|
|
|
|
int i;
|
|
|
|
int fields;
|
1999-11-27 05:58:42 +08:00
|
|
|
|
1999-09-21 11:22:53 +08:00
|
|
|
s = xmalloc(length + 1);
|
1999-11-27 05:58:42 +08:00
|
|
|
|
1995-11-28 06:31:21 +08:00
|
|
|
fields = 1;
|
|
|
|
for (source = str, dest = s, i = 0; i < length; i++, source++, dest++) {
|
|
|
|
*dest = *source;
|
|
|
|
if (*dest == sep) fields++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*dest = '\0';
|
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
list = xmalloc(sizeof(*list) * (fields + 1));
|
1995-11-28 06:31:21 +08:00
|
|
|
|
|
|
|
dest = s;
|
|
|
|
list[0] = dest;
|
|
|
|
i = 1;
|
|
|
|
while (i < fields) {
|
|
|
|
if (*dest == sep) {
|
|
|
|
list[i++] = dest + 1;
|
|
|
|
*dest = 0;
|
|
|
|
}
|
|
|
|
dest++;
|
|
|
|
}
|
|
|
|
|
|
|
|
list[i] = NULL;
|
|
|
|
|
2007-09-12 01:07:39 +08:00
|
|
|
/* FIX: list[i] is NULL */
|
1995-11-28 06:31:21 +08:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
void freeSplitString(char ** list)
|
|
|
|
{
|
2001-03-24 04:27:48 +08:00
|
|
|
list[0] = _free(list[0]);
|
|
|
|
list = _free(list);
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-14 04:11:31 +08:00
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
int doputenv(const char *str)
|
|
|
|
{
|
1996-12-24 22:01:56 +08:00
|
|
|
char * a;
|
1999-11-27 05:58:42 +08:00
|
|
|
|
1996-12-24 22:01:56 +08:00
|
|
|
/* FIXME: this leaks memory! */
|
1999-09-21 11:22:53 +08:00
|
|
|
a = xmalloc(strlen(str) + 1);
|
1996-12-24 22:01:56 +08:00
|
|
|
strcpy(a, str);
|
|
|
|
return putenv(a);
|
|
|
|
}
|
|
|
|
|
2001-06-18 06:18:03 +08:00
|
|
|
int dosetenv(const char * name, const char * value, int overwrite)
|
1999-11-27 05:58:42 +08:00
|
|
|
{
|
1996-12-24 22:01:56 +08:00
|
|
|
char * a;
|
|
|
|
|
|
|
|
if (!overwrite && getenv(name)) return 0;
|
|
|
|
|
2001-06-18 06:18:03 +08:00
|
|
|
/* FIXME: this leaks memory! */
|
|
|
|
a = xmalloc(strlen(name) + strlen(value) + sizeof("="));
|
|
|
|
(void) stpcpy( stpcpy( stpcpy( a, name), "="), value);
|
1996-12-24 22:01:56 +08:00
|
|
|
return putenv(a);
|
|
|
|
}
|
1997-02-14 10:05:13 +08:00
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr)
|
|
|
|
{
|
2007-08-31 14:55:06 +08:00
|
|
|
const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:" LOCALSTATEDIR "/tmp}";
|
1999-11-20 02:19:41 +08:00
|
|
|
const char * tempfn = NULL;
|
|
|
|
const char * tfn = NULL;
|
2000-12-20 01:43:56 +08:00
|
|
|
static int _initialized = 0;
|
1999-11-19 02:07:46 +08:00
|
|
|
int temput;
|
1999-11-27 05:58:42 +08:00
|
|
|
FD_t fd = NULL;
|
1997-08-29 03:13:54 +08:00
|
|
|
int ran;
|
|
|
|
|
|
|
|
if (!prefix) prefix = "";
|
|
|
|
|
2000-12-20 01:43:56 +08:00
|
|
|
/* Create the temp directory if it doesn't already exist. */
|
|
|
|
if (!_initialized) {
|
|
|
|
_initialized = 1;
|
|
|
|
tempfn = rpmGenPath(prefix, tpmacro, NULL);
|
2002-08-14 04:40:32 +08:00
|
|
|
if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
|
2000-12-20 01:43:56 +08:00
|
|
|
goto errxit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX should probably use mkstemp here */
|
1997-11-01 01:31:17 +08:00
|
|
|
srand(time(NULL));
|
|
|
|
ran = rand() % 100000;
|
1998-09-15 02:55:18 +08:00
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
/* maybe this should use link/stat? */
|
1998-09-15 02:55:18 +08:00
|
|
|
|
1997-08-29 03:13:54 +08:00
|
|
|
do {
|
1999-11-11 06:09:49 +08:00
|
|
|
char tfnbuf[64];
|
|
|
|
#ifndef NOTYET
|
|
|
|
sprintf(tfnbuf, "rpm-tmp.%d", ran++);
|
2001-03-24 04:27:48 +08:00
|
|
|
tempfn = _free(tempfn);
|
2000-12-20 01:43:56 +08:00
|
|
|
tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
|
1999-11-11 06:09:49 +08:00
|
|
|
#else
|
|
|
|
strcpy(tfnbuf, "rpm-tmp.XXXXXX");
|
2001-03-24 04:27:48 +08:00
|
|
|
tempfn = _free(tempfn);
|
2000-12-20 01:43:56 +08:00
|
|
|
tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
|
1999-11-11 06:09:49 +08:00
|
|
|
#endif
|
|
|
|
|
1999-11-19 02:07:46 +08:00
|
|
|
temput = urlPath(tempfn, &tfn);
|
1999-11-20 02:19:41 +08:00
|
|
|
if (*tfn == '\0') goto errxit;
|
|
|
|
|
1999-11-19 02:07:46 +08:00
|
|
|
switch (temput) {
|
1999-11-11 06:09:49 +08:00
|
|
|
case URL_IS_DASH:
|
2004-11-29 05:14:41 +08:00
|
|
|
case URL_IS_HKP:
|
1999-11-19 02:07:46 +08:00
|
|
|
goto errxit;
|
2007-09-12 01:07:39 +08:00
|
|
|
break;
|
2004-11-04 21:29:11 +08:00
|
|
|
case URL_IS_HTTPS:
|
|
|
|
case URL_IS_HTTP:
|
|
|
|
case URL_IS_FTP:
|
1999-11-01 05:38:21 +08:00
|
|
|
default:
|
2007-09-12 01:07:39 +08:00
|
|
|
break;
|
1999-11-01 05:38:21 +08:00
|
|
|
}
|
1999-11-13 01:20:49 +08:00
|
|
|
|
1999-11-20 02:19:41 +08:00
|
|
|
fd = Fopen(tempfn, "w+x.ufdio");
|
1999-11-27 05:58:42 +08:00
|
|
|
/* XXX FIXME: errno may not be correct for ufdio */
|
1999-11-11 06:09:49 +08:00
|
|
|
} while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
|
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
if (fd == NULL || Ferror(fd))
|
|
|
|
goto errxit;
|
|
|
|
|
1999-11-19 02:07:46 +08:00
|
|
|
switch(temput) {
|
|
|
|
case URL_IS_PATH:
|
|
|
|
case URL_IS_UNKNOWN:
|
2001-09-21 23:07:11 +08:00
|
|
|
{ struct stat sb, sb2;
|
1999-11-19 02:07:46 +08:00
|
|
|
if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
|
2007-10-09 19:06:06 +08:00
|
|
|
rpmlog(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
|
1999-11-19 02:07:46 +08:00
|
|
|
goto errxit;
|
|
|
|
}
|
1998-03-04 05:45:38 +08:00
|
|
|
|
1999-11-19 02:07:46 +08:00
|
|
|
if (sb.st_nlink != 1) {
|
2007-10-09 19:06:06 +08:00
|
|
|
rpmlog(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
|
1999-11-19 02:07:46 +08:00
|
|
|
goto errxit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fstat(Fileno(fd), &sb2) == 0) {
|
|
|
|
if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
|
2007-10-09 19:06:06 +08:00
|
|
|
rpmlog(RPMERR_SCRIPT, _("error creating temporary file %s\n"), tfn);
|
1999-11-19 02:07:46 +08:00
|
|
|
goto errxit;
|
|
|
|
}
|
1999-11-15 03:15:18 +08:00
|
|
|
}
|
2001-09-21 23:07:11 +08:00
|
|
|
} break;
|
1999-11-19 02:07:46 +08:00
|
|
|
default:
|
|
|
|
break;
|
1998-03-04 05:45:38 +08:00
|
|
|
}
|
|
|
|
|
1999-01-07 01:33:50 +08:00
|
|
|
if (fnptr)
|
1999-11-20 02:19:41 +08:00
|
|
|
*fnptr = tempfn;
|
2001-03-24 04:27:48 +08:00
|
|
|
else
|
|
|
|
tempfn = _free(tempfn);
|
1997-08-29 03:13:54 +08:00
|
|
|
*fdptr = fd;
|
|
|
|
|
|
|
|
return 0;
|
1999-11-19 02:07:46 +08:00
|
|
|
|
|
|
|
errxit:
|
2001-03-24 04:27:48 +08:00
|
|
|
tempfn = _free(tempfn);
|
2003-01-24 04:23:24 +08:00
|
|
|
if (fd != NULL) (void) Fclose(fd);
|
1999-11-19 02:07:46 +08:00
|
|
|
return 1;
|
1997-08-29 03:13:54 +08:00
|
|
|
}
|
1999-01-08 11:10:12 +08:00
|
|
|
|
1999-11-27 05:58:42 +08:00
|
|
|
char * currentDirectory(void)
|
|
|
|
{
|
2003-02-03 19:46:52 +08:00
|
|
|
int currDirLen = 0;
|
|
|
|
char * currDir = NULL;
|
1999-01-08 11:10:12 +08:00
|
|
|
|
2003-02-03 19:46:52 +08:00
|
|
|
do {
|
|
|
|
currDirLen += 128;
|
1999-09-21 11:22:53 +08:00
|
|
|
currDir = xrealloc(currDir, currDirLen);
|
2003-02-03 19:46:52 +08:00
|
|
|
memset(currDir, 0, currDirLen);
|
|
|
|
} while (getcwd(currDir, currDirLen) == NULL && errno == ERANGE);
|
1999-01-08 11:10:12 +08:00
|
|
|
|
|
|
|
return currDir;
|
|
|
|
}
|
1999-10-06 23:51:14 +08:00
|
|
|
|