1%%	options
2
3copyright owner	=	Dirk Krause
4copyright year	=	2015-xxxx
5SPDX-License-Identifier:	BSD-3-Clause
6
7
8
9%%	header
10
11/**	@file	dk4fileia.h	File information with application support.
12*/
13
14#ifndef	DK4CONF_H_INCLUDED
15#if DK4_BUILDING_DKTOOLS4
16#include "dk4conf.h"
17#else
18#include <dktools-4/dk4conf.h>
19#endif
20#endif
21
22#ifndef	DK4FILEIT_H_INCLUDED
23#if DK4_BUILDING_DKTOOLS4
24#include <libdk4c/dk4fileit.h>
25#else
26#include <dktools-4/dk4fileit.h>
27#endif
28#endif
29
30#ifndef	DK4APP_H_INCLUDED
31#if DK4_BUILDING_DKTOOLS4
32#include <libdk4app/dk4app.h>
33#else
34#include <dktools-4/dk4app.h>
35#endif
36#endif
37
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/**	Retrieve full information for a path name.
44	For symbolic links attempt to retrieve information both
45	about the link and about the link target.
46	@param	dptr	Pointer to result structure.
47	@param	fn	File path name.
48	@param	app	Application structure for diagnostics, may be NULL.
49	@return	1 if information is found, 0 otherwise.
50	If information about the link is found and no information about
51	the target, the function returns 1 as we can recognize the
52	directory item as a dangling link (link with non-existing target).
53*/
54int
55dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app);
56
57/**	Report errors from the stat() function.
58	@param	app	Application structure.
59	@param	path	Path name for which stat failed.
60	@param	errc	Error code from errno variable.
61*/
62void
63dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc);
64
65#if DK4_ON_WINDOWS
66/**	Report errors from Windows functions.
67	@param	app	Application structure.
68	@param	path	Path name for which the functions failed.
69	@param	errc	Error code from GetLastError().
70*/
71void
72dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc);
73#endif
74
75#ifdef __cplusplus
76}
77#endif
78
79
80%%	module
81
82#include "dk4conf.h"
83#include <libdk4base/dk4const.h>
84
85#if DK4_ON_WINDOWS
86#ifndef WINDOWS_H_INCLUDED
87#include <windows.h>
88#define WINDOWS_H_INCLUDED 1
89#endif
90#endif
91
92#if DK4_HAVE_ERRNO_H
93#ifndef ERRNO_H_INCLUDED
94#include <errno.h>
95#define	ERRNO_H_INCLUDED 1
96#endif
97#endif
98
99#include <libdk4c/dk4filei.h>
100#include <libdk4app/dk4fileia.h>
101#include <libdk4base/dk4error.h>
102#include <libdk4base/dk4mem.h>
103
104#if DK4_ON_WINDOWS
105#include <libdk4maiodd/dk4maodd.h>
106#include <libdk4maiodh/dk4maodh.h>
107#endif
108
109#if DK4_HAVE_ASSERT_H
110#ifndef	ASSERT_H_INCLUDED
111#include <assert.h>
112#define	ASSERT_H_INCLUDED 1
113#endif
114#endif
115
116
117$!trace-include
118
119
120
121#if DK4_ON_WINDOWS
122void
123dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc)
124{
125  dkChar	eb1[8 * sizeof(DWORD) + 16];
126  dkChar	eb2[8 * sizeof(DWORD) + 16];
127  int		res   = 0;
128  int		found = 0;
129
130  if (ERROR_FILE_NOT_FOUND == errc) {
131    dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
132    found = 1;
133    goto finished;
134  }
135  if (ERROR_PATH_NOT_FOUND == errc) {
136    dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
137    found = 1;
138    goto finished;
139  }
140  if (ERROR_ACCESS_DENIED == errc) {
141    dk4app_log_base3(app, DK4_LL_ERROR, 149, 55, path);
142    found = 1;
143    goto finished;
144  }
145  if (ERROR_BAD_NET_NAME == errc) {
146    dk4app_log_base3(app, DK4_LL_ERROR, 149, 74, path);
147    found = 1;
148    goto finished;
149  }
150  if (ERROR_BAD_NETPATH == errc) {
151    dk4app_log_base3(app, DK4_LL_ERROR, 149, 75, path);
152    found = 1;
153    goto finished;
154  }
155  if (ERROR_SHARING_VIOLATION == errc) {
156    dk4app_log_base3(app, DK4_LL_ERROR, 149, 151, path);
157    found = 1;
158    goto finished;
159  }
160  if (0 == found) {
161    res = dk4ma_write_decimal_unsigned(
162      eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)(errc), 0, NULL
163    );
164    if (0 != res) {
165      res = dk4ma_write_hex_unsigned(
166        eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)(errc),
167	0, NULL
168      );
169    }
170    if (0 != res) {
171      dk4app_log_base7(app,DK4_LL_ERROR,149,69,70,71,path,eb1,eb2);
172    } else {
173      dk4app_log_base3(app, DK4_LL_ERROR, 149, 40, path);
174    }
175  }
176  finished: ;
177}
178#endif
179
180
181
182void
183dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc)
184{
185  $? "+ dk4fileinfo_report_stat_failed \"%!ds\"", path
186  switch (errc) {
187#ifdef EACCES
188    case EACCES : {
189      dk4app_log_base3(app, DK4_LL_ERROR, 149, 138, path);
190    } break;
191#endif
192#ifdef EFAULT
193    case EFAULT : {
194      dk4app_log_base3(app, DK4_LL_ERROR, 149, 123, path);
195    } break;
196#endif
197#ifdef ELOOP
198    case ELOOP : {
199      dk4app_log_base3(app, DK4_LL_ERROR, 149, 61, path);
200    } break;
201#endif
202#ifdef ENAMETOOLONG
203    case ENAMETOOLONG : {
204      dk4app_log_base3(app, DK4_LL_ERROR, 149, 42, path);
205    } break;
206#endif
207#ifdef ENOENT
208    case ENOENT : {
209      dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
210    } break;
211#endif
212#ifdef ENOMEM
213    case ENOMEM : {
214      dk4app_log_base3(app, DK4_LL_ERROR, 149, 142, path);
215    } break;
216#endif
217#ifdef ENOTDIR
218    case ENOTDIR : {
219      dk4app_log_base3(app, DK4_LL_ERROR, 149, 150, path);
220    } break;
221#endif
222#ifdef EOVERFLOW
223    case EOVERFLOW : {
224      dk4app_log_base3(app, DK4_LL_ERROR, 149, 117, path);
225    } break;
226#endif
227#ifdef EIO
228    case EIO : {
229      dk4app_log_base3(app, DK4_LL_ERROR, 149, 126, path);
230    } break;
231#endif
232    default : {
233      dk4app_log_base3(app, DK4_LL_ERROR, 149, 101, path);
234    } break;
235  }
236  $? "- dk4fileinfo_report_stat_failed"
237}
238
239
240
241int
242dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app)
243{
244  dk4_er_t	 er;
245  int		 back	= 0;
246#if	DK4_USE_ASSERT
247  assert(NULL != dptr);
248  assert(NULL != fn);
249#endif
250  if ((NULL != dptr) && (NULL != fn)) {
251    dk4error_init(&er);
252    back = dk4fileinfo(dptr, fn, &er);
253    if (0 == back) {
254      switch (er.ec) {
255#if DK4_ON_WINDOWS
256	case DK4_E_CREATE_FILE_FAILED :
257	case DK4_E_FILE_INFORMATION_FAILED :
258	case DK4_E_FINDFIRSTFILE_FAILED :
259	case DK4_E_SYSTEM : {
260	  dk4fileinfo_report_win_failed(app, fn, er.dt.lDetails1);
261	} break;
262#else
263	case DK4_E_SYSTEM : {
264	  dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1);
265	} break;
266#endif
267      }
268    }
269  }
270  return back;
271}
272
273