Ejemplo n.º 1
0
int file_link(const char *src, const char *dest)
{
    struct stat dest_stat;
    int r;

    r = stat(dest, &dest_stat);
    if (r == 0) {
        r = unlink(dest);
        if (r < 0) {
            opkg_perror(ERROR, "unable to remove `%s'", dest);
            return -1;
        }
    } else if (errno != ENOENT) {
        opkg_perror(ERROR, "unable to stat `%s'", dest);
        return -1;
    }

    r = symlink(src, dest);
    if (r < 0) {
        opkg_perror(DEBUG, "unable to create symlink '%s', falling back to copy",
                    dest);
        return file_copy(src, dest);
    }

    return r;
}
Ejemplo n.º 2
0
static int copy_file_data(FILE * src_file, FILE * dst_file)
{
    size_t nread, nwritten;
    char buffer[BUFSIZ];

    while (1) {
        nread = fread(buffer, 1, BUFSIZ, src_file);

        if (nread != BUFSIZ && ferror(src_file)) {
            opkg_perror(ERROR, "read");
            return -1;
        }

        /* Check for EOF. */
        if (nread == 0)
            return 0;

        nwritten = fwrite(buffer, 1, nread, dst_file);

        if (nwritten != nread) {
            if (ferror(dst_file))
                opkg_perror(ERROR, "write");
            else
                opkg_msg(ERROR, "Unable to write all data.\n");
            return -1;
        }
    }
}
Ejemplo n.º 3
0
int file_mkdir_hier(const char *path, long mode)
{
    struct stat st;
    int r;

    r = stat(path, &st);
    if (r < 0 && errno == ENOENT) {
        int status;
        char *parent;

        parent = xdirname(path);
        status = file_mkdir_hier(parent, mode | 0300);
        free(parent);

        if (status < 0)
            return -1;

        r = mkdir(path, 0777);
        if (r < 0) {
            opkg_perror(ERROR, "Cannot create directory `%s'", path);
            return -1;
        }

        if (mode != -1) {
            r = chmod(path, mode);
            if (r < 0) {
                opkg_perror(ERROR, "Cannot set permissions of directory `%s'",
                            path);
                return -1;
            }
        }
    }

    return 0;
}
Ejemplo n.º 4
0
extern void *xcalloc(size_t nmemb, size_t size)
{
    void *ptr = calloc(nmemb, size);
    if (ptr == NULL && nmemb != 0 && size != 0) {
        opkg_perror(ERROR, "calloc");
        exit(EXIT_FAILURE);
    }
    return ptr;
}
Ejemplo n.º 5
0
extern void *xrealloc(void *ptr, size_t size)
{
    ptr = realloc(ptr, size);
    if (ptr == NULL && size != 0) {
        opkg_perror(ERROR, "realloc");
        exit(EXIT_FAILURE);
    }
    return ptr;
}
Ejemplo n.º 6
0
extern void *xmalloc(size_t size)
{
    void *ptr = malloc(size);
    if (ptr == NULL && size != 0) {
        opkg_perror(ERROR, "malloc");
        exit(EXIT_FAILURE);
    }
    return ptr;
}
Ejemplo n.º 7
0
/* Like system(3), but with error messages printed if the fork fails
   or if the child process dies due to an uncaught signal. Also, the
   return value is a bit simpler:

   -1 if there was any problem
   Otherwise, the 8-bit return value of the program ala WEXITSTATUS
   as defined in <sys/wait.h>.
*/
int
xsystem(const char *argv[])
{
	int status;
	pid_t pid;

	pid = vfork();

	switch (pid) {
	case -1:
		opkg_perror(ERROR, "%s: vfork", argv[0]);
		return -1;
	case 0:
		/* child */
		execvp(argv[0], (char*const*)argv);
		_exit(-1);
	default:
		/* parent */
		break;
	}

	if (waitpid(pid, &status, 0) == -1) {
		opkg_perror(ERROR, "%s: waitpid", argv[0]);
		return -1;
	}

	if (WIFSIGNALED(status)) {
		opkg_msg(ERROR, "%s: Child killed by signal %d.\n",
			argv[0], WTERMSIG(status));
		return -1;
	}

	if (!WIFEXITED(status)) {
		/* shouldn't happen */
		opkg_msg(ERROR, "%s: Your system is broken: got status %d "
			"from waitpid.\n", argv[0], status);
		return -1;
	}

	return WEXITSTATUS(status);
}
Ejemplo n.º 8
0
unsigned long get_available_kbytes(char *filesystem)
{
    int r;
#ifdef HAVE_STATVFS
    struct statvfs f;

    r = statvfs(filesystem, &f);
    if (r == -1) {
        opkg_perror(ERROR, "Failed to statvfs for %s", filesystem);
        return 0;
    }
    // Actually ((sfs.f_bavail * sfs.f_frsize) / 1024)
    // and here we try to avoid overflow.
    if (f.f_frsize >= 1024)
        return (f.f_bavail * (f.f_frsize / 1024));
    else if (f.f_frsize > 0)
        return f.f_bavail / (1024 / f.f_frsize);
#else
    struct statfs f;

    r = statfs(filesystem, &f);
    if (r < 0) {
        opkg_perror(ERROR, "Failed to statfs for %s", filesystem);
        return 0;
    }
    // Actually ((sfs.f_bavail * sfs.f_bsize) / 1024)
    // and here we try to avoid overflow.
    if (f.f_bsize >= 1024)
        return (f.f_bavail * (f.f_bsize / 1024));
    else if (f.f_bsize > 0)
        return f.f_bavail / (1024 / f.f_bsize);
#endif
    opkg_msg(ERROR, "Unknown block size for target filesystem.\n");

    return 0;
}
Ejemplo n.º 9
0
extern char *xstrdup(const char *s)
{
    char *t;

    if (s == NULL)
        return NULL;

    t = strdup(s);

    if (t == NULL) {
        opkg_perror(ERROR, "strdup");
        exit(EXIT_FAILURE);
    }

    return t;
}
Ejemplo n.º 10
0
char *file_sha256sum_alloc(const char *file_name)
{
    static const int sha256sum_bin_len = 32;
    static const int sha256sum_hex_len = 64;

    static const unsigned char bin2hex[16] = {
        '0', '1', '2', '3',
        '4', '5', '6', '7',
        '8', '9', 'a', 'b',
        'c', 'd', 'e', 'f'
    };

    int i, err;
    FILE *file;
    char *sha256sum_hex;
    unsigned char sha256sum_bin[sha256sum_bin_len];

    sha256sum_hex = xcalloc(1, sha256sum_hex_len + 1);

    file = fopen(file_name, "r");
    if (file == NULL) {
        opkg_perror(ERROR, "Failed to open file %s", file_name);
        free(sha256sum_hex);
        return NULL;
    }

    err = sha256_stream(file, sha256sum_bin);
    if (err) {
        opkg_msg(ERROR, "Could't compute sha256sum for %s.\n", file_name);
        fclose(file);
        free(sha256sum_hex);
        return NULL;
    }

    fclose(file);

    for (i = 0; i < sha256sum_bin_len; i++) {
        sha256sum_hex[i * 2] = bin2hex[sha256sum_bin[i] >> 4];
        sha256sum_hex[i * 2 + 1] = bin2hex[sha256sum_bin[i] & 0xf];
    }

    sha256sum_hex[sha256sum_hex_len] = '\0';

    return sha256sum_hex;
}
Ejemplo n.º 11
0
int file_move(const char *src, const char *dest)
{
    int err;

    err = rename(src, dest);
    if (err == -1) {
        if (errno == EXDEV) {
            /* src & dest live on different file systems */
            err = file_copy(src, dest);
            if (err == 0)
                unlink(src);
        } else {
            opkg_perror(ERROR, "Failed to rename %s to %s", src, dest);
        }
    }

    return err;
}
Ejemplo n.º 12
0
extern char *xstrndup(const char *s, int n)
{
    char *t;
    size_t len;

    if (s == NULL)
        return NULL;

    len = strlen (s);
    if (n < len)
        len = n;

    t = (char*) malloc (len + 1);
    if (t == NULL) {
        opkg_perror(ERROR, "strdup");
        exit(EXIT_FAILURE);
    }
    memcpy (t, s, len);
    t[len] = '\0';

    return t;
}
Ejemplo n.º 13
0
char *file_sha256sum_alloc(const char *file_name)
{
    int err;
    FILE *file;
    unsigned char sha256sum_bin[32];

    file = fopen(file_name, "r");
    if (file == NULL) {
        opkg_perror(ERROR, "Failed to open file %s", file_name);
        return NULL;
    }

    err = sha256_stream(file, sha256sum_bin);
    if (err) {
        opkg_msg(ERROR, "Could't compute sha256sum for %s.\n", file_name);
        fclose(file);
        return NULL;
    }

    fclose(file);

    return sha256_to_string(sha256sum_bin);
}
Ejemplo n.º 14
0
char *file_md5sum_alloc(const char *file_name)
{
    int err;
    FILE *file;
    unsigned char md5sum_bin[16];

    file = fopen(file_name, "r");
    if (file == NULL) {
        opkg_perror(ERROR, "Failed to open file %s", file_name);
        return NULL;
    }

    err = md5_stream(file, md5sum_bin);
    if (err) {
        opkg_msg(ERROR, "Could't compute md5sum for %s.\n", file_name);
        fclose(file);
        return NULL;
    }

    fclose(file);

    return md5_to_string(md5sum_bin);
}
Ejemplo n.º 15
0
int rm_r(const char *path)
{
    int ret = 0;
    DIR *dir;
    struct dirent *dent;
    int r;

    if (path == NULL) {
        opkg_perror(ERROR, "Missing directory parameter");
        return -1;
    }

    dir = opendir(path);
    if (dir == NULL) {
        opkg_perror(ERROR, "Failed to open dir %s", path);
        return -1;
    }

    r = fchdir(dirfd(dir));
    if (r == -1) {
        opkg_perror(ERROR, "Failed to change to dir %s", path);
        closedir(dir);
        return -1;
    }

    while (1) {
        errno = 0;
        dent = readdir(dir);
        if (dent == NULL) {
            if (errno) {
                opkg_perror(ERROR, "Failed to read dir %s", path);
                ret = -1;
            }
            break;
        }

        if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
            continue;

#ifdef _BSD_SOURCE
        if (dent->d_type == DT_DIR) {
            ret = rm_r(dent->d_name);
            if (ret == -1)
                break;
            continue;
        } else if (dent->d_type == DT_UNKNOWN)
#endif
        {
            struct stat st;
            ret = lstat(dent->d_name, &st);
            if (ret == -1) {
                opkg_perror(ERROR, "Failed to lstat %s", dent->d_name);
                break;
            }
            if (S_ISDIR(st.st_mode)) {
                ret = rm_r(dent->d_name);
                if (ret == -1)
                    break;
                continue;
            }
        }

        ret = unlink(dent->d_name);
        if (ret == -1) {
            opkg_perror(ERROR, "Failed to unlink %s", dent->d_name);
            break;
        }
    }

    r = chdir("..");
    if (r == -1) {
        ret = -1;
        opkg_perror(ERROR, "Failed to change to dir %s/..", path);
    }

    r = rmdir(path);
    if (r == -1) {
        ret = -1;
        opkg_perror(ERROR, "Failed to remove dir %s", path);
    }

    r = closedir(dir);
    if (r == -1) {
        ret = -1;
        opkg_perror(ERROR, "Failed to close dir %s", path);
    }

    return ret;
}
Ejemplo n.º 16
0
int
opkg_download(const char *src, const char *dest_file_name,
	curl_progress_func cb, void *data, const short hide_error)
{
    int err = 0;

    char *src_basec = xstrdup(src);
    char *src_base = basename(src_basec);
    char *tmp_file_location;

    opkg_msg(NOTICE,"Downloading %s.\n", src);

    if (str_starts_with(src, "file:")) {
	const char *file_src = src + 5;
	opkg_msg(INFO, "Copying %s to %s...", file_src, dest_file_name);
	err = file_copy(file_src, dest_file_name);
	opkg_msg(INFO, "Done.\n");
        free(src_basec);
	return err;
    }

    sprintf_alloc(&tmp_file_location, "%s/%s", conf->tmp_dir, src_base);
    free(src_basec);
    err = unlink(tmp_file_location);
    if (err && errno != ENOENT) {
	opkg_perror(ERROR, "Failed to unlink %s", tmp_file_location);
	free(tmp_file_location);
	return -1;
    }

    if (conf->http_proxy) {
	opkg_msg(DEBUG, "Setting environment variable: http_proxy = %s.\n",
		conf->http_proxy);
	setenv("http_proxy", conf->http_proxy, 1);
    }
    if (conf->ftp_proxy) {
	opkg_msg(DEBUG, "Setting environment variable: ftp_proxy = %s.\n",
		conf->ftp_proxy);
	setenv("ftp_proxy", conf->ftp_proxy, 1);
    }
    if (conf->no_proxy) {
	opkg_msg(DEBUG,"Setting environment variable: no_proxy = %s.\n",
		conf->no_proxy);
	setenv("no_proxy", conf->no_proxy, 1);
    }

#ifdef HAVE_CURL
    CURLcode res;
    FILE * file = fopen (tmp_file_location, "w");

    curl = opkg_curl_init (cb, data);
    if (curl)
    {
	curl_easy_setopt (curl, CURLOPT_URL, src);
	curl_easy_setopt (curl, CURLOPT_WRITEDATA, file);

	res = curl_easy_perform (curl);
	fclose (file);
	if (res)
	{
	    long error_code;
	    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &error_code);
	    opkg_msg(hide_error?DEBUG2:ERROR, "Failed to download %s: %s.\n",
		    src, curl_easy_strerror(res));
	    free(tmp_file_location);
	    return -1;
	}

    }
    else
    {
	free(tmp_file_location);
	return -1;
    }
