1 /*
2  * Copyright (C) 2020, 2021  Vladimir Panteleev <btdu@cy.md>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18 
19 /// Common definitions
20 module btdu.common;
21 
22 import std.format : format;
23 import std.random : Random;
24 
25 enum btduVersion = "0.3.0";
26 
27 alias Seed = typeof(Random.defaultSeed);
28 
29 // C error messages
30 
31 struct Errno
32 {
33 	string name, description;
34 }
35 int[string] errnoLookup;
36 ref Errno getErrno(int errno)
37 {
38 	static Errno[int] cache;
39 	return cache.require(errno, {
40 		Errno m;
41 
42 		// TODO: use strerrorname_np, once glibc 2.32 is generally available everywhere
43 		switch (errno)
44 		{
45 			case 1: m.name = "EPERM"; break;
46 			case 2: m.name = "ENOENT"; break;
47 			case 3: m.name = "ESRCH"; break;
48 			case 4: m.name = "EINTR"; break;
49 			case 5: m.name = "EIO"; break;
50 			case 6: m.name = "ENXIO"; break;
51 			case 7: m.name = "E2BIG"; break;
52 			case 8: m.name = "ENOEXEC"; break;
53 			case 9: m.name = "EBADF"; break;
54 			case 10: m.name = "ECHILD"; break;
55 			case 11: m.name = "EAGAIN"; break;
56 			case 12: m.name = "ENOMEM"; break;
57 			case 13: m.name = "EACCES"; break;
58 			case 14: m.name = "EFAULT"; break;
59 			case 15: m.name = "ENOTBLK"; break;
60 			case 16: m.name = "EBUSY"; break;
61 			case 17: m.name = "EEXIST"; break;
62 			case 18: m.name = "EXDEV"; break;
63 			case 19: m.name = "ENODEV"; break;
64 			case 20: m.name = "ENOTDIR"; break;
65 			case 21: m.name = "EISDIR"; break;
66 			case 22: m.name = "EINVAL"; break;
67 			case 23: m.name = "ENFILE"; break;
68 			case 24: m.name = "EMFILE"; break;
69 			case 25: m.name = "ENOTTY"; break;
70 			case 26: m.name = "ETXTBSY"; break;
71 			case 27: m.name = "EFBIG"; break;
72 			case 28: m.name = "ENOSPC"; break;
73 			case 29: m.name = "ESPIPE"; break;
74 			case 30: m.name = "EROFS"; break;
75 			case 31: m.name = "EMLINK"; break;
76 			case 32: m.name = "EPIPE"; break;
77 			case 33: m.name = "EDOM"; break;
78 			case 34: m.name = "ERANGE"; break;
79 			case 35: m.name = "EDEADLK"; break;
80 			case 36: m.name = "ENAMETOOLONG"; break;
81 			case 37: m.name = "ENOLCK"; break;
82 			case 38: m.name = "ENOSYS"; break;
83 			case 39: m.name = "ENOTEMPTY"; break;
84 			case 40: m.name = "ELOOP"; break;
85 			case 42: m.name = "ENOMSG"; break;
86 			case 43: m.name = "EIDRM"; break;
87 			case 44: m.name = "ECHRNG"; break;
88 			case 45: m.name = "EL2NSYNC"; break;
89 			case 46: m.name = "EL3HLT"; break;
90 			case 47: m.name = "EL3RST"; break;
91 			case 48: m.name = "ELNRNG"; break;
92 			case 49: m.name = "EUNATCH"; break;
93 			case 50: m.name = "ENOCSI"; break;
94 			case 51: m.name = "EL2HLT"; break;
95 			case 52: m.name = "EBADE"; break;
96 			case 53: m.name = "EBADR"; break;
97 			case 54: m.name = "EXFULL"; break;
98 			case 55: m.name = "ENOANO"; break;
99 			case 56: m.name = "EBADRQC"; break;
100 			case 57: m.name = "EBADSLT"; break;
101 			case 59: m.name = "EBFONT"; break;
102 			case 60: m.name = "ENOSTR"; break;
103 			case 61: m.name = "ENODATA"; break;
104 			case 62: m.name = "ETIME"; break;
105 			case 63: m.name = "ENOSR"; break;
106 			case 64: m.name = "ENONET"; break;
107 			case 65: m.name = "ENOPKG"; break;
108 			case 66: m.name = "EREMOTE"; break;
109 			case 67: m.name = "ENOLINK"; break;
110 			case 68: m.name = "EADV"; break;
111 			case 69: m.name = "ESRMNT"; break;
112 			case 70: m.name = "ECOMM"; break;
113 			case 71: m.name = "EPROTO"; break;
114 			case 72: m.name = "EMULTIHOP"; break;
115 			case 73: m.name = "EDOTDOT"; break;
116 			case 74: m.name = "EBADMSG"; break;
117 			case 75: m.name = "EOVERFLOW"; break;
118 			case 76: m.name = "ENOTUNIQ"; break;
119 			case 77: m.name = "EBADFD"; break;
120 			case 78: m.name = "EREMCHG"; break;
121 			case 79: m.name = "ELIBACC"; break;
122 			case 80: m.name = "ELIBBAD"; break;
123 			case 81: m.name = "ELIBSCN"; break;
124 			case 82: m.name = "ELIBMAX"; break;
125 			case 83: m.name = "ELIBEXEC"; break;
126 			case 84: m.name = "EILSEQ"; break;
127 			case 85: m.name = "ERESTART"; break;
128 			case 86: m.name = "ESTRPIPE"; break;
129 			case 87: m.name = "EUSERS"; break;
130 			case 88: m.name = "ENOTSOCK"; break;
131 			case 89: m.name = "EDESTADDRREQ"; break;
132 			case 90: m.name = "EMSGSIZE"; break;
133 			case 91: m.name = "EPROTOTYPE"; break;
134 			case 92: m.name = "ENOPROTOOPT"; break;
135 			case 93: m.name = "EPROTONOSUPPORT"; break;
136 			case 94: m.name = "ESOCKTNOSUPPORT"; break;
137 			case 95: m.name = "EOPNOTSUPP"; break;
138 			case 96: m.name = "EPFNOSUPPORT"; break;
139 			case 97: m.name = "EAFNOSUPPORT"; break;
140 			case 98: m.name = "EADDRINUSE"; break;
141 			case 99: m.name = "EADDRNOTAVAIL"; break;
142 			case 100: m.name = "ENETDOWN"; break;
143 			case 101: m.name = "ENETUNREACH"; break;
144 			case 102: m.name = "ENETRESET"; break;
145 			case 103: m.name = "ECONNABORTED"; break;
146 			case 104: m.name = "ECONNRESET"; break;
147 			case 105: m.name = "ENOBUFS"; break;
148 			case 106: m.name = "EISCONN"; break;
149 			case 107: m.name = "ENOTCONN"; break;
150 			case 108: m.name = "ESHUTDOWN"; break;
151 			case 109: m.name = "ETOOMANYREFS"; break;
152 			case 110: m.name = "ETIMEDOUT"; break;
153 			case 111: m.name = "ECONNREFUSED"; break;
154 			case 112: m.name = "EHOSTDOWN"; break;
155 			case 113: m.name = "EHOSTUNREACH"; break;
156 			case 114: m.name = "EALREADY"; break;
157 			case 115: m.name = "EINPROGRESS"; break;
158 			case 116: m.name = "ESTALE"; break;
159 			case 117: m.name = "EUCLEAN"; break;
160 			case 118: m.name = "ENOTNAM"; break;
161 			case 119: m.name = "ENAVAIL"; break;
162 			case 120: m.name = "EISNAM"; break;
163 			case 121: m.name = "EREMOTEIO"; break;
164 			case 122: m.name = "EDQUOT"; break;
165 			case 123: m.name = "ENOMEDIUM"; break;
166 			case 124: m.name = "EMEDIUMTYPE"; break;
167 			case 125: m.name = "ECANCELED"; break;
168 			case 126: m.name = "ENOKEY"; break;
169 			case 127: m.name = "EKEYEXPIRED"; break;
170 			case 128: m.name = "EKEYREVOKED"; break;
171 			case 129: m.name = "EKEYREJECTED"; break;
172 			case 130: m.name = "EOWNERDEAD"; break;
173 			case 131: m.name = "ENOTRECOVERABLE"; break;
174 			case 132: m.name = "ERFKILL"; break;
175 			case 133: m.name = "EHWPOISON"; break;
176 			default: m.name = format!"%d"(errno);
177 		}
178 		errnoLookup.require(m.name, errno);
179 
180 		import core.stdc..string : strlen, strerror_r;
181 		char[1024] buf = void;
182 		auto s = strerror_r(errno, buf.ptr, buf.length);
183 		m.description = s[0 .. s.strlen].idup;
184 
185 		return m;
186 	}());
187 }