[CABMAN] Second addendum to 7afc888: Use the old code to make Linux happy.
[reactos.git] / sdk / tools / cabman / CCFDATAStorage.cxx
1 /*
2 * PROJECT: ReactOS cabinet manager
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: CCFDATAStorage class implementation for Linux/Unix
5 * COPYRIGHT: Copyright 2017 Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * Copyright 2017 Colin Finck <mail@colinfinck.de>
7 * Copyright 2018 Dmitry Bagdanov <dimbo_job@mail.ru>
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14
15 #if !defined(_WIN32)
16 #include <dirent.h>
17 #endif
18
19 #include "cabinet.h"
20 #include "raw.h"
21 #include "mszip.h"
22
23 #if !defined(CAB_READ_ONLY)
24
25 /**
26 * @name CCFDATAStorage class
27 * @implemented
28 *
29 * Default constructor
30 */
31 CCFDATAStorage::CCFDATAStorage()
32 {
33 FileHandle = NULL;
34 }
35
36 /**
37 * @name CCFDATAStorage class
38 * @implemented
39 *
40 * Default destructor
41 */
42 CCFDATAStorage::~CCFDATAStorage()
43 {
44 ASSERT(FileHandle == NULL);
45 }
46
47 /**
48 * @name CCFDATAStorage class
49 * @implemented
50 *
51 * Creates the file
52 *
53 * @return
54 * Status of operation
55 */
56 ULONG CCFDATAStorage::Create()
57 {
58 #if defined(_WIN32)
59 char TmpName[PATH_MAX];
60 char *pName;
61 int length;
62
63 if (tmpnam(TmpName) == NULL)
64 return CAB_STATUS_CANNOT_CREATE;
65
66 /* Append 'tmp' if the file name ends with a dot */
67 length = strlen(TmpName);
68 if (length > 0 && TmpName[length - 1] == '.')
69 strcat(TmpName, "tmp");
70
71 /* Skip a leading slash or backslash */
72 pName = TmpName;
73 if (*pName == '/' || *pName == '\\')
74 pName++;
75
76 strcpy(FullName, pName);
77
78 FileHandle = fopen(FullName, "w+b");
79 if (FileHandle == NULL)
80 return CAB_STATUS_CANNOT_CREATE;
81 #else
82 if ((FileHandle = tmpfile()) == NULL)
83 return CAB_STATUS_CANNOT_CREATE;
84 #endif
85 return CAB_STATUS_SUCCESS;
86 }
87
88 /**
89 * @name CCFDATAStorage class
90 * @implemented
91 *
92 * Destroys the file
93 *
94 * @return
95 * Status of operation
96 */
97 ULONG CCFDATAStorage::Destroy()
98 {
99 ASSERT(FileHandle != NULL);
100
101 fclose(FileHandle);
102
103 FileHandle = NULL;
104
105 #if defined(_WIN32)
106 remove(FullName);
107 #endif
108
109 return CAB_STATUS_SUCCESS;
110 }
111
112 /**
113 * @name CCFDATAStorage class
114 * @implemented
115 *
116 * Truncate the scratch file to zero bytes
117 *
118 * @return
119 * Status of operation
120 */
121 ULONG CCFDATAStorage::Truncate()
122 {
123 fclose(FileHandle);
124 FileHandle = fopen(FullName, "w+b");
125 if (FileHandle == NULL)
126 {
127 DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
128 return CAB_STATUS_FAILURE;
129 }
130
131 return CAB_STATUS_SUCCESS;
132 }
133
134 /**
135 * @name CCFDATAStorage class
136 * @implemented
137 *
138 * Returns current position in file
139 *
140 * @return
141 * Current position
142 */
143 ULONG CCFDATAStorage::Position()
144 {
145 return (ULONG)ftell(FileHandle);
146 }
147
148
149 /**
150 * @name CCFDATAStorage class
151 * @implemented
152 *
153 * Seeks to an absolute position
154 *
155 * @param Position
156 * Absolute position to seek to
157 *
158 * @return
159 * Status of operation
160 */
161 ULONG CCFDATAStorage::Seek(LONG Position)
162 {
163 if (fseek(FileHandle, (off_t)Position, SEEK_SET) != 0)
164 return CAB_STATUS_FAILURE;
165 else
166 return CAB_STATUS_SUCCESS;
167 }
168
169
170 /**
171 * @name CCFDATAStorage class
172 * @implemented
173 *
174 * Reads a CFDATA block from the file
175 *
176 * @param Data
177 * Pointer to CFDATA block for the buffer
178 *
179 * @param Buffer
180 * Pointer to buffer to store data read
181 *
182 * @param BytesRead
183 * Pointer to buffer to write number of bytes read
184 *
185 * @return
186 * Status of operation
187 */
188 ULONG CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, PULONG BytesRead)
189 {
190 *BytesRead = fread(Buffer, 1, Data->CompSize, FileHandle);
191 if (*BytesRead != Data->CompSize)
192 return CAB_STATUS_CANNOT_READ;
193
194 return CAB_STATUS_SUCCESS;
195 }
196
197
198 /**
199 * @name CCFDATAStorage class
200 * @implemented
201 *
202 * Writes a CFDATA block to the file
203 *
204 * @param Data
205 * Pointer to CFDATA block for the buffer
206 *
207 * @param Buffer
208 * Pointer to buffer with data to write
209 *
210 * @param BytesWritten
211 * Pointer to buffer to write number of bytes written
212 *
213 * @return
214 * Status of operation
215 */
216 ULONG CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, PULONG BytesWritten)
217 {
218 *BytesWritten = fwrite(Buffer, 1, Data->CompSize, FileHandle);
219 if (*BytesWritten != Data->CompSize)
220 return CAB_STATUS_CANNOT_WRITE;
221
222 return CAB_STATUS_SUCCESS;
223 }
224
225
226 #endif /* CAB_READ_ONLY */