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