#else
    {
      int res;
      const char *argv[8];
      int i = 0;

      argv[i++] = "wget";
      argv[i++] = "-q";
      if (conf->http_proxy || conf->ftp_proxy) {
	argv[i++] = "-Y";
	argv[i++] = "on";
      }
      argv[i++] = "-O";
      argv[i++] = tmp_file_location;
      argv[i++] = src;
      argv[i++] = NULL;
      res = xsystem(argv);

      if (res) {
	opkg_msg(ERROR, "Failed to download %s, wget returned %d.\n", src, res);
	free(tmp_file_location);
	return -1;
      }
    }
#endif

    err = file_move(tmp_file_location, dest_file_name);

    free(tmp_file_location);

    return err;
}
Ejemplo n.º 17
0
int
parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
						char **buf0, size_t buf0len)
{
	int ret, lineno;
	char *buf, *nl;
	size_t buflen;

	lineno = 1;
	ret = 0;

	buflen = buf0len;
	buf = *buf0;
	buf[0] = '\0';

	while (1) {
		if (fgets(buf, (int)buflen, fp) == NULL) {
			if (ferror(fp)) {
				opkg_perror(ERROR, "fgets");
				ret = -1;
			} else if (strlen(*buf0) == buf0len-1) {
				opkg_msg(ERROR, "Missing new line character"
						" at end of file!\n");
				parse_line(item, *buf0, mask);
			}
			break;
		}

		nl = strchr(buf, '\n');
		if (nl == NULL) {
			if (strlen(buf) < buflen-1) {
				/*
				 * Line could be exactly buflen-1 long and
				 * missing a newline, but we won't know until
				 * fgets fails to read more data.
				 */
				opkg_msg(ERROR, "Missing new line character"
						" at end of file!\n");
				parse_line(item, *buf0, mask);
				break;
			}
			if (buf0len >= EXCESSIVE_LINE_LEN) {
				opkg_msg(ERROR, "Excessively long line at "
					"%d. Corrupt file?\n",
					lineno);
				ret = -1;
				break;
			}

			/*
			 * Realloc and point buf past the data already read,
			 * at the NULL terminator inserted by fgets.
			 * |<--------------- buf0len ----------------->|
			 * |                     |<------- buflen ---->|
			 * |---------------------|---------------------|
			 * buf0                   buf
			 */
			buflen = buf0len +1;
			buf0len *= 2;
			*buf0 = xrealloc(*buf0, buf0len);
			buf = *buf0 + buflen -2;

			continue;
		}

		*nl = '\0';

		lineno++;

		if (parse_line(item, *buf0, mask))
			break;

		buf = *buf0;
		buflen = buf0len;
		buf[0] = '\0';
	}

	return ret;
}
Ejemplo n.º 18
0
int file_copy(const char *src, const char *dest)
{
    struct stat src_stat;
    struct stat dest_stat;
    int dest_exists = 1;
    int status = 0;
    int r;

    r = stat(src, &src_stat);
    if (r < 0) {
        opkg_perror(ERROR, "%s", src);
        return -1;
    }

    r = stat(dest, &dest_stat);
    if (r < 0) {
        if (errno != ENOENT) {
            opkg_perror(ERROR, "unable to stat `%s'", dest);
            return -1;
        }
        dest_exists = 0;
    } else {
        int is_same_file = (src_stat.st_rdev == dest_stat.st_rdev
                && src_stat.st_ino == dest_stat.st_ino);
        if (is_same_file) {
            opkg_msg(ERROR, "`%s' and `%s' are the same file.\n", src, dest);
            return -1;
        }
    }

    if (S_ISREG(src_stat.st_mode)) {
        FILE *sfp, *dfp;
        struct utimbuf times;

        if (dest_exists) {
            dfp = fopen(dest, "w");
            if (dfp == NULL) {
                r = unlink(dest);
                if (r < 0) {
                    opkg_perror(ERROR, "unable to remove `%s'", dest);
                    return -1;
                }
            }
        } else {
            int fd;

            fd = open(dest, O_WRONLY | O_CREAT, src_stat.st_mode);
            if (fd < 0) {
                opkg_perror(ERROR, "unable to open `%s'", dest);
                return -1;
            }
            dfp = fdopen(fd, "w");
            if (dfp == NULL) {
                if (fd >= 0)
                    close(fd);
                opkg_perror(ERROR, "unable to open `%s'", dest);
                return -1;
            }
        }

        sfp = fopen(src, "r");
        if (sfp) {
            r = copy_file_data(sfp, dfp);
            if (r < 0)
                status = -1;

            r = fclose(sfp);
            if (r < 0) {
                opkg_perror(ERROR, "unable to close `%s'", src);
                status = -1;
            }
        } else {
            opkg_perror(ERROR, "unable to open `%s'", src);
            status = -1;
        }

        r = fclose(dfp);
        if (r < 0) {
            opkg_perror(ERROR, "unable to close `%s'", dest);
            status = -1;
        }

        times.actime = src_stat.st_atime;
        times.modtime = src_stat.st_mtime;
        r = utime(dest, &times);
        if (r < 0)
            opkg_perror(ERROR, "unable to preserve times of `%s'", dest);

        r = chown(dest, src_stat.st_uid, src_stat.st_gid);
        if (r < 0) {
            src_stat.st_mode &= ~(S_ISUID | S_ISGID);
            opkg_perror(ERROR, "unable to preserve ownership of `%s'", dest);
        }

        r = chmod(dest, src_stat.st_mode);
        if (r < 0)
            opkg_perror(ERROR, "unable to preserve permissions of `%s'", dest);

        return status;
    } else if (S_ISBLK(src_stat.st_mode) || S_ISCHR(src_stat.st_mode)
               || S_ISSOCK(src_stat.st_mode)) {
        r = mknod(dest, src_stat.st_mode, src_stat.st_rdev);
        if (r < 0) {
            opkg_perror(ERROR, "unable to create `%s'", dest);
            return -1;
        }
    } else if (S_ISFIFO(src_stat.st_mode)) {
        r = mkfifo(dest, src_stat.st_mode);
        if (r < 0) {
            opkg_perror(ERROR, "cannot create fifo `%s'", dest);
            return -1;
        }
    } else if (S_ISDIR(src_stat.st_mode)) {
        opkg_msg(ERROR, "%s: omitting directory.\n", src);
        return -1;
    }

    opkg_msg(ERROR, "internal error: unrecognized file type.\n");
    return -1;
}