dclib-file.h 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #ifndef DCLIB_FILE_H
  34. #define DCLIB_FILE_H 1
  35. #include <sys/types.h>
  36. #include <sys/select.h>
  37. #include <sys/stat.h>
  38. #include "dclib-types.h"
  39. #include "dclib-basics.h"
  40. //
  41. ///////////////////////////////////////////////////////////////////////////////
  42. /////////////// log helpers ///////////////
  43. ///////////////////////////////////////////////////////////////////////////////
  44. #define TRY_OPEN_FILE ((FILE*)1)
  45. #define SETUP_TRY_OPEN_FILE(f,fname,mode) \
  46. static FILE *f = TRY_OPEN_FILE; f = TryOpenFile(f,fname,mode)
  47. FILE * TryOpenFile ( FILE *f, ccp fname, ccp mode );
  48. //-----------------------------------------------------------------------------
  49. // [[TimestampMode_t]
  50. typedef enum TimestampMode_t
  51. {
  52. TSM_OFF, // no timestamp
  53. TSM_SEC, // timstamp HH:MM:SS
  54. TSM_MSEC, // timstamp HH:MM:SS.123
  55. TSM_USEC, // timstamp HH:MM:SS.123456
  56. }
  57. TimestampMode_t;
  58. //-----------------------------------------------------------------------------
  59. // [[LogFile_t]
  60. typedef struct LogFile_t
  61. {
  62. FILE *log; // NULL or log file
  63. mem_t tag; // A string to print before message
  64. TimestampMode_t ts_mode; // How to print the timestamp
  65. bool flush; // TRUE: fflush() for each log
  66. }
  67. LogFile_t;
  68. //-----------------------------------------------------------------------------
  69. extern LogFile_t GlobalLogFile;
  70. int GetLogTimestamp ( char *buf, uint buf_size, TimestampMode_t ts_mode );
  71. int PrintLogTimestamp ( LogFile_t *lf );
  72. int PutLogFile ( LogFile_t *lf, ccp text, int text_len );
  73. int PrintArgLogFile ( LogFile_t *lf, ccp format, va_list arg );
  74. int PrintLogFile ( LogFile_t *lf, ccp format, ... )
  75. __attribute__ ((__format__(__printf__,2,3)));
  76. //-----------------------------------------------------------------------------
  77. exmem_t SearchToolByPATH ( ccp tool );
  78. exmem_t SearchToolByList ( ccp * list, int max ); // max<0: NULL is list terminator
  79. FILE * OpenPipeToPager();
  80. void ClosePagerFile();
  81. bool StdoutToPager();
  82. void CloseStdoutToPager();
  83. //
  84. ///////////////////////////////////////////////////////////////////////////////
  85. /////////////// enum FileMode_t ///////////////
  86. ///////////////////////////////////////////////////////////////////////////////
  87. // [[FileMode_t]]
  88. typedef enum FileMode_t
  89. {
  90. FM_TEST = 0x00001, // test mode, don't modify any file
  91. FM_SILENT = 0x00002, // suppress error messages
  92. FM_IGNORE = 0x00004, // ignore, if no file on OpenFile()
  93. // and return ERR_NOT_EXISTS
  94. FM_MODIFY = 0x00010, // open file for reading and writing
  95. FM_APPEND = 0x00020, // append to existing files
  96. FM_UPDATE = 0x00040, // update existing file
  97. FM_OVERWRITE = 0x00080, // overwrite existing files silently
  98. FM_NUMBER = 0x00100, // renumber filename for existing files
  99. FM_REMOVE = 0x00200, // remove file before open
  100. FM_MKDIR = 0x00400, // create path automatically
  101. FM_TCP = 0x00800, // detect 'tcp:' and 'unix:' prefix on open
  102. FM_STDIO = 0x01000, // detect and allow "-" as stdin or stdout
  103. FM_DEV = 0x02000, // allow character and block devices
  104. FM_SOCK = 0x04000, // allow sockets and connect as unix stream
  105. FM_SPC = 0x08000, // allow special files like pipes and sockets
  106. FM_TOUCH = 0x40000, // touch file (set timestamp) on close
  107. FM_TEMP = 0x80000, // temporary file: remove file on close
  108. FM_M_OPEN = FM_TEST
  109. | FM_SILENT
  110. | FM_IGNORE
  111. | FM_MODIFY
  112. | FM_STDIO
  113. | FM_DEV
  114. | FM_SPC
  115. | FM_TCP
  116. | FM_TEMP,
  117. FM_M_CREATE = FM_TEST
  118. | FM_SILENT
  119. | FM_MODIFY
  120. | FM_APPEND
  121. | FM_UPDATE
  122. | FM_OVERWRITE
  123. | FM_NUMBER
  124. | FM_REMOVE
  125. | FM_MKDIR
  126. | FM_STDIO
  127. | FM_DEV
  128. | FM_SOCK
  129. | FM_SPC
  130. | FM_TOUCH
  131. | FM_TEMP,
  132. FM_M_ALL = FM_M_OPEN
  133. | FM_M_CREATE
  134. }
  135. FileMode_t;
  136. //-----------------------------------------------------------------------------
  137. ccp GetFileModeStatus
  138. (
  139. char *buf, // result buffer
  140. // NULL: use a local circulary static buffer
  141. size_t buf_size, // size of 'buf', ignored if buf==NULL
  142. FileMode_t file_mode, // filemode to print
  143. uint print_mode // 0: short vector, 1 char for 1 attrib
  144. // 1: long mode: keyword for each set attrib
  145. );
  146. ccp GetFileOpenMode
  147. (
  148. bool create, // false: open, true: create
  149. FileMode_t file_mode // open modes
  150. );
  151. //
  152. ///////////////////////////////////////////////////////////////////////////////
  153. /////////////// nanoseconds: struct stat, struct timespec ///////////////
  154. ///////////////////////////////////////////////////////////////////////////////
  155. #ifndef HAVE_STATTIME_NSEC
  156. #ifdef _STATBUF_ST_NSEC
  157. #define HAVE_STATTIME_NSEC 1
  158. #else
  159. #define HAVE_STATTIME_NSEC 0
  160. #endif
  161. #endif
  162. //-----------------------------------------------------------------------------
  163. #undef STATTIME_SEC
  164. #undef STATTIME_NSEC
  165. #if HAVE_STATTIME_NSEC
  166. #define STATTIME_SEC(t) ((t).tv_sec)
  167. #define STATTIME_NSEC(t) ((t).tv_nsec)
  168. #else
  169. #define STATTIME_SEC(t) (t)
  170. #define STATTIME_NSEC(t) 0
  171. #endif
  172. ///////////////////////////////////////////////////////////////////////////////
  173. // struct timespec helpers
  174. extern const struct timespec null_timespec;
  175. // NULL pointers allowed
  176. int CompareTimeSpec0 ( const struct timespec *a, const struct timespec *b );
  177. // NULL pointers forbidden
  178. static inline int CompareTimeSpec
  179. ( const struct timespec *a, const struct timespec *b )
  180. {
  181. DASSERT(a);
  182. DASSERT(b);
  183. return a->tv_sec < b->tv_sec ? -1
  184. : a->tv_sec > b->tv_sec ? 1
  185. : a->tv_nsec < b->tv_nsec ? -1
  186. : a->tv_nsec > b->tv_nsec;
  187. }
  188. // NULL pointers forbidden
  189. static inline int CompareTimeSpecVal
  190. ( const struct timespec *a, const struct timeval *b )
  191. {
  192. DASSERT(a);
  193. DASSERT(b);
  194. return a->tv_sec < b->tv_sec ? -1
  195. : a->tv_sec > b->tv_sec ? 1
  196. : a->tv_nsec < b->tv_usec*1000 ? -1
  197. : a->tv_nsec > b->tv_usec*1000;
  198. }
  199. // NULL pointers forbidden
  200. static inline int CompareTimeSpecTime ( const struct timespec *a, const time_t tim )
  201. {
  202. DASSERT(a);
  203. return a->tv_sec < tim ? -1
  204. : a->tv_sec > tim ? 1
  205. : a->tv_nsec > 0;
  206. }
  207. static inline bool IsTimeSpecNull ( const struct timespec *ts )
  208. {
  209. return !ts
  210. || (unsigned long)ts->tv_nsec > 999999999 // includes UTIME_NOW and UTIME_OMIT
  211. || !ts->tv_nsec && !ts->tv_sec;
  212. }
  213. //-----------------------------------------------------------------------------
  214. void SetAMTimes ( ccp fname, const struct timespec times[2] );
  215. //
  216. ///////////////////////////////////////////////////////////////////////////////
  217. /////////////// struct FileAttrib_t ///////////////
  218. ///////////////////////////////////////////////////////////////////////////////
  219. // [[FileAttrib_t]]
  220. typedef struct FileAttrib_t
  221. {
  222. union
  223. {
  224. struct timespec times[4]; // all times as array
  225. struct
  226. {
  227. // order compatible to utimensat() and futimens()
  228. struct timespec atime; // last ascces time
  229. struct timespec mtime; // time of last content modification
  230. struct timespec ctime; // time of file creation or last status change
  231. struct timespec itime; // insertion time (special time for archives)
  232. };
  233. };
  234. size_t size; // file size
  235. mode_t mode; // file mode
  236. }
  237. FileAttrib_t;
  238. ///////////////////////////////////////////////////////////////////////////////
  239. FileAttrib_t * ClearFileAttrib
  240. (
  241. FileAttrib_t * dest // NULL or destination attribute
  242. );
  243. static inline void ZeroFileAttrib ( FileAttrib_t * dest )
  244. { DASSERT(dest); memset(dest,0,sizeof(*dest)); }
  245. FileAttrib_t * TouchFileAttrib
  246. (
  247. FileAttrib_t * dest // valid destination attribute
  248. );
  249. FileAttrib_t * SetFileAttrib
  250. (
  251. FileAttrib_t * dest, // valid destination attribute
  252. const FileAttrib_t * src_fa, // NULL or source attribute
  253. const struct stat * src_stat // NULL or source attribute
  254. // only used if 'src_fa==NULL'
  255. );
  256. FileAttrib_t * MaxFileAttrib
  257. (
  258. FileAttrib_t * dest, // valid source and destination attribute
  259. const FileAttrib_t * src_fa, // NULL or second source attribute
  260. const struct stat * src_stat // NULL or third source attribute
  261. );
  262. static inline FileAttrib_t * UseFileAttrib
  263. (
  264. FileAttrib_t * dest, // valid destination attribute
  265. const FileAttrib_t * src_fa, // NULL or source attribute
  266. const struct stat * src_stat, // NULL or source attribute
  267. bool use_max // switch for SetFileAttrib() | MaxFileAttrib()
  268. )
  269. {
  270. return ( use_max ? MaxFileAttrib : SetFileAttrib )(dest,src_fa,src_stat);
  271. }
  272. FileAttrib_t * NormalizeFileAttrib
  273. (
  274. FileAttrib_t * fa // valid attribute
  275. );
  276. //
  277. ///////////////////////////////////////////////////////////////////////////////
  278. /////////////// struct File_t ///////////////
  279. ///////////////////////////////////////////////////////////////////////////////
  280. // [[File_t]]
  281. typedef struct File_t
  282. {
  283. //--- file handle
  284. FILE *f; // file descriptor
  285. //--- basic status
  286. ccp fname; // file name, alloced
  287. FileMode_t fmode; // file open mode
  288. struct stat st; // file status just before opened
  289. FileAttrib_t fatt; // file attributes
  290. //--- advanced status
  291. bool is_stdio; // true: read from stdin or to stdout
  292. bool is_socket; // true: file is a UNIX stream socket
  293. bool is_reading; // true: file opened for reading
  294. bool is_writing; // true: file opened for writing
  295. bool is_seekable; // true: file is seekable
  296. enumError max_err; // maximum file related error
  297. //--- file data
  298. u8 * data; // NULL or file data
  299. size_t size; // size of 'data'
  300. bool data_alloced; // true: 'data' is alloced,
  301. // free it on ResetFile()
  302. }
  303. File_t;
  304. ///////////////////////////////////////////////////////////////////////////////
  305. void InitializeFile
  306. (
  307. File_t * f // file structure
  308. );
  309. enumError ResetFile
  310. (
  311. File_t * f, // file structure
  312. uint set_time // 0: don't set
  313. // 1: set time before closing using 'fatt'
  314. // 2: set current time before closing
  315. );
  316. enumError CloseFile
  317. (
  318. File_t * f, // file structure
  319. uint set_time // 0: don't set
  320. // 1: set time before closing using 'fatt'
  321. // 2: set current time before closing
  322. );
  323. //-----------------------------------------------------------------------------
  324. enumError OpenFile
  325. (
  326. File_t * f, // file structure
  327. bool initialize, // true: initialize 'f'
  328. ccp fname, // file to open
  329. FileMode_t file_mode, // open modes
  330. off_t limit, // >0: don't open, if file size > limit
  331. ccp limit_message // NULL or a with LF terminated text.
  332. // It is printed after the message.
  333. );
  334. //-----------------------------------------------------------------------------
  335. enumError CheckCreateFile
  336. (
  337. // returns:
  338. // ERR_DIFFER: [FM_STDIO] source is "-" => 'st' is zeroed
  339. // ERR_WARNING: [FM_DEV,FM_SPC] not a regular file
  340. // ERR_WRONG_FILE_TYPE: file exists, but is not a regular file
  341. // ERR_ALREADY_EXISTS: file already exists
  342. // ERR_INVALID_VERSION: already exists, but FM_NUMBER set => no msg printed
  343. // ERR_CANT_CREATE: FM_UPDATE is set, but file don't exist
  344. // ERR_OK: file not exist or can be overwritten
  345. ccp fname, // filename to open
  346. FileMode_t file_mode, // open modes
  347. struct stat *st // not NULL: store file status here
  348. );
  349. enumError CreateFile
  350. (
  351. File_t * f, // file structure
  352. bool initialize, // true: initialize 'f'
  353. ccp fname, // file to open
  354. FileMode_t file_mode // open modes
  355. );
  356. static inline enumError AppendFile
  357. (
  358. File_t * f, // file structure
  359. bool initialize, // true: initialize 'f'
  360. ccp fname, // file to open
  361. FileMode_t file_mode // open modes
  362. )
  363. {
  364. return CreateFile(f,initialize,fname,file_mode|FM_APPEND);
  365. }
  366. //-----------------------------------------------------------------------------
  367. enumError WriteFileAt
  368. (
  369. File_t * F, // file to write
  370. size_t * cur_offset, // pointer to current file offset, modified
  371. size_t offset, // offset to write
  372. const void * data, // data to write
  373. size_t size // size of 'data'
  374. );
  375. //-----------------------------------------------------------------------------
  376. enumError SetFileSize
  377. (
  378. File_t * F, // file to write
  379. size_t * cur_offset, // pointer to current file offset, modified
  380. size_t size // offset to write
  381. );
  382. //-----------------------------------------------------------------------------
  383. enumError SkipFile
  384. (
  385. File_t *F, // file to write
  386. size_t skip // number of bytes to skip
  387. );
  388. //-----------------------------------------------------------------------------
  389. enumError RegisterFileError
  390. (
  391. File_t * f, // file structure
  392. enumError new_error // new error code
  393. );
  394. ///////////////////////////////////////////////////////////////////////////////
  395. s64 GetFileSize
  396. (
  397. ccp path1, // NULL or part 1 of path
  398. ccp path2, // NULL or part 2 of path
  399. s64 not_found_val, // return value if no regular file found
  400. FileAttrib_t * fatt, // not NULL: store file attributes
  401. bool fatt_max // true: store max values to 'fatt'
  402. );
  403. //-----------------------------------------------------------------------------
  404. enumError OpenReadFile
  405. (
  406. ccp path1, // NULL or part #1 of path
  407. ccp path2, // NULL or part #2 of path
  408. FileMode_t file_mode, // open modes
  409. off_t limit, // >0: don't open, if file size > limit
  410. ccp limit_message, // NULL or a with LF terminated text.
  411. // It is printed after the message.
  412. u8 ** res_data, // store alloced data here (always NULL terminated)
  413. uint * res_size, // not NULL: store data size
  414. ccp * res_fname, // not NULL: store alloced filename
  415. FileAttrib_t * res_fatt // not NULL: store file attributes
  416. );
  417. //-----------------------------------------------------------------------------
  418. enumError LoadFile
  419. (
  420. ccp path1, // NULL or part #1 of path
  421. ccp path2, // NULL or part #2 of path
  422. size_t skip, // skip num of bytes before reading
  423. void * data, // destination buffer, size = 'size'
  424. size_t size, // size to read
  425. int silent, // 0: print all error messages
  426. // 1: suppress file size warning
  427. // 2: suppress all error messages
  428. FileAttrib_t * fatt, // not NULL: store file attributes
  429. bool fatt_max // true: store *max* values to 'fatt'
  430. );
  431. //-----------------------------------------------------------------------------
  432. enumError LoadFileAlloc
  433. (
  434. ccp path1, // NULL or part #1 of path
  435. ccp path2, // NULL or part #2 of path
  436. size_t skip, // skip num of bytes before reading
  437. u8 ** res_data, // result: free existing data, store ptr to alloc data
  438. // always one more byte is alloced and set to NULL
  439. size_t * res_size, // result: size of 'res_data'
  440. size_t max_size, // >0: a file size limit
  441. int silent, // 0: print all error messages
  442. // 1: suppress file size warning
  443. // 2: suppress all error messages
  444. FileAttrib_t * fatt, // not NULL: store file attributes
  445. bool fatt_max // true: store max values to 'fatt'
  446. );
  447. //-----------------------------------------------------------------------------
  448. enumError SaveFile
  449. (
  450. ccp path1, // NULL or part #1 of path
  451. ccp path2, // NULL or part #2 of path
  452. FileMode_t file_mode, // open modes
  453. const void * data, // data to write
  454. uint data_size, // size of 'data'
  455. FileAttrib_t * fatt // not NULL: set timestamps using this attrib
  456. );
  457. //-----------------------------------------------------------------------------
  458. enumError OpenWriteFile
  459. (
  460. File_t * f, // file structure
  461. bool initialize, // true: initialize 'f'
  462. ccp path1, // NULL or part #1 of path
  463. ccp path2, // NULL or part #2 of path
  464. FileMode_t file_mode, // open modes
  465. const void * data, // data to write
  466. uint data_size // size of 'data'
  467. );
  468. //-----------------------------------------------------------------------------
  469. uint CloseAllExcept
  470. (
  471. int *list, // exception list of unordered FD, max contain -1
  472. uint n_list, // number of elements in 'list'
  473. int min, // close all until and including this fd
  474. int add // if a FD was found, incremet 'min' to 'fd+add'
  475. );
  476. //
  477. ///////////////////////////////////////////////////////////////////////////////
  478. /////////////// CopyFile*(), TransferFile() ///////////////
  479. ///////////////////////////////////////////////////////////////////////////////
  480. // compare paths and by stat()
  481. bool IsSameFile ( ccp path1, ccp path2 );
  482. ///////////////////////////////////////////////////////////////////////////////
  483. // returns:
  484. // ERR_OK file copied
  485. // ERR_NOTHING_TO_DO src and dest are the same
  486. // ERR_MISSING_PARAM invalid parameters
  487. // ERR_CANT_OPEN can't open dest
  488. // ERR_WRITE_FAILED write error
  489. enumError CopyFileHelper
  490. (
  491. ccp src, // source path
  492. ccp dest, // destination path
  493. int open_flags, // flags for open()
  494. mode_t open_mode, // mode for open()
  495. uint temp_and_move // >0: ignore open_flags,
  496. // create temp, then move temp to dest
  497. );
  498. //-----------------------------------------------------------------------------
  499. enumError CopyFile
  500. (
  501. ccp src, // source path
  502. ccp dest, // destination path
  503. mode_t open_mode // mode for open()
  504. );
  505. //-----------------------------------------------------------------------------
  506. enumError CopyFileCreate
  507. (
  508. ccp src, // source path
  509. ccp dest, // destination path
  510. mode_t open_mode // mode for open()
  511. );
  512. //-----------------------------------------------------------------------------
  513. enumError CopyFileTemp
  514. (
  515. ccp src, // source path
  516. ccp dest, // destination path
  517. mode_t open_mode // mode for open()
  518. );
  519. ///////////////////////////////////////////////////////////////////////////////
  520. // [[TransferMode_t]]
  521. typedef enum TransferMode_t
  522. {
  523. //--- jobs
  524. TFMD_J_MOVE = 0x001, // move file
  525. TFMD_J_MOVE1 = 0x002, // move file, but only if not linked (ignore TFMD_J_MOVE)
  526. TFMD_J_RM_DEST = 0x004, // remove dest before TFMD_J_LINK and TFMD_J_COPY
  527. TFMD_J_LINK = 0x008, // link file
  528. TFMD_J_COPY = 0x010, // copy file
  529. TFMD_J_RM_SRC = 0x020, // remove source after TFMD_J_COPY
  530. // TFMD_J_TOUCH = 0x040, // touch destination => not supported yet
  531. //--- flags
  532. TFMD_F_TEST = 0x100, // testmode, don't touch files
  533. //--- masks
  534. TFMD_M_JOBS = 0x03f, // mask for jobs
  535. TFMD_M_FLAGS = 0x100, // mask for flags
  536. //--- modes
  537. TFMD_MOVE = TFMD_J_MOVE | TFMD_J_RM_DEST | TFMD_J_COPY | TFMD_J_RM_SRC,
  538. TFMD_MOVE1 = TFMD_J_MOVE1 | TFMD_J_RM_DEST | TFMD_J_COPY | TFMD_J_RM_SRC,
  539. TFMD_LINK = TFMD_J_LINK | TFMD_J_RM_DEST | TFMD_J_COPY,
  540. TFMD_COPY = TFMD_J_RM_DEST | TFMD_J_COPY,
  541. TFMD_CAT = TFMD_J_COPY,
  542. }
  543. TransferMode_t;
  544. //-----------------------------------------------------------------------------
  545. // returns:
  546. // ERR_OK file copied
  547. // ERR_NOTHING_TO_DO src and dest are the same
  548. // ERR_MISSING_PARAM invalid parameters
  549. // ERR_CANT_OPEN can't open dest
  550. // ERR_WRITE_FAILED write error
  551. // ERR_ERROR other error
  552. enumError TransferFile
  553. (
  554. LogFile_t *log, // not NULL: log activities
  555. ccp dest, // destination path
  556. ccp src, // source path
  557. TransferMode_t tfer_mode, // transfer mode
  558. mode_t open_mode // mode for CopyFile*() -> open()
  559. );
  560. //
  561. ///////////////////////////////////////////////////////////////////////////////
  562. /////////////// struct MemFile_t ///////////////
  563. ///////////////////////////////////////////////////////////////////////////////
  564. // [[MemFile_t]]
  565. typedef struct MemFile_t
  566. {
  567. u8 *data; // pointer to alloced data
  568. uint size; // size of 'data'
  569. uint max_size; // >0: max allowed size of 'data'
  570. uint fend; // current end of file position, always '<=size'
  571. uint fpos; // current file pointer, always '<=fend'
  572. ccp err_name; // not NULL: print error messages
  573. bool err_name_alloced; // true: 'err_name' must be freed
  574. bool zero_extend; // true: assume unlimted file on Read*()
  575. bool eof; // set by Read*(), if read behind 'fend'
  576. FileAttrib_t fatt; // file attribute for loaded files
  577. }
  578. MemFile_t;
  579. ///////////////////////////////////////////////////////////////////////////////
  580. bool IsValidMemFile ( MemFile_t *mf );
  581. void DumpMemFile
  582. (
  583. FILE *f, // valid output stream
  584. int indent, // indent of output
  585. MemFile_t *mf // valid MemFile_t data
  586. );
  587. bool AssertMemFile
  588. (
  589. MemFile_t *mf // valid MemFile_t data
  590. );
  591. ///////////////////////////////////////////////////////////////////////////////
  592. u8 * GetDataMemFile
  593. (
  594. // return NULL on err or a pointer to the data posisiton.
  595. MemFile_t *mf, // valid MemFile_t data
  596. uint fpos, // fpos to read from
  597. uint size // needed data size
  598. );
  599. void InitializeMemFile
  600. (
  601. MemFile_t *mf, // structure to initialize
  602. uint start_size, // >0: alloc this for data
  603. uint max_size // >0: file never grows above 'max_size'
  604. );
  605. void ResetMemFile
  606. (
  607. MemFile_t *mf // valid MemFile_t data
  608. );
  609. ///////////////////////////////////////////////////////////////////////////////
  610. enumError WriteMemFileAt
  611. (
  612. MemFile_t *mf, // valid MemFile_t data
  613. uint fpos, // fpos to write
  614. const void *data, // data to write
  615. uint size // size to write
  616. );
  617. static inline enumError WriteMemFile
  618. (
  619. MemFile_t *mf, // valid MemFile_t data
  620. const void *data, // data to write
  621. uint size // size to write
  622. )
  623. {
  624. DASSERT(mf);
  625. return WriteMemFileAt(mf,mf->fpos,data,size);
  626. }
  627. ///////////////////////////////////////////////////////////////////////////////
  628. uint ReadMemFileAt
  629. (
  630. MemFile_t *mf, // valid MemFile_t data
  631. uint fpos, // fpos to read from
  632. void *buf, // destination buffer
  633. uint size // size to read
  634. );
  635. static inline uint ReadMemFile
  636. (
  637. MemFile_t *mf, // valid MemFile_t data
  638. void *buf, // destination buffer
  639. uint size // size to read
  640. )
  641. {
  642. DASSERT(mf);
  643. return ReadMemFileAt(mf,mf->fpos,buf,size);
  644. }
  645. ///////////////////////////////////////////////////////////////////////////////
  646. enumError LoadMemFile
  647. (
  648. MemFile_t *mf, // MemFile_t data
  649. bool init_mf, // true: initialize 'mf' first
  650. ccp path1, // NULL or part #1 of path
  651. ccp path2, // NULL or part #2 of path
  652. size_t skip, // >0: skip num of bytes before reading
  653. size_t size, // >0: max size to read; 0: read all (remaining)
  654. bool silent // true: suppress error messages
  655. );
  656. enumError SaveMemFile
  657. (
  658. MemFile_t *mf, // MemFile_t data
  659. ccp path1, // NULL or part #1 of path
  660. ccp path2, // NULL or part #2 of path
  661. FileMode_t fmode, // mode for file creation
  662. bool sparse // true: enable sparse support
  663. );
  664. //
  665. ///////////////////////////////////////////////////////////////////////////////
  666. /////////////// TraceLog_t ///////////////
  667. ///////////////////////////////////////////////////////////////////////////////
  668. // [[TraceLog_t]]
  669. typedef struct TraceLog_t
  670. {
  671. ccp fname; // name of file to open
  672. FILE *log; // NULL or open log file
  673. int level; // log level, don't log if <0
  674. }
  675. TraceLog_t;
  676. //-----------------------------------------------------------------------------
  677. bool OpenTraceLog ( TraceLog_t *tl );
  678. bool TraceLogText ( TraceLog_t *tl, ccp text );
  679. bool TraceLogPrint ( TraceLog_t *tl, ccp format, ... )
  680. __attribute__ ((__format__(__printf__,2,3)));
  681. //
  682. ///////////////////////////////////////////////////////////////////////////////
  683. /////////////// struct LineBuffer_t ///////////////
  684. ///////////////////////////////////////////////////////////////////////////////
  685. #ifndef __APPLE__
  686. ///////////////////////////////////////////////////////////////////////////////
  687. // [[LineBuffer_t]]
  688. typedef struct LineBuffer_t
  689. {
  690. FILE *fp; // current file pointer
  691. FILE *old_fp; // NULL or file before opened
  692. FILE **old_fp_pos; // not NULL: store 'old_fp' on close()
  693. int redirect; // >0: redirect to 'old_fp' (waste if old_fp==0)
  694. GrowBuffer_t buf; // grow buffer to hold lines
  695. u8 *prev_buf_ptr; // previous 'buf.ptr', if changed recalc 'line'
  696. uint max_lines; // max numbers of lines
  697. uint used_lines; // numbers of used lines
  698. uint max_line_size; // >0: max size of a single line
  699. mem_t *line; // list with 'max_lines' elements
  700. bool open_line; // true: last line not terminated yet
  701. uint seq_count; // increased by 1 on every change
  702. uint prev_seq_count; // previous 'seq_count', if changed recalc 'line'
  703. uint line_count; // increased for each insertet LF, no internal impact
  704. }
  705. LineBuffer_t;
  706. //-----------------------------------------------------------------------------
  707. void InitializeLineBuffer ( LineBuffer_t *lb, uint max_buf_size );
  708. void ResetLineBuffer ( LineBuffer_t *lb );
  709. void ClearLineBuffer ( LineBuffer_t *lb );
  710. void RedirectLineBuffer
  711. (
  712. LineBuffer_t *lb, // valid line buffer
  713. FILE *f, // output file, if NULL use 'lb->old_fd'
  714. int max_lines // >=0: max number of redirected lines
  715. );
  716. LineBuffer_t * OpenLineBuffer
  717. (
  718. LineBuffer_t *lb, // line buffer; if NULL, malloc() one
  719. bool init_lb, // true: initialize 'lb'
  720. FILE **fp_pos, // NULL or external place of the file pointer
  721. uint max_lines, // max numbers of lines
  722. uint max_line_size, // >0: max size of a single line
  723. uint max_buf_size // >0: max total buffer size
  724. );
  725. int CloseLineBuffer ( LineBuffer_t *lb );
  726. ssize_t WriteLineBuffer ( LineBuffer_t *lb, ccp buf, size_t size );
  727. void FixMemListLineBuffer ( LineBuffer_t *lb, bool force );
  728. uint GetMemListLineBuffer
  729. (
  730. // returns the number of elements
  731. LineBuffer_t *lb, // line buffer; if NULL, malloc() one
  732. mem_t **res, // not NULL: store pointer to first element here
  733. int max_lines // !0: limit lines, <0: count from end
  734. );
  735. uint PrintLineBuffer
  736. (
  737. // returns number of written lines
  738. FILE *f, // output stream
  739. int indent, // indention
  740. LineBuffer_t *lb, // line buffer; if NULL, malloc() one
  741. int max_lines, // !0: limit lines, <0: count from end
  742. ccp open_line // not NULL: append this text for an open line
  743. );
  744. ///////////////////////////////////////////////////////////////////////////////
  745. #endif // !__APPLE__
  746. ///////////////////////////////////////////////////////////////////////////////
  747. //
  748. ///////////////////////////////////////////////////////////////////////////////
  749. /////////////// file helpers ///////////////
  750. ///////////////////////////////////////////////////////////////////////////////
  751. // [[inode_type_t]]
  752. typedef enum inode_type_t
  753. {
  754. INTY_UNKNOWN, // never tested
  755. INTY_NOTFOUND, // file not found or error
  756. INTY_AVAIL, // file is available
  757. INTY_SOCK, // S_ISSOCK
  758. INTY_LINK, // S_ISLNK
  759. INTY_FIFO, // S_ISFIFO
  760. INTY_BLOCK, // S_ISBLK
  761. INTY_CHAR, // S_ISCHR
  762. INTY_DIR, // S_ISDIR
  763. INTY_REG, // S_ISREG
  764. INTY__N
  765. }
  766. __attribute__ ((packed)) inode_type_t;
  767. extern const char inode_type_char[INTY__N+1];
  768. //-----------------------------------------------------------------------------
  769. inode_type_t GetInodeType ( int ret_status, mode_t mode );
  770. inode_type_t GetInodeTypeByPath ( ccp path, mode_t *mode );
  771. inode_type_t GetInodeTypeByFD ( int fd, mode_t *mode );
  772. ///////////////////////////////////////////////////////////////////////////////
  773. int IsDirectory
  774. (
  775. // analyse filename (last char == '/') and stat(fname)
  776. ccp fname, // NULL or path
  777. int answer_if_empty // answer, if !fname || !*fname
  778. );
  779. int ExistDirectory
  780. (
  781. // check only real file (stat(fname))
  782. ccp fname, // NULL or path
  783. int answer_if_empty // answer, if !fname || !*fname
  784. );
  785. bool IsSameFilename ( ccp fn1, ccp fn2 );
  786. // convert type get by readdir() to of struct stat.st_mode
  787. uint ConvertDType2STMode ( uint d_type );
  788. ///////////////////////////////////////////////////////////////////////////////
  789. // [[FindConfigFile_t]]
  790. typedef enum FindConfigFile_t
  791. {
  792. FCF_HOME = 0x001, // ~/.<SHARE>/<FILENAME>
  793. FCF_REL_SHARE = 0x002, // <PROGPATH>/../share/<SHARE>/<FILENAME>
  794. FCF_LOC_SHARE = 0x004, // /usr/local/share/<SHARE>/<FILENAME>
  795. FCF_USR_SHARE = 0x008, // /usr/share/<SHARE>/<FILENAME>
  796. FCF_PROG_SHARE = 0x010, // <PROGPATH>/share/<PROGNAME><EXT>
  797. FCF_PROG = 0x020, // <PROGPATH>/<PROGNAME><EXT>
  798. FCF_STD_SHARE = FCF_REL_SHARE
  799. | FCF_LOC_SHARE
  800. | FCF_USR_SHARE,
  801. FCF_STD_PROG = FCF_PROG_SHARE
  802. | FCF_PROG,
  803. FCF_ALL = 0x03f,
  804. FCF_F_DEBUG = 0x100, // enable logging
  805. }
  806. FindConfigFile_t;
  807. //-----------------------------------------------------------------------------
  808. // Managed and read by user, ignored by FindConfigFile()
  809. // Intention: if set globally, call FindConfigFile() with FCF_F_DEBUG
  810. extern bool enable_config_search_log;
  811. //-----------------------------------------------------------------------------
  812. ccp FindConfigFile
  813. (
  814. // returns NULL or found file (alloced)
  815. FindConfigFile_t mode, // bit field: select search destinations
  816. ccp share_name, // NULL or <SHARE>
  817. ccp file_name, // NULL or <FILENAME>
  818. ccp prog_ext // <EXT>, if NULL use '.' + <FILENAME>
  819. );
  820. //-----------------------------------------------------------------------------
  821. struct dirent;
  822. typedef int (*SearchFilesFunc) ( ccp basepath, struct dirent *dent, void * param );
  823. int SearchFiles
  824. (
  825. ccp path1, // not NULL: part #1 of base path
  826. ccp path2, // not NULL: part #2 of base path
  827. ccp match, // not NULL: filter files by MatchPattern()
  828. // if empty: extract from combined path
  829. SearchFilesFunc func, // callback function, never NULL
  830. void *param // third parameter of func()
  831. );
  832. ///////////////////////////////////////////////////////////////////////////////
  833. // [[search_paths_stat_t]]
  834. typedef struct search_paths_stat_t
  835. {
  836. bool abort; // true: abort search
  837. enumError max_err; // max found error
  838. uint dir_count; // number of scanned directories
  839. uint func_count; // number of func() calls
  840. uint hit_count; // number of hits (!ERR_JOB_IGNORED)
  841. }
  842. search_paths_stat_t;
  843. //-----------------------------------------------------------------------------
  844. // error codes < 0 mean: abort.
  845. // return ERR_JOB_IGNORED if path finally not match
  846. typedef enumError (*SearchPathsFunc)
  847. (
  848. mem_t path, // full path of existing file, never NULL
  849. uint st_mode, // copy of struct stat.st_mode, see "man 2 stat"
  850. void *param // user defined parameter
  851. );
  852. //-----------------------------------------------------------------------------
  853. search_paths_stat_t SearchPaths
  854. (
  855. ccp path1, // not NULL: part #1 of base path
  856. ccp path2, // not NULL: part #2 of base path
  857. bool allow_hidden, // allow hiddent directories and files
  858. SearchPathsFunc func, // callback function, never NULL
  859. void *param // last param for func()
  860. );
  861. ///////////////////////////////////////////////////////////////////////////////
  862. enumError CreatePath
  863. (
  864. ccp path, // path to create
  865. bool is_pure_dir // true: 'path' don't contains a filename part
  866. );
  867. enumError RemoveSource
  868. (
  869. ccp fname, // file to remove
  870. ccp dest_fname, // NULL or dest file name
  871. // If real paths are same: don't remove
  872. bool print_log, // true: print a log message
  873. bool testmode // true: don't remove, log only
  874. );
  875. ///////////////////////////////////////////////////////////////////////////////
  876. char * FindFilename
  877. (
  878. // Find the last part of the path, trailing '/' are ignored
  879. // return poiner to found string
  880. ccp path, // path to analyze, valid string
  881. uint * result_len // not NULL: return length of found string
  882. );
  883. uint NumberedFilename
  884. (
  885. // return used index number or 0, if not modified.
  886. char * buf, // destination buffer
  887. size_t bufsize, // size of 'buf'
  888. ccp source, // source filename, may be part of 'buf'
  889. // if NULL or empty:
  890. ccp ext, // not NULL & not empty: file extension ('.ext')
  891. uint ext_mode, // only relevant, if 'ext' is neither NULL not empty
  892. // 0: use 'ext' only for detection
  893. // 1: replace 'source' extension by 'ext'
  894. // 2: append 'ext' if 'source' differ
  895. // 3: append 'ext' always
  896. bool detect_stdio // true: don't number "-"
  897. );
  898. ///////////////////////////////////////////////////////////////////////////////
  899. #if 0
  900. char * SplitSubPath
  901. (
  902. char * buf, // destination buffer
  903. size_t buf_size, // size of 'buf'
  904. ccp path // source path, if NULL: use 'buf'
  905. );
  906. #endif
  907. ///////////////////////////////////////////////////////////////////////////////
  908. // return a string of the internal cache
  909. // if ret_level: store level here.
  910. ccp GetBlockDeviceHolder ( ccp name, ccp sep, int *ret_level );
  911. //
  912. ///////////////////////////////////////////////////////////////////////////////
  913. /////////////// normalize filenames ///////////////
  914. ///////////////////////////////////////////////////////////////////////////////
  915. // [[trailing_slash]]
  916. typedef enum trailing_slash
  917. {
  918. TRSL_NONE, // do nothing special
  919. TRSL_REMOVE, // remove trailing slash always
  920. TRSL_ADD_ALWAYS, // add trailing slash always
  921. TRSL_ADD_AUTO, // add trailing slash if it is a directory
  922. TRSL_AUTO, // add trailing slash if it is a directory, remove otherwise
  923. }
  924. trailing_slash;
  925. ///////////////////////////////////////////////////////////////////////////////
  926. char * NormalizeFileName
  927. (
  928. // returns a pointer to the NULL terminator within 'buf'
  929. char * buf, // valid destination buffer
  930. uint buf_size, // size of buf
  931. ccp source, // NULL or source
  932. bool allow_slash, // true: allow '/' in source
  933. bool is_utf8, // true: enter UTF-8 mode
  934. trailing_slash slash_mode // manipulate trailing slash
  935. );
  936. ///////////////////////////////////////////////////////////////////////////////
  937. uint IsWindowsDriveSpec
  938. (
  939. // returns the length of the found windows drive specification (0|2|3)
  940. ccp src // NULL or valid string
  941. );
  942. uint NormalizeFilenameCygwin
  943. (
  944. // returns the used length (without 0-term) of buf.
  945. char * buf, // valid destination buffer
  946. uint buf_size, // size of buf
  947. ccp src // NULL or source
  948. );
  949. exmem_t GetNormalizeFilenameCygwin
  950. (
  951. // returns an object. Call FreeExMem(RESULT) to free possible alloced memory.
  952. ccp source, // NULL or source
  953. bool try_circ // use circ-buffer, if result is small enough
  954. );
  955. char * AllocNormalizedFilenameCygwin
  956. (
  957. // returns an alloced buffer with the normalized filename
  958. // Call FreeString(RESULT) to free possible alloced memory.
  959. ccp source, // NULL or source
  960. bool try_circ // use circ-buffer, if result is small enough
  961. );
  962. //
  963. ///////////////////////////////////////////////////////////////////////////////
  964. /////////////// search file & config ///////////////
  965. ///////////////////////////////////////////////////////////////////////////////
  966. // [[search_file_t]]}
  967. typedef struct search_file_t
  968. {
  969. ccp fname; // filename
  970. bool alloced; // is 'fname' alloced
  971. inode_type_t itype; // one of INTY_*
  972. u16 hint; // any hint
  973. }
  974. search_file_t;
  975. //-----------------------------------------------------------------------------
  976. // [[search_file_list_t]]}
  977. typedef struct search_file_list_t
  978. {
  979. search_file_t *list; // list of files
  980. uint used; // number of used elements in 'list'
  981. uint size; // number of alloced elements for 'list'
  982. exmem_list_t symbols; // list to resolve $(SYMBOL)
  983. }
  984. search_file_list_t;
  985. //-----------------------------------------------------------------------------
  986. static inline void InitializeSearchFile ( search_file_list_t *sfl )
  987. { DASSERT(sfl); memset(sfl,0,sizeof(*sfl)); }
  988. void ResetSearchFile ( search_file_list_t *sfl );
  989. search_file_t * AppendSearchFile
  990. (
  991. search_file_list_t *sfl, // valid search list, new files will be appended
  992. ccp fname, // path+fname to add
  993. CopyMode_t copy_mode, // copy mode for 'fname'
  994. ccp append_if_dir // append this if 'fname' is a directory
  995. );
  996. void DumpSearchFile ( FILE *f, int indent,
  997. const search_file_list_t *sfl, bool show_symbols, ccp info );
  998. ///////////////////////////////////////////////////////////////////////////////
  999. // [[config_hint_t]]
  1000. typedef enum config_hint_t
  1001. {
  1002. CONF_HINT_MISC = 0x01,
  1003. CONF_HINT_INST = 0x02,
  1004. CONF_HINT_ETC = 0x04,
  1005. CONF_HINT_HOME = 0x08,
  1006. CONF_HINT_OPT = 0x10,
  1007. }
  1008. config_hint_t;
  1009. //-----------------------------------------------------------------------------
  1010. bool SearchConfig
  1011. (
  1012. // for all paths:
  1013. // /... is an absolute path
  1014. // $(home)/... path relative to getenv("HOME")
  1015. // $(xdg_home)/... path relative to first path of getenv("XDG_CONFIG_HOME")
  1016. // $(xdg_etc)/... path relative to first path of getenv("XDG_CONFIG_DIRS")
  1017. // $(etc)/... path relative to /etc directory
  1018. // $(install)/... path relative to installation directory = ProgramDirectory()
  1019. // $(NAME)/... path relative to symbol in sfl->symbols
  1020. // xx relative paths otherwise
  1021. search_file_list_t *sfl,
  1022. // valid search list, new paths will be appended
  1023. // sfl->symbols: home, etc and install are added (not replaced)
  1024. // It is used to resolve all $(NAME) references.
  1025. ccp config_fname, // default filename (without path) of config file
  1026. ccp *option, // NULL or filenames by option => CONF_HINT_OPT
  1027. int n_option, // num of 'option' elements, -1:null terminated list
  1028. ccp *xdg_home, // NULL or $(xdg_home) based paths => CONF_HINT_HOME
  1029. int n_xdg_home, // num of 'home' elements, -1:null terminated list
  1030. ccp *home, // NULL or $(home) based paths => CONF_HINT_HOME
  1031. int n_home, // num of 'home' elements, -1:null terminated list
  1032. ccp *etc, // NULL or $(etc) based paths => CONF_HINT_ETC
  1033. int n_etc, // num of 'etc' elements, -1:null terminated list
  1034. ccp *install, // NULL or $(install) based paths => CONF_HINT_INST
  1035. int n_install, // num of 'install' elements, -1:null terminated list
  1036. ccp *misc, // NULL or absolute paths => CONF_HINT_MISC
  1037. int n_misc, // num of 'misc' elements, -1:null terminated list
  1038. int stop_mode // >0: stop if found, >1: stop on option
  1039. );
  1040. //
  1041. ///////////////////////////////////////////////////////////////////////////////
  1042. /////////////// FDList_t ///////////////
  1043. ///////////////////////////////////////////////////////////////////////////////
  1044. // [[FDList_t]]
  1045. struct pollfd;
  1046. typedef struct FDList_t
  1047. {
  1048. bool use_poll; // false: use select(), true: use poll()
  1049. u_usec_t now_usec; // set on Clear() and Wait(), result of GetTimeUSec(false)
  1050. u_usec_t timeout_usec; // next timeout, based on GetTimeUSec(false) (TIME!)
  1051. u_nsec_t timeout_nsec; // next timeout, based on GetTimerNSec() (TIMER!)
  1052. u_usec_t min_wait_usec; // if >0: minimal waiting time (increment 'timeout_usec')
  1053. //--- select() params
  1054. int max_fd; // highest-numbered file descriptor, add 1 on select()
  1055. fd_set readfds; // ready to read
  1056. fd_set writefds; // ready to write
  1057. fd_set exceptfds; // ready to except
  1058. //--- poll() params
  1059. struct pollfd *poll_list; // list of poll parameters
  1060. uint poll_used; // poll_list: number of used elements
  1061. uint poll_size; // poll_list: number of alloced elements
  1062. //--- statistics
  1063. FILE *debug_file; // not NULL: print debug line each select() and poll()
  1064. uint n_sock; // current number of registered sockets
  1065. // equals poll_used if poll is used
  1066. uint wait_count; // total number of waits
  1067. u_usec_t wait_usec; // total wait time in usec
  1068. u_usec_t last_wait_usec; // last wait time in usec
  1069. }
  1070. FDList_t;
  1071. ///////////////////////////////////////////////////////////////////////////////
  1072. void ClearFDList ( FDList_t *fdl );
  1073. void InitializeFDList ( FDList_t *fdl, bool use_poll );
  1074. void ResetFDList ( FDList_t *fdl );
  1075. //-----------------------------------------------------------------------------
  1076. // announce new sockets
  1077. void AnnounceFDList ( FDList_t *fdl, uint n );
  1078. struct pollfd * AllocFDList ( FDList_t *fdl, uint n );
  1079. uint AddFDList
  1080. (
  1081. // returns the pool-index if available, ~0 otherwise
  1082. FDList_t *fdl, // valid socket list
  1083. int sock, // socket to add
  1084. uint events // bit field: POLLIN|POLLPRI|POLLOUT|POLLRDHUP|...
  1085. );
  1086. uint GetEventFDList
  1087. (
  1088. // returns bit field: POLLIN|POLLOUT|POLLERR|...
  1089. FDList_t *fdl, // valid socket list
  1090. int sock, // socket to look for
  1091. uint poll_index // if use_poll: use the index for a fast search
  1092. );
  1093. //-----------------------------------------------------------------------------
  1094. // use select() or poll()
  1095. int WaitFDList ( FDList_t *fdl );
  1096. // use pselect() or ppoll()
  1097. int PWaitFDList ( FDList_t *fdl, const sigset_t *sigmask );
  1098. // return ptr to file path, if begins with 1 of: file: unix: / ./ ../
  1099. ccp CheckUnixSocketPath
  1100. (
  1101. ccp src, // NULL or source path to analyse
  1102. int tolerance // <1: 'unix:', 'file:', '/', './' and '../' detected
  1103. // 1: not 'NAME:' && at relast one '/'
  1104. // 2: not 'NAME:'
  1105. );
  1106. // return mem_t to file path, if begins with 1 of: file: unix: / ./ ../
  1107. mem_t CheckUnixSocketPathMem
  1108. (
  1109. mem_t src, // NULL or source path to analyse
  1110. int tolerance // <1: 'unix:', 'file:', '/', './' and '../' detected
  1111. // 1: not 'NAME:' && at relast one '/'
  1112. // 2: not 'NAME:'
  1113. );
  1114. //
  1115. ///////////////////////////////////////////////////////////////////////////////
  1116. /////////////// Catch Output ///////////////
  1117. ///////////////////////////////////////////////////////////////////////////////
  1118. struct CatchOutput_t;
  1119. typedef int (*CatchOutputFunc)
  1120. (
  1121. struct CatchOutput_t *ctrl, // control struct incl. data
  1122. int call_mode // 0:init, 1:new data, 2:term
  1123. );
  1124. ///////////////////////////////////////////////////////////////////////////////
  1125. typedef struct CatchOutput_t
  1126. {
  1127. int mode; // -1: disabled, 1:stdout, 2:stderr
  1128. int pipe_fd[2]; // pipe
  1129. CatchOutputFunc func; // function
  1130. GrowBuffer_t buf; // output buffer
  1131. void *user_ptr; // pointer by user
  1132. }
  1133. CatchOutput_t;
  1134. ///////////////////////////////////////////////////////////////////////////////
  1135. ///////////////////////////////////////////////////////////////////////////////
  1136. int CatchIgnoreOutput
  1137. (
  1138. struct CatchOutput_t *ctrl, // control struct incl. data
  1139. int call_mode // 0:init, 1:new data, 2:term
  1140. );
  1141. //-----------------------------------------------------------------------------
  1142. void ResetCatchOutput ( CatchOutput_t *co, uint n );
  1143. //-----------------------------------------------------------------------------
  1144. enumError CatchOutput
  1145. (
  1146. ccp command, // command to execute
  1147. int argc, // num(arguments) in 'argv'; -1: argv is NULL terminated
  1148. char *const* argv, // list of arguments
  1149. CatchOutputFunc stdout_func, // NULL or function to catch stdout
  1150. CatchOutputFunc stderr_func, // NULL or function to catch stderr
  1151. void *user_ptr, // NULL or user defined parameter
  1152. bool silent // true: suppress error messages
  1153. );
  1154. //-----------------------------------------------------------------------------
  1155. enumError CatchOutputLine
  1156. (
  1157. ccp command_line, // command line to execute
  1158. CatchOutputFunc stdout_func, // NULL or function to catch stdout
  1159. CatchOutputFunc stderr_func, // NULL or function to catch stderr
  1160. void *user_ptr, // NULL or user defined parameter
  1161. bool silent // true: suppress error messages
  1162. );
  1163. //
  1164. ///////////////////////////////////////////////////////////////////////////////
  1165. /////////////// scan sections ///////////////
  1166. ///////////////////////////////////////////////////////////////////////////////
  1167. typedef struct SectionInfo_t
  1168. {
  1169. FILE *f; // source file
  1170. ccp section; // section name, alloced
  1171. ccp path; // path name, NULL or alloced
  1172. int index; // index of section, -1 if not available
  1173. ParamField_t param; // parameter list
  1174. void *user_param; // user defined parameter
  1175. }
  1176. SectionInfo_t;
  1177. typedef int (*SectionFunc) ( SectionInfo_t *si );
  1178. ///////////////////////////////////////////////////////////////////////////////
  1179. bool FindSection
  1180. (
  1181. // search file until next section found
  1182. // => read line and store data into 'si'
  1183. // => return TRUE, if section found
  1184. SectionInfo_t *si, // valid section info
  1185. char *buf, // use this buffer for line scanning
  1186. uint buf_size, // size of 'buf'
  1187. bool scan_buf // true: buffer contains already a valid
  1188. // and NULL terminated line
  1189. );
  1190. int ScanSections
  1191. (
  1192. // return the last returned value by On*()
  1193. FILE *f, // source file
  1194. SectionFunc OnSection, // not NULL: call this function for each section
  1195. // on result: <0: abort, 0:next section, 1:scan param
  1196. SectionFunc OnParams, // not NULL: call this function after param scan
  1197. // on result: <0: abort, continue
  1198. void *user_param // user defined parameter
  1199. );
  1200. //
  1201. ///////////////////////////////////////////////////////////////////////////////
  1202. /////////////// scan socket type ///////////////
  1203. ///////////////////////////////////////////////////////////////////////////////
  1204. // [[socket_info_t]]
  1205. #define AF_INET_ANY (AF_INET6+100)
  1206. typedef struct socket_info_t
  1207. {
  1208. bool is_valid; // true: structure is valid
  1209. int sock; // -1 or used socket
  1210. int protocol; // -1 | AF_UNIX | AF_INET | AF_INET6 | AF_INET_ANY
  1211. int type; // -1 | SOCK_STREAM | SOCK_DGRAM | SOCK_RAW | SOCK_SEQPACKET
  1212. ccp address; // NULL or pointer to relevant address or path
  1213. bool alloced; // true: address is alloced
  1214. }
  1215. socket_info_t;
  1216. ///////////////////////////////////////////////////////////////////////////////
  1217. static inline void InitializeSocketInfo ( socket_info_t *si )
  1218. {
  1219. DASSERT(si);
  1220. memset(si,0,sizeof(*si));
  1221. si->sock = si->protocol = si->type = -1;
  1222. }
  1223. ///////////////////////////////////////////////////////////////////////////////
  1224. static inline void ResetSocketInfo ( socket_info_t *si )
  1225. {
  1226. if (si)
  1227. {
  1228. if ( si->alloced )
  1229. FreeString(si->address);
  1230. InitializeSocketInfo(si);
  1231. }
  1232. }
  1233. ///////////////////////////////////////////////////////////////////////////////
  1234. bool ScanSocketInfo
  1235. (
  1236. // Syntax: [ PREFIX ',' ]... [ PREFIX ':' ] address
  1237. // returns TRUE, if a protocol or a type is found
  1238. socket_info_t *si, // result, not NULL, will be initialized
  1239. ccp address, // address to analyze
  1240. uint tolerance // tolerace:
  1241. // 0: invalid without prefix
  1242. // 1: analyse beginning of address part:
  1243. // '/' or './' or '../' -> AF_UNIX
  1244. // 2: estimate type
  1245. // '/' before first ':' -> AF_UNIX
  1246. // 1.2 | 1.2.3 | 1.2.3.4 -> AF_INET
  1247. // a HEX:IP combi -> AF_INET6
  1248. // domain name -> AF_INET_ANY
  1249. );
  1250. ///////////////////////////////////////////////////////////////////////////////
  1251. bool GetSocketInfoBySocket
  1252. (
  1253. // returns TRUE, if infos retrived
  1254. socket_info_t *si, // result, not NULL, will be initialized
  1255. int sock, // socket id, maybe -1
  1256. bool get_name // true: alloc 'address' and copy name
  1257. // -> call ResetSocketInfo() to free mem
  1258. );
  1259. ///////////////////////////////////////////////////////////////////////////////
  1260. // returns a static string
  1261. ccp PrintSocketInfo ( int protocol, int type );
  1262. //
  1263. ///////////////////////////////////////////////////////////////////////////////
  1264. /////////////// stat_file_count_t ///////////////
  1265. ///////////////////////////////////////////////////////////////////////////////
  1266. // [[stat_file_count_t]]
  1267. typedef struct stat_file_count_t
  1268. {
  1269. uint cur_files; // currently open files
  1270. uint max_files; // max open files
  1271. uint cur_limit; // current limit
  1272. uint max_limit; // max limit
  1273. }
  1274. stat_file_count_t;
  1275. //-----------------------------------------------------------------------------
  1276. extern stat_file_count_t stat_file_count;
  1277. uint CountOpenFiles(void);
  1278. void RegisterFileId ( int fd );
  1279. void UpdateOpenFiles ( bool count_current );
  1280. uint SetOpenFilesLimit ( uint limit );
  1281. ccp PrintOpenFiles ( bool count_current ); // print to circ buffer
  1282. //
  1283. ///////////////////////////////////////////////////////////////////////////////
  1284. /////////////// PrintScript ///////////////
  1285. ///////////////////////////////////////////////////////////////////////////////
  1286. // [[PrintScriptFF]] // FF = File Format
  1287. typedef enum PrintScriptFF
  1288. {
  1289. PSFF_UNKNOWN, // always 0
  1290. PSFF_ASSIGN,
  1291. PSFF_CONFIG,
  1292. PSFF_JSON,
  1293. PSFF_BASH,
  1294. PSFF_SH,
  1295. PSFF_PHP,
  1296. PSFF_MAKEDOC,
  1297. PSFF_C,
  1298. }
  1299. PrintScriptFF;
  1300. ccp GetNamePSFF ( PrintScriptFF fform );
  1301. //-----------------------------------------------------------------------------
  1302. // [[PrintScript_t]]
  1303. typedef struct PrintScript_t
  1304. {
  1305. FILE *f; // valid output file
  1306. PrintScriptFF fform; // output: file format
  1307. ccp var_name; // NULL or variable name for result
  1308. ccp var_prefix; // NULL or prefix for member names
  1309. int var_size; // if > 0: print size of var name (some 'fform' only)
  1310. int eq_tabstop; // if > 0: indent '=' to set tabstop (some 'fform' only)
  1311. LowerUpper_t force_case; // change case of var names if not LOUP_AUTO
  1312. bool create_array; // true: create arrays
  1313. bool auto_quote; // true: detect quotes and use EscapeString()
  1314. bool add_index; // true: add index to varname
  1315. bool ena_empty; // true: enable empty lines
  1316. bool ena_comments; // true: enable comments
  1317. uint count; // number of printed records (used for seoarators)
  1318. uint index; // index for array operations
  1319. char sep[2]; // separator for JSON
  1320. char prefix[100]; // var name prefix
  1321. ccp boc; // begin of comment
  1322. }
  1323. PrintScript_t;
  1324. //-----------------------------------------------------------------------------
  1325. static inline void InitializePrintScript ( PrintScript_t *ps )
  1326. { DASSERT(ps); memset(ps,0,sizeof(*ps)); }
  1327. static inline void ResetPrintScript ( PrintScript_t *ps )
  1328. { DASSERT(ps); memset(ps,0,sizeof(*ps)); }
  1329. ///////////////////////////////////////////////////////////////////////////////
  1330. void PrintScriptHeader ( PrintScript_t *ps );
  1331. void PrintScriptFooter ( PrintScript_t *ps );
  1332. int PutScriptVars
  1333. (
  1334. PrintScript_t *ps, // valid control struct
  1335. uint mode, // bit field: 1=open var, 2:close var
  1336. ccp text // text with lines of format NAME=VALUE
  1337. );
  1338. int PrintScriptVars
  1339. (
  1340. PrintScript_t *ps, // valid control struct
  1341. uint mode, // bit field: 1=open var, 2:close var
  1342. ccp format, // format of message
  1343. ... // arguments
  1344. )
  1345. __attribute__ ((__format__(__printf__,3,4)));
  1346. //
  1347. ///////////////////////////////////////////////////////////////////////////////
  1348. /////////////// CpuStatus_t ///////////////
  1349. ///////////////////////////////////////////////////////////////////////////////
  1350. // [[CpuStatus_t]]
  1351. typedef struct CpuStatus_t
  1352. {
  1353. bool valid; // TRUE: data valid (setup done)
  1354. u_nsec_t nsec; // GetTimerNSec()
  1355. int clock_ticks; // number of clock ticks per second
  1356. int n_cpu; // total number of cpus
  1357. // all times in 1e4 ticks per second (in 0.01%)
  1358. u64 user; // time spent in user mode.
  1359. u64 nice; // time spent in user mode with low priority.
  1360. u64 system; // time spent in system mode.
  1361. u64 idle; // time spent in the idle task.
  1362. int running_proc; // currently runnable processes
  1363. int total_proc; // currently total processes
  1364. union
  1365. {
  1366. struct
  1367. {
  1368. double loadavg_1m; // load average last minute
  1369. double loadavg_5m; // load average last 5 minutes
  1370. double loadavg_15m; // load average last 12 minutes
  1371. };
  1372. double loadavg[3]; // load average as array
  1373. };
  1374. }
  1375. CpuStatus_t;
  1376. //-----------------------------------------------------------------------------
  1377. // prev_cpuinfo == NULL: get absolute values
  1378. // prev_cpuinfo != NULL: update 'prev_cpuinfo' and get delta
  1379. CpuStatus_t GetCpuStatus ( CpuStatus_t * prev_cpuinfo );
  1380. ccp PrintCpuStatus ( const CpuStatus_t * cpuinfo );
  1381. //
  1382. ///////////////////////////////////////////////////////////////////////////////
  1383. /////////////// MemoryStatus_t ///////////////
  1384. ///////////////////////////////////////////////////////////////////////////////
  1385. // [[MemoryStatus_t]]
  1386. typedef struct MemoryStatus_t
  1387. {
  1388. // man 5 proc | oo +//proc/meminfo
  1389. u64 total; // Total usable RAM.
  1390. u64 free; // The sum of LowFree + HighFree.
  1391. u64 avail; // An estimate of available memory for starting new applications.
  1392. u64 buffers; // Relatively temporary storage.
  1393. u64 cached; // In-memory cache for files read from the disk.
  1394. u64 used; // = total - free - buffers - cached;
  1395. }
  1396. MemoryStatus_t;
  1397. //-----------------------------------------------------------------------------
  1398. MemoryStatus_t GetMemoryStatus(void);
  1399. ccp PrintMemoryStatus ( const MemoryStatus_t * ms );
  1400. //
  1401. ///////////////////////////////////////////////////////////////////////////////
  1402. /////////////// E N D ///////////////
  1403. ///////////////////////////////////////////////////////////////////////////////
  1404. #endif // DCLIB_FILE_H