-// Ensure entire path exists.
-// If mode != -1 set permissions on newly created dirs.
-// Requires that path string be writable (for temporary null terminators).
-static
-void xmkpath(char *path, int mode)
-{
- char *p, old;
- mode_t mask;
- int rc;
- struct stat st;
-
- for (p = path; ; p++) {
- if (!*p || *p == '/') {
- old = *p;
- *p = rc = 0;
- if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
- if (mode != -1) {
- mask = umask(0);
- rc = mkdir(path, mode);
- umask(mask);
- } else rc = mkdir(path, 0777);
- }
- *p = old;
- if(rc) bb_perror_msg_and_die("mkpath '%s'", path);
- }
- if (!*p) break;
- }
-}
-
-// Slow, but small.
-static
-char *get_rawline(int fd, long *plen, char end)
-{
- char c, *buf = NULL;
- long len = 0;
-
- for (;;) {
- if (1>read(fd, &c, 1)) break;
- if (!(len & 63)) buf=xrealloc(buf, len+65);
- if ((buf[len++]=c) == end) break;
- }
- if (buf) buf[len]=0;
- if (plen) *plen = len;
-
- return buf;
-}
-
-static
-char *get_line(int fd)
-{
- long len;
- char *buf = get_rawline(fd, &len, '\n');
-
- if (buf && buf[--len]=='\n') buf[len]=0;
-
- return buf;
-}
-
-// Copy the rest of in to out and close both files.
-static
-void xsendfile(int in, int out)
-{
- long len;
- char buf[4096];
-
- if (in<0) return;
- for (;;) {
- len = safe_read(in, buf, 4096);
- if (len<1) break;
- xwrite(out, buf, len);
- }
-}
-
-// Copy the rest of the data and replace the original with the copy.
-static
-void replace_tempfile(int fdin, int fdout, char **tempname)
-{
- char *temp = xstrdup(*tempname);
-
- temp[strlen(temp)-6]=0;
- if (fdin != -1) {
- xsendfile(fdin, fdout);
- xclose(fdin);
- }
- xclose(fdout);
- rename(*tempname, temp);
- free(*tempname);
- free(temp);
- *tempname = NULL;
-}
-
-// Open a temporary file to copy an existing file into.
-static
-int copy_tempfile(int fdin, char *name, char **tempname)
-{
- struct stat statbuf;
- int fd;
-
- *tempname = xasprintf("%sXXXXXX", name);
- fd = xmkstemp(*tempname);
-
- // Set permissions of output file
- fstat(fdin, &statbuf);
- fchmod(fd, statbuf.st_mode);
-
- return fd;
-}
-
-// Abort the copy and delete the temporary file.
-static
-void delete_tempfile(int fdin, int fdout, char **tempname)
-{
- close(fdin);
- close(fdout);
- unlink(*tempname);
- free(*tempname);
- *tempname = NULL;
-}
-