1 2 3 /* This version of microEmacs is based on the public domain C 4 * version written by Dave G. Conroy. 5 * The D programming language version is written by Walter Bright. 6 * http://www.digitalmars.com/d/ 7 * This program is in the public domain. 8 */ 9 10 /* 11 * The routines in this file read and write ASCII files from the disk. All of 12 * the knowledge about files are here. A better message writing scheme should 13 * be used. 14 */ 15 16 module fileio; 17 18 import core.stdc.stdio; 19 import core.stdc.stdlib; 20 import core.stdc.errno; 21 22 import std.file; 23 import std.path; 24 import std..string; 25 import std.stdio; 26 import std.conv; 27 28 version (Windows) 29 { 30 import core.sys.windows.windows; 31 } 32 33 version (Posix) 34 { 35 import core.sys.posix.unistd; 36 import core.sys.posix.sys.stat; 37 } 38 39 import ed; 40 import display; 41 42 enum ENOENT = 2; 43 44 enum 45 { 46 FIOSUC = 0, /* File I/O, success. */ 47 FIOFNF = 1, /* File I/O, file not found. */ 48 FIOEOF = 2, /* File I/O, end of file. */ 49 FIOERR = 3, /* File I/O, error. */ 50 } 51 52 /*************************** 53 * Determine if file is read-only. 54 */ 55 56 bool ffreadonly(string name) 57 { 58 uint a; 59 bool exists = true; 60 try 61 { 62 a = std.file.getAttributes(name); 63 } 64 catch (Throwable o) 65 { 66 exists = false; 67 } 68 69 version (Win32) 70 { 71 return (a & FILE_ATTRIBUTE_READONLY) != 0; 72 } 73 else 74 { 75 return exists && (a & S_IWUSR) == 0; 76 } 77 } 78 79 /* 80 * Rename a file 81 */ 82 int ffrename(string from, string to) 83 { 84 try 85 { 86 from = std.path.expandTilde(from); 87 to = std.path.expandTilde(to); 88 version (Posix) 89 { 90 stat_t buf; 91 if( stat( toStringz(from), &buf ) != -1 92 && !(buf.st_uid == getuid() && (buf.st_mode & octal!200)) 93 && !(buf.st_gid == getgid() && (buf.st_mode & octal!20)) 94 && !( (buf.st_mode & octal!2)) ) 95 { 96 mlwrite("Cannot open file for writing."); 97 /* Note the above message is a lie, but because this */ 98 /* routine is only called by the backup file creation */ 99 /* code, the message will look right to the user. */ 100 return( FIOERR ); 101 } 102 } 103 rename( from, to ); 104 } 105 catch (Throwable o) 106 { 107 } 108 return( FIOSUC ); 109 } 110 111 112 /* 113 * Change the protection on a file <subject> to match that on file <image> 114 */ 115 int ffchmod(string subject, string image) 116 { 117 version (Posix) 118 { 119 subject = std.path.expandTilde(subject); 120 image = std.path.expandTilde(image); 121 122 uint attr; 123 try 124 { 125 attr = std.file.getAttributes(image); 126 } 127 catch (FileException fe) 128 { 129 return( FIOSUC ); 130 /* Note that this won't work in all cases, but because */ 131 /* this is only called from the backup file creator, it */ 132 /* will work. UGLY!! */ 133 } 134 if (chmod( toStringz(subject), attr ) == -1 ) 135 { 136 mlwrite("Cannot open file for writing."); 137 /* Note the above message is a lie, but because this */ 138 /* routine is only called by the backup file creation */ 139 /* code, the message will look right to the user. */ 140 return( FIOERR ); 141 } 142 } 143 return( FIOSUC ); 144 } 145