cpdir.c revision 20302
11558Srgrimes/*- 21558Srgrimes * Copyright (C) 1996 31558Srgrimes * David L. Nugent. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 141558Srgrimes * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 151558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 181558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241558Srgrimes * SUCH DAMAGE. 251558Srgrimes * 261558Srgrimes * $Id: cpdir.c,v 1.1.1.2 1996/12/09 23:55:15 joerg Exp $ 271558Srgrimes */ 281558Srgrimes 291558Srgrimes#include <stdio.h> 30114589Sobrien#include <string.h> 311558Srgrimes#include <stdlib.h> 3238036Scharnier#include <fcntl.h> 331558Srgrimes#include <sys/types.h> 341558Srgrimes#include <sys/stat.h> 351558Srgrimes#include <dirent.h> 361558Srgrimes#include <unistd.h> 371558Srgrimes#include <sys/param.h> 3841684Sbde#include <errno.h> 39114589Sobrien 4038036Scharnier#include "pwupd.h" 41114589Sobrien 42114589Sobrienvoid 431558Srgrimescopymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid) 441558Srgrimes{ 451558Srgrimes int rc = 0; 461558Srgrimes char src[MAXPATHLEN]; 471558Srgrimes char dst[MAXPATHLEN]; 481558Srgrimes 491558Srgrimes if (mkdir(dir, mode) != 0 && errno != EEXIST) { 5038036Scharnier sprintf(src, "mkdir(%s)", dir); 511558Srgrimes perror(src); 52114763Sobrien } else { 531558Srgrimes int infd, outfd; 541558Srgrimes struct stat st; 551558Srgrimes 561558Srgrimes static char counter = 0; 571558Srgrimes static char *copybuf = NULL; 581558Srgrimes 591558Srgrimes ++counter; 601558Srgrimes chown(dir, uid, gid); 611558Srgrimes if (skel == NULL || *skel == '\0') 621558Srgrimes rc = 1; 631558Srgrimes else { 641558Srgrimes DIR *d = opendir(skel); 651558Srgrimes 661558Srgrimes if (d != NULL) { 671558Srgrimes struct dirent *e; 681558Srgrimes 691558Srgrimes while ((e = readdir(d)) != NULL) { 70227081Sed char *p = e->d_name; 711558Srgrimes 721558Srgrimes sprintf(src, "%s/%s", skel, p); 7332399Salex if (stat(src, &st) == 0) { 7432399Salex if (strncmp(p, "dot.", 4) == 0) /* Conversion */ 7532399Salex p += 3; 7632399Salex sprintf(dst, "%s/%s", dir, p); 7732399Salex if (S_ISDIR(st.st_mode)) { /* Recurse for this */ 7832399Salex if (strcmp(e->d_name, ".") != 0 && strcmp(e->d_name, "..") != 0) 7932399Salex copymkdir(dst, src, (st.st_mode & 0777), uid, gid); 8032399Salex /* 8132399Salex * Note: don't propogate 'special' attributes 8232399Salex */ 8332399Salex } else if (S_ISREG(st.st_mode) && (outfd = open(dst, O_RDWR | O_CREAT | O_EXCL, st.st_mode)) != -1) { 8432399Salex if ((infd = open(src, O_RDONLY)) == -1) { 851558Srgrimes close(outfd); 861558Srgrimes remove(dst); 871558Srgrimes } else { 881558Srgrimes int b; 891558Srgrimes 901558Srgrimes /* 9148078Sru * Allocate our copy buffer if we need to 9279749Sdd */ 9379749Sdd if (copybuf == NULL) 941558Srgrimes copybuf = malloc(4096); 95197560Sdelphij while ((b = read(infd, copybuf, 4096)) > 0) 96238968Sdes write(outfd, copybuf, b); 97197560Sdelphij close(infd); 98197560Sdelphij close(outfd); 99197560Sdelphij chown(dst, uid, gid); 100197560Sdelphij } 101197560Sdelphij } 102197560Sdelphij } 103197560Sdelphij } 1041558Srgrimes closedir(d); 105140796Sdelphij } 106140796Sdelphij } 1071558Srgrimes if (--counter == 0 && copybuf != NULL) { 108140796Sdelphij free(copybuf); 1091558Srgrimes copybuf = NULL; 11079749Sdd } 1111558Srgrimes } 1121558Srgrimes} 1131558Srgrimes 1141558Srgrimes