1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "fileops.h"
5 #include <sys/stat.h>
6 #if defined(_MSC_VER)
7 # include <sys/utime.h>
8 #else
9 # include <utime.h>
10 #endif
11 #if !defined(_WIN32)
12 # include <unistd.h>
13 #else
14 # include <io.h>
15 #endif
16 #if !defined(S_ISLNK)
17 # define lstat (stat)
18 # define S_ISLNK(m) (0)
19 #endif
20
21 /*
22
23 copyright (c) 2003, 2005, 2006 squell <squell@alumina.nl>
24
25 use, modification, copying and distribution of this software is permitted
26 under the conditions described in the file 'COPYING'.
27
28 */
29
fcopy(FILE * dest,FILE * src)30 int fcopy(FILE *dest, FILE *src)
31 {
32 char buffer[0x4000]; /* 16kb buffer */
33 size_t r, w;
34
35 do {
36 r = fread (buffer, 1, sizeof buffer, src);
37 w = fwrite(buffer, 1, r, dest);
38 if(w != r) return 0;
39 } while(r == sizeof buffer);
40
41 return feof(src);
42 }
43
fpadd(char c,size_t len,FILE * dest)44 size_t fpadd(char c, size_t len, FILE *dest)
45 {
46 char buffer[0x4000]; /* 16kb buffer */
47 size_t w;
48
49 memset(buffer, c, sizeof buffer);
50
51 while(len > sizeof buffer) {
52 w = fwrite(buffer, sizeof buffer, 1, dest);
53 if(w!=1) return 0;
54 len -= sizeof buffer;
55 }
56
57 w = fwrite(buffer, 1, len, dest);
58
59 return w;
60 }
61
ftemp(char * templ,const char * mode)62 FILE *ftemp(char *templ, const char *mode)
63 {
64 FILE *f;
65 #if defined(__DJGPP__) || defined(_WIN32)
66 FILE *fc;
67 if(mktemp(templ) && (fc = fopen(templ, "wb+"))) {
68 if(f = freopen(templ, mode, fc)) return f;
69 fclose(fc);
70 #else
71 int fd = mkstemp(templ);
72 if(fd >= 0) {
73 FILE* fdopen(); /* in case -ansi is used */
74 if(f = fdopen(fd, mode)) return f;
75 close(fd);
76 #endif
77 unlink(templ);
78 }
79 return 0;
80 }
81
82 FILE *opentemp(const char *hint, char **name) /* free() name! */
83 {
84 static const char template[] = "idXXXXXX";
85
86 char *buf, *dirsep = strrchr(hint, '/');
87 size_t prefix = dirsep? dirsep-hint+1 : 0;
88 FILE *f;
89
90 if(buf = malloc(prefix + sizeof template)) {
91 strncpy(buf, hint, prefix);
92 strncpy(buf+prefix, template, sizeof template);
93 if(f = ftemp(buf, "wb")) {
94 if(name) *name = buf;
95 else free(buf);
96 return f;
97 }
98 free(buf);
99 }
100
101 return 0;
102 }
103
104 /* ==================================================== */
105
106 int cpfile(const char *srcnam, const char *dstnam)
107 {
108 FILE *src, *dst;
109 int result = 0;
110
111 if(src = fopen(srcnam, "rb")) {
112 if(dst = fopen(dstnam, "wb")) {
113 result = fcopy(dst, src);
114 if(fclose(dst) != 0) result = 0;
115 }
116 fclose(src);
117 }
118 return result;
119 }
120
121 int mvfile(const char *srcnam, const char *dstnam)
122 {
123 struct stat fs;
124 int file = 0, slow = 0;
125
126 if(lstat(dstnam, &fs) == 0) {
127 file = !S_ISLNK(fs.st_mode);
128 slow = fs.st_nlink > 1 || !file; /* honour links */
129 slow = slow || remove(dstnam) != 0;
130 }
131 if(slow || rename(srcnam, dstnam) != 0) {
132 struct utimbuf buf, *stamp = 0;
133 struct stat ss;
134 if(stat(srcnam, &ss) == 0) {
135 stamp = &buf; /* preserve file time */
136 buf.actime = ss.st_atime;
137 buf.modtime = ss.st_mtime;
138 }
139 if(!cpfile(srcnam, dstnam))
140 return 0; /* could not rename, could not copy - give up */
141 (void) remove(srcnam); /* dont check result */
142 (void) utime(dstnam, stamp);
143 }
144 if(file)
145 (void) chmod(dstnam, fs.st_mode);
146 return 1; /* successful rename (or copy) */
147 }
148
149