1 /* $OpenBSD: dir.c,v 1.27 2014/04/03 20:17:12 lum Exp $ */ 2 3 /* This file is in the public domain. */ 4 5 /* 6 * Name: MG 2a 7 * Directory management functions 8 * Created: Ron Flax (ron@vsedev.vse.com) 9 * Modified for MG 2a by Mic Kaczmarczik 03-Aug-1987 10 */ 11 12 #include <sys/stat.h> 13 14 #include "def.h" 15 16 static char mgcwd[NFILEN]; 17 18 /* 19 * Initialize anything the directory management routines need. 20 */ 21 void 22 dirinit(void) 23 { 24 mgcwd[0] = '\0'; 25 if (getcwd(mgcwd, sizeof(mgcwd)) == NULL) { 26 ewprintf("Can't get current directory!"); 27 chdir("/"); 28 } 29 if (!(mgcwd[0] == '/' && mgcwd [1] == '\0')) 30 (void)strlcat(mgcwd, "/", sizeof(mgcwd)); 31 } 32 33 /* 34 * Change current working directory. 35 */ 36 /* ARGSUSED */ 37 int 38 changedir(int f, int n) 39 { 40 char bufc[NFILEN], *bufp; 41 42 (void)strlcpy(bufc, mgcwd, sizeof(bufc)); 43 if ((bufp = eread("Change default directory: ", bufc, NFILEN, 44 EFDEF | EFNEW | EFCR | EFFILE)) == NULL) 45 return (ABORT); 46 else if (bufp[0] == '\0') 47 return (FALSE); 48 /* Append trailing slash */ 49 if (chdir(bufc) == -1) { 50 dobeep(); 51 ewprintf("Can't change dir to %s", bufc); 52 return (FALSE); 53 } 54 if ((bufp = getcwd(mgcwd, sizeof(mgcwd))) == NULL) 55 panic("Can't get current directory!"); 56 if (mgcwd[strlen(mgcwd) - 1] != '/') 57 (void)strlcat(mgcwd, "/", sizeof(mgcwd)); 58 ewprintf("Current directory is now %s", bufp); 59 return (TRUE); 60 } 61 62 /* 63 * Show current directory. 64 */ 65 /* ARGSUSED */ 66 int 67 showcwdir(int f, int n) 68 { 69 ewprintf("Current directory: %s", mgcwd); 70 return (TRUE); 71 } 72 73 int 74 getcwdir(char *buf, size_t len) 75 { 76 if (strlcpy(buf, mgcwd, len) >= len) 77 return (FALSE); 78 79 return (TRUE); 80 } 81 82 /* Create the directory and it's parents. */ 83 /* ARGSUSED */ 84 int 85 makedir(int f, int n) 86 { 87 return (ask_makedir()); 88 } 89 90 int 91 ask_makedir(void) 92 { 93 94 char bufc[NFILEN]; 95 char *path; 96 97 if (getbufcwd(bufc, sizeof(bufc)) != TRUE) 98 return (ABORT); 99 if ((path = eread("Make directory: ", bufc, NFILEN, 100 EFDEF | EFNEW | EFCR | EFFILE)) == NULL) 101 return (ABORT); 102 else if (path[0] == '\0') 103 return (FALSE); 104 105 return (do_makedir(path)); 106 } 107 108 int 109 do_makedir(char *path) 110 { 111 struct stat sb; 112 int finished, ishere; 113 mode_t dir_mode, mode, oumask; 114 char *slash; 115 116 if ((path = adjustname(path, TRUE)) == NULL) 117 return (FALSE); 118 119 /* Remove trailing slashes */ 120 slash = strrchr(path, '\0'); 121 while (--slash > path && *slash == '/') 122 *slash = '\0'; 123 124 slash = path; 125 126 oumask = umask(0); 127 mode = 0777 & ~oumask; 128 dir_mode = mode | S_IWUSR | S_IXUSR; 129 130 for (;;) { 131 slash += strspn(slash, "/"); 132 slash += strcspn(slash, "/"); 133 134 finished = (*slash == '\0'); 135 *slash = '\0'; 136 137 ishere = !stat(path, &sb); 138 if (finished && ishere) { 139 dobeep(); 140 ewprintf("Cannot create directory %s: file exists", 141 path); 142 return(FALSE); 143 } else if (!finished && ishere && S_ISDIR(sb.st_mode)) { 144 *slash = '/'; 145 continue; 146 } 147 148 if (mkdir(path, finished ? mode : dir_mode) == 0) { 149 if (mode > 0777 && chmod(path, mode) < 0) { 150 umask(oumask); 151 return (ABORT); 152 } 153 } else { 154 if (!ishere || !S_ISDIR(sb.st_mode)) { 155 if (!ishere) { 156 dobeep(); 157 ewprintf("Creating directory: " 158 "permission denied, %s", path); 159 } else 160 eerase(); 161 162 umask(oumask); 163 return (FALSE); 164 } 165 } 166 167 if (finished) 168 break; 169 170 *slash = '/'; 171 } 172 173 eerase(); 174 umask(oumask); 175 return (TRUE); 176 } 177