1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: dk4filei.ctr
12 */
13 
14 /**	@file dk4filei.c The dk4filei module.
15 */
16 
17 
18 #include "dk4conf.h"
19 #include <libdk4c/dk4filei.h>
20 
21 #ifndef DK4MEM_H_INCLUDED
22 #include <libdk4base/dk4mem.h>
23 #endif
24 
25 #ifndef DK4MAADU_H_INCLUDED
26 #include <libdk4ma/dk4maadu.h>
27 #endif
28 
29 
30 #include <libdk4base/dk4unused.h>
31 
32 #if DK4_HAVE_ASSERT_H
33 #ifndef	ASSERT_H_INCLUDED
34 #include <assert.h>
35 #define	ASSERT_H_INCLUDED 1
36 #endif
37 #endif
38 
39 
40 
41 
42 
43 
44 
45 void
dk4fileinfo_init(dk4_file_info_t * dptr)46 dk4fileinfo_init(dk4_file_info_t *dptr)
47 {
48 #if	DK4_USE_ASSERT
49   assert(NULL != dptr);
50 #endif
51   if (NULL != dptr) {
52     DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
53     dptr->contents = 0;
54   }
55 }
56 
57 
58 
59 int
dk4fileinfo_is_symlink(const dk4_file_info_t * dptr)60 dk4fileinfo_is_symlink(const dk4_file_info_t *dptr)
61 {
62   int		 back = 0;
63 #if	DK4_USE_ASSERT
64   assert(NULL != dptr);
65 #endif
66   if (NULL != dptr) {
67     if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (dptr->contents))) {
68 #if DK4_ON_WINDOWS
69       if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & (dptr->fattr))) {
70         if (IO_REPARSE_TAG_MOUNT_POINT == dptr->rppnt) {
71 	  back = 1;
72 	}
73 	if (IO_REPARSE_TAG_SYMLINK == dptr->rppnt) {
74 	  back = 1;
75 	}
76       }
77 #else
78 #if defined(S_IFMT) && defined (S_IFLNK)
79       if (S_IFLNK == (S_IFMT & ((dptr->lstb).st_mode))) {
80         back = 1;
81       }
82 #endif
83 #endif
84     }
85   }
86   return back;
87 }
88 
89 
90 
91 #if DK4_ON_WINDOWS
92 static
93 int
dk4fileinfo_copy_size(dk4_um_t * dptr,const BY_HANDLE_FILE_INFORMATION * bhfi,dk4_er_t * erp)94 dk4fileinfo_copy_size(
95   dk4_um_t				*dptr,
96   const BY_HANDLE_FILE_INFORMATION	*bhfi,
97   dk4_er_t				*erp
98 )
99 {
100   dk4_er_t	 er;
101   dk4_um_t	 val;
102   int	 	 back = 0;
103 
104 #if	DK4_USE_ASSERT
105   assert(NULL != dptr);
106   assert(NULL != bhfi);
107 #endif
108   dk4error_init(&er);
109 
110 
111   if ((DWORD)0UL != bhfi->nFileSizeHigh) {
112     val = dk4ma_um_add(
113       dk4ma_um_mul(
114         dk4ma_um_add(
115           (dk4_um_t)0xFFFFFFFFUL,
116 	  (dk4_um_t)1UL,
117 	  &er
118         ),
119         (dk4_um_t)(bhfi->nFileSizeHigh),
120         &er
121       ),
122       (dk4_um_t)(bhfi->nFileSizeLow),
123       &er
124     );
125   } else {
126     val = (dk4_um_t)(bhfi->nFileSizeLow);
127   }
128   if (DK4_E_NONE == er.ec) {
129     back = 1;
130     *dptr = val;
131   } else {
132     dk4error_copy(erp, &er);
133   }
134 
135   return back;
136 }
137 #else
138 static
139 int
dk4fileinfo_copy_size(dk4_um_t * dptr,const dk4_stat_t * stb,dk4_er_t * DK4_ARG_UNUSED (erp))140 dk4fileinfo_copy_size(
141   dk4_um_t				*dptr,
142   const dk4_stat_t			*stb,
143   dk4_er_t				* DK4_ARG_UNUSED(erp)
144 )
145 {
146   DK4_UNUSED_ARG(erp)
147 #if	DK4_USE_ASSERT
148   assert(NULL != dptr);
149   assert(NULL != stb);
150 #endif
151   *dptr = (dk4_um_t)(stb->st_size);
152   return 1;
153 }
154 #endif
155 
156 
157 int
dk4fileinfo_size(dk4_um_t * dptr,const dk4_file_info_t * fi,int ch,dk4_er_t * erp)158 dk4fileinfo_size(
159   dk4_um_t		*dptr,
160   const dk4_file_info_t *fi,
161   int			 ch,
162   dk4_er_t		*erp
163 )
164 {
165   dk4_er_t	 er;
166   int		 back = 0;
167 
168 #if	DK4_USE_ASSERT
169   assert(NULL != dptr);
170   assert(NULL != fi);
171 #endif
172   if ((NULL != dptr) && (NULL != fi)) {
173     dk4error_init(&er);
174     switch (ch) {
175       case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
176 
177         if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_LINK)) {
178 #if DK4_ON_WINDOWS
179 
180 	  back = dk4fileinfo_copy_size(dptr, &(fi->linfo), &er);
181 #else
182 
183 	  back = dk4fileinfo_copy_size(dptr, &(fi->lstb), &er);
184 #endif
185 	} else {
186 	  dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
187 	}
188       } break;
189       default: {
190 
191         if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_TARGET)) {
192 #if DK4_ON_WINDOWS
193 
194 	  back = dk4fileinfo_copy_size(dptr, &(fi->tinfo), &er);
195 #else
196 
197 	  back = dk4fileinfo_copy_size(dptr, &(fi->tstb), &er);
198 #endif
199 	} else {
200 	  dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
201 	}
202       } break;
203     }
204     if (0 != back) {
205       dk4error_copy(erp, &er);
206     }
207   } else {
208     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
209   }
210   return back;
211 }
212 
213 
214 
215 int
dk4fileinfo_exists_and_is_regular(const dk4_file_info_t * fi,dk4_er_t * erp)216 dk4fileinfo_exists_and_is_regular(const dk4_file_info_t *fi, dk4_er_t *erp)
217 {
218   int		 back = 0;
219 #if	DK4_USE_ASSERT
220   assert(NULL != fi);
221 #endif
222   if (NULL != fi) {
223 #if DK4_ON_WINDOWS
224     if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
225       if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & fi->fattr)) {
226         if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & fi->fattr)) {
227 	  back = 1;
228 	}
229       }
230     }
231 #else
232     if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
233       if (S_IFREG == (S_IFMT & ((fi->tstb).st_mode))) {
234         back = 1;
235       }
236     }
237 #endif
238   } else {
239     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
240   }
241   return back;
242 }
243 
244