1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4/*
5 Title: OS Abstraction
6*/
7
8#ifndef BASE_SYSTEM_H
9#define BASE_SYSTEM_H
10
11#include "detect.h"
12#include "types.h"
13
14#ifndef __USE_GNU
15#define __USE_GNU
16#endif
17
18#include <chrono>
19#include <cinttypes>
20#include <cstdarg>
21#include <cstdint>
22#include <cstring>
23#include <ctime>
24#include <functional>
25#include <mutex>
26#include <optional>
27#include <string>
28
29#ifdef __MINGW32__
30#undef PRId64
31#undef PRIu64
32#undef PRIX64
33#define PRId64 "I64d"
34#define PRIu64 "I64u"
35#define PRIX64 "I64X"
36#define PRIzu "Iu"
37#else
38#define PRIzu "zu"
39#endif
40
41#ifdef CONF_FAMILY_UNIX
42#include <sys/un.h>
43#endif
44
45#ifdef CONF_PLATFORM_LINUX
46#include <netinet/in.h>
47#include <sys/socket.h>
48#endif
49
50#if __cplusplus >= 201703L
51#define MAYBE_UNUSED [[maybe_unused]]
52#elif defined(__GNUC__)
53#define MAYBE_UNUSED __attribute__((unused))
54#else
55#define MAYBE_UNUSED
56#endif
57
58/**
59 * @defgroup Debug
60 *
61 * Utilities for debugging.
62 */
63
64/**
65 * @ingroup Debug
66 *
67 * Breaks into the debugger based on a test.
68 *
69 * @param test Result of the test.
70 * @param msg Message that should be printed if the test fails.
71 *
72 * @remark Also works in release mode.
73 *
74 * @see dbg_break
75 */
76#define dbg_assert(test, msg) dbg_assert_imp(__FILE__, __LINE__, test, msg)
77void dbg_assert_imp(const char *filename, int line, bool test, const char *msg);
78
79#ifdef __clang_analyzer__
80#include <cassert>
81#undef dbg_assert
82#define dbg_assert(test, msg) assert(test)
83#endif
84
85#ifdef __GNUC__
86#define GNUC_ATTRIBUTE(x) __attribute__(x)
87#else
88#define GNUC_ATTRIBUTE(x)
89#endif
90
91/**
92 * Checks whether the program is currently shutting down due to a failed
93 * assert.
94 *
95 * @ingroup Debug
96 *
97 * @return indication whether the program is currently shutting down due to a
98 * failed assert.
99 */
100bool dbg_assert_has_failed();
101
102/**
103 * Breaks into the debugger.
104 *
105 * @ingroup Debug
106 * @remark Also works in release mode.
107 *
108 * @see dbg_assert
109 */
110#if defined(__cplusplus)
111[[noreturn]]
112#endif
113void
114dbg_break();
115
116typedef std::function<void(const char *message)> DBG_ASSERT_HANDLER;
117void dbg_assert_set_handler(DBG_ASSERT_HANDLER handler);
118
119/**
120 * Prints a debug message.
121 *
122 * @ingroup Debug
123 *
124 * @param sys A string that describes what system the message belongs to.
125 * @param fmt A printf styled format string.
126 *
127 * @remark Also works in release mode.
128 *
129 * @see dbg_assert
130 */
131void dbg_msg(const char *sys, const char *fmt, ...)
132 GNUC_ATTRIBUTE((format(printf, 2, 3)));
133
134/**
135 * @defgroup Memory
136 * Memory management utilities.
137 */
138
139/**
140 * Copies a a memory block.
141 *
142 * @ingroup Memory
143 *
144 * @param dest Destination.
145 * @param source Source to copy.
146 * @param size Size of the block to copy.
147 *
148 * @remark This functions DOES NOT handle cases where the source and destination is overlapping.
149 *
150 * @see mem_move
151 */
152void mem_copy(void *dest, const void *source, size_t size);
153
154/**
155 * Copies a a memory block.
156 *
157 * @ingroup Memory
158 *
159 * @param dest Destination.
160 * @param source Source to copy.
161 * @param size Size of the block to copy.
162 *
163 * @remark This functions handles the cases where the source and destination is overlapping.
164 *
165 * @see mem_copy
166 */
167void mem_move(void *dest, const void *source, size_t size);
168
169/**
170 * Sets a complete memory block to 0.
171 *
172 * @ingroup Memory
173 *
174 * @param block Pointer to the block to zero out.
175 * @param size Size of the block.
176 */
177template<typename T>
178inline void mem_zero(T *block, size_t size)
179{
180 static_assert((std::is_trivially_constructible<T>::value && std::is_trivially_destructible<T>::value) || std::is_fundamental<T>::value);
181 memset(block, 0, size);
182}
183
184/**
185 * Compares two blocks of memory
186 *
187 * @ingroup Memory
188 *
189 * @param a First block of data
190 * @param b Second block of data
191 * @param size Size of the data to compare
192 *
193 * @return < 0 - Block a is less than block b.
194 * @return 0 - Block a is equal to block b.
195 * @return > 0 - Block a is greater than block b.
196 */
197int mem_comp(const void *a, const void *b, size_t size);
198
199/**
200 * Checks whether a block of memory contains null bytes.
201 *
202 * @ingroup Memory
203 *
204 * @param block Pointer to the block to check for nulls.
205 * @param size Size of the block.
206 *
207 * @return true if the block has a null byte, false otherwise.
208 */
209bool mem_has_null(const void *block, size_t size);
210
211/**
212 * @defgroup File-IO
213 *
214 * I/O related operations.
215 */
216
217/**
218 * @ingroup File-IO
219 */
220enum
221{
222 IOFLAG_READ = 1,
223 IOFLAG_WRITE = 2,
224 IOFLAG_APPEND = 4,
225 IOFLAG_SKIP_BOM = 8,
226
227 IOSEEK_START = 0,
228 IOSEEK_CUR = 1,
229 IOSEEK_END = 2,
230};
231
232/**
233 * Opens a file.
234 *
235 * @ingroup File-IO
236 *
237 * @param File to open.
238 * @param flags A set of IOFLAG flags.
239 *
240 * @sa IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND, IOFLAG_SKIP_BOM.
241 *
242 * @return A handle to the file on success and 0 on failure.
243 *
244 */
245IOHANDLE io_open(const char *filename, int flags);
246
247/**
248 * Reads data into a buffer from a file.
249 *
250 * @ingroup File-IO
251 *
252 * @param io Handle to the file to read data from.
253 * @param buffer Pointer to the buffer that will receive the data.
254 * @param size Number of bytes to read from the file.
255 *
256 * @return Number of bytes read.
257 *
258 */
259unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
260
261/**
262 * Reads the rest of the file into a buffer.
263 *
264 * @ingroup File-IO
265 *
266 * @param io Handle to the file to read data from.
267 * @param result Receives the file's remaining contents.
268 * @param result_len Receives the file's remaining length.
269 *
270 * @remark Does NOT guarantee that there are no internal null bytes.
271 * @remark The result must be freed after it has been used.
272 */
273void io_read_all(IOHANDLE io, void **result, unsigned *result_len);
274
275/**
276 * Reads the rest of the file into a zero-terminated buffer with
277 * no internal null bytes.
278 *
279 * @ingroup File-IO
280 *
281 * @param io Handle to the file to read data from.
282 *
283 * @return The file's remaining contents or null on failure.
284 *
285 * @remark Guarantees that there are no internal null bytes.
286 * @remark Guarantees that result will contain zero-termination.
287 * @remark The result must be freed after it has been used.
288 */
289char *io_read_all_str(IOHANDLE io);
290
291/**
292 * Skips data in a file.
293 *
294 * @ingroup File-IO
295 *
296 * @param io Handle to the file.
297 * @param size Number of bytes to skip.
298 *
299 * @return 0 on success.
300 */
301int io_skip(IOHANDLE io, int size);
302
303/**
304 * Writes data from a buffer to file.
305 *
306 * @ingroup File-IO
307 *
308 * @param io Handle to the file.
309 * @param buffer Pointer to the data that should be written.
310 * @param size Number of bytes to write.
311 *
312 * @return Number of bytes written.
313 */
314unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
315
316/**
317 * Writes a platform dependent newline to file.
318 *
319 * @ingroup File-IO
320 *
321 * @param io Handle to the file.
322 *
323 * @return true on success, false on failure.
324 */
325bool io_write_newline(IOHANDLE io);
326
327/**
328 * Seeks to a specified offset in the file.
329 *
330 * @ingroup File-IO
331 *
332 * @param io Handle to the file.
333 * @param offset Offset from pos to stop.
334 * @param origin Position to start searching from.
335 *
336 * @return 0 on success.
337 */
338int io_seek(IOHANDLE io, int offset, int origin);
339
340/**
341 * Gets the current position in the file.
342 *
343 * @ingroup File-IO
344 *
345 * @param io Handle to the file.
346 *
347 * @return The current position. @c -1L if an error occurred.
348 */
349long int io_tell(IOHANDLE io);
350
351/**
352 * Gets the total length of the file. Resetting cursor to the beginning
353 *
354 * @ingroup File-IO
355 *
356 * @param io Handle to the file.
357 *
358 * @return The total size. @c -1L if an error occurred.
359 */
360long int io_length(IOHANDLE io);
361
362/**
363 * Closes a file.
364 *
365 * @ingroup File-IO
366 *
367 * @param io Handle to the file.
368 *
369 * @return 0 on success.
370 */
371int io_close(IOHANDLE io);
372
373/**
374 * Empties all buffers and writes all pending data.
375 *
376 * @ingroup File-IO
377 *
378 * @param io Handle to the file.
379 *
380 * @return 0 on success.
381 */
382int io_flush(IOHANDLE io);
383
384/**
385 * Synchronize file changes to disk.
386 *
387 * @ingroup File-IO
388 *
389 * @param io Handle to the file.
390 *
391 * @return 0 on success.
392 */
393int io_sync(IOHANDLE io);
394
395/**
396 * Checks whether an error occurred during I/O with the file.
397 *
398 * @ingroup File-IO
399 *
400 * @param io Handle to the file.
401 *
402 * @return nonzero on error, 0 otherwise.
403 */
404int io_error(IOHANDLE io);
405
406/**
407 * @ingroup File-IO
408 * @return An <IOHANDLE> to the standard input.
409 */
410IOHANDLE io_stdin();
411
412/**
413 * @ingroup File-IO
414 * @return An <IOHANDLE> to the standard output.
415 */
416IOHANDLE io_stdout();
417
418/**
419 * @ingroup File-IO
420 * @return An <IOHANDLE> to the standard error.
421 */
422IOHANDLE io_stderr();
423
424/**
425 * @ingroup File-IO
426 * @return An <IOHANDLE> to the current executable.
427 */
428IOHANDLE io_current_exe();
429
430typedef struct ASYNCIO ASYNCIO;
431
432/**
433 * Wraps a @link IOHANDLE @endlink for asynchronous writing.
434 *
435 * @ingroup File-IO
436 *
437 * @param io Handle to the file.
438 *
439 * @return The handle for asynchronous writing.
440 *
441 */
442ASYNCIO *aio_new(IOHANDLE io);
443
444/**
445 * Locks the ASYNCIO structure so it can't be written into by
446 * other threads.
447 *
448 * @ingroup File-IO
449 *
450 * @param aio Handle to the file.
451 */
452void aio_lock(ASYNCIO *aio);
453
454/**
455 * Unlocks the ASYNCIO structure after finishing the contiguous
456 * write.
457 *
458 * @ingroup File-IO
459 *
460 * @param aio Handle to the file.
461 */
462void aio_unlock(ASYNCIO *aio);
463
464/**
465 * Queues a chunk of data for writing.
466 *
467 * @ingroup File-IO
468 *
469 * @param aio Handle to the file.
470 * @param buffer Pointer to the data that should be written.
471 * @param size Number of bytes to write.
472 */
473void aio_write(ASYNCIO *aio, const void *buffer, unsigned size);
474
475/**
476 * Queues a newline for writing.
477 *
478 * @ingroup File-IO
479 *
480 * @param aio Handle to the file.
481 *
482 */
483void aio_write_newline(ASYNCIO *aio);
484
485/**
486 * Queues a chunk of data for writing. The ASYNCIO struct must be
487 * locked using @link aio_lock @endlink first.
488 *
489 * @ingroup File-IO
490 *
491 * @param aio Handle to the file.
492 * @param buffer Pointer to the data that should be written.
493 * @param size Number of bytes to write.
494 *
495 */
496void aio_write_unlocked(ASYNCIO *aio, const void *buffer, unsigned size);
497
498/**
499 * Queues a newline for writing. The ASYNCIO struct must be locked
500 * using @link aio_lock @endlink first.
501 *
502 * @ingroup File-IO
503 *
504 * @param aio Handle to the file.
505 *
506 */
507void aio_write_newline_unlocked(ASYNCIO *aio);
508
509/**
510 * Checks whether errors have occurred during the asynchronous
511 * writing.
512 *
513 * Call this function regularly to see if there are errors. Call
514 * this function after <aio_wait> to see if the process of writing
515 * to the file succeeded.
516 *
517 * @ingroup File-IO
518 *
519 * @param aio Handle to the file.
520 *
521 * @eturn 0 if no error occurred, and nonzero on error.
522 *
523 */
524int aio_error(ASYNCIO *aio);
525
526/**
527 * Queues file closing.
528 *
529 * @ingroup File-IO
530 *
531 * @param aio Handle to the file.
532 *
533 */
534void aio_close(ASYNCIO *aio);
535
536/**
537 * Wait for the asynchronous operations to complete.
538 *
539 * @ingroup File-IO
540 *
541 * @param aio Handle to the file.
542 *
543 */
544void aio_wait(ASYNCIO *aio);
545
546/**
547 * Frees the resources associated to the asynchronous file handle.
548 *
549 * @ingroup File-IO
550 *
551 * @param aio Handle to the file.
552 *
553 */
554void aio_free(ASYNCIO *aio);
555
556/**
557 * @defgroup Threads
558 * Threading related functions.
559 *
560 * @see Locks
561 * @see Semaphore
562 */
563
564/**
565 * Creates a new thread.
566 *
567 * @ingroup Threads
568 *
569 * @param threadfunc Entry point for the new thread.
570 * @param user Pointer to pass to the thread.
571 * @param name Name describing the use of the thread.
572 *
573 * @return Handle for the new thread.
574 */
575void *thread_init(void (*threadfunc)(void *), void *user, const char *name);
576
577/**
578 * Waits for a thread to be done or destroyed.
579 *
580 * @ingroup Threads
581 *
582 * @param thread Thread to wait for.
583 */
584void thread_wait(void *thread);
585
586/**
587 * Yield the current thread's execution slice.
588 *
589 * @ingroup Threads
590 */
591void thread_yield();
592
593/**
594 * Puts the thread in the detached state, guaranteeing that
595 * resources of the thread will be freed immediately when the
596 * thread terminates.
597 *
598 * @ingroup Threads
599 *
600 * @param thread Thread to detach.
601 */
602void thread_detach(void *thread);
603
604/**
605 * Creates a new thread and detaches it.
606 *
607 * @ingroup Threads
608 *
609 * @param threadfunc Entry point for the new thread.
610 * @param user Pointer to pass to the thread.
611 * @param name Name describing the use of the thread.
612 */
613void thread_init_and_detach(void (*threadfunc)(void *), void *user, const char *name);
614
615/**
616 * @defgroup Semaphore
617 * @see Threads
618 */
619
620#if defined(CONF_FAMILY_WINDOWS)
621typedef void *SEMAPHORE;
622#elif defined(CONF_PLATFORM_MACOS)
623#include <semaphore.h>
624typedef sem_t *SEMAPHORE;
625#elif defined(CONF_FAMILY_UNIX)
626#include <semaphore.h>
627typedef sem_t SEMAPHORE;
628#else
629#error not implemented on this platform
630#endif
631
632/**
633 * @ingroup Semaphore
634 */
635void sphore_init(SEMAPHORE *sem);
636/**
637 * @ingroup Semaphore
638 */
639void sphore_wait(SEMAPHORE *sem);
640/**
641 * @ingroup Semaphore
642 */
643void sphore_signal(SEMAPHORE *sem);
644/**
645 * @ingroup Semaphore
646 */
647void sphore_destroy(SEMAPHORE *sem);
648
649/**
650 * @defgroup Time
651 *
652 * Time utilities.
653 */
654
655/**
656 * @ingroup Time
657 */
658void set_new_tick();
659
660/**
661 * Fetches a sample from a high resolution timer.
662 *
663 * @ingroup Time
664 *
665 * @return Current value of the timer.
666 *
667 * @remark To know how fast the timer is ticking, see @link time_freq @endlink.
668 *
669 * @see time_freq
670 */
671int64_t time_get_impl();
672
673/**
674 * Fetches a sample from a high resolution timer.
675 *
676 * @ingroup Time
677 *
678 * @return Current value of the timer.
679 *
680 * @remark To know how fast the timer is ticking, see @link time_freq @endlink.
681 * @remark Uses @link time_get_impl @endlink to fetch the sample.
682 *
683 * @see time_freq time_get_impl
684 */
685int64_t time_get();
686
687/**
688 * @ingroup Time
689 *
690 * @return The frequency of the high resolution timer.
691 */
692int64_t time_freq();
693
694/**
695 * Retrieves the current time as a UNIX timestamp
696 *
697 * @ingroup Time
698 *
699 * @return The time as a UNIX timestamp
700 */
701int64_t time_timestamp();
702
703/**
704 * Retrieves the hours since midnight (0..23)
705 *
706 * @ingroup Time
707 *
708 * @return The current hour of the day
709 */
710int time_houroftheday();
711
712/**
713 * @ingroup Time
714 */
715enum ETimeSeason
716{
717 SEASON_SPRING = 0,
718 SEASON_SUMMER,
719 SEASON_AUTUMN,
720 SEASON_WINTER,
721 SEASON_EASTER,
722 SEASON_HALLOWEEN,
723 SEASON_XMAS,
724 SEASON_NEWYEAR
725};
726
727/**
728 * Retrieves the current season of the year.
729 *
730 * @ingroup Time
731 *
732 * @return One of the SEASON_* enum literals
733 *
734 * @see SEASON_SPRING
735 */
736ETimeSeason time_season();
737
738/**
739 * @defgroup Network-General
740 */
741
742extern const NETADDR NETADDR_ZEROED;
743
744/**
745 * @ingroup Network-General
746 */
747
748#ifdef CONF_FAMILY_UNIX
749/**
750 * @ingroup Network-General
751 */
752typedef int UNIXSOCKET;
753/**
754 * @ingroup Network-General
755 */
756typedef struct sockaddr_un UNIXSOCKETADDR;
757#endif
758
759/**
760 * Initiates network functionality.
761 *
762 * @ingroup Network-General
763 *
764 * @remark You must call this function before using any other network functions.
765 */
766void net_init();
767
768/*
769 Function: net_host_lookup
770 Does a hostname lookup by name and fills out the passed
771 NETADDR struct with the received details.
772
773 Returns:
774 0 on success.
775*/
776int net_host_lookup(const char *hostname, NETADDR *addr, int types);
777
778/**
779 * Compares two network addresses.
780 *
781 * @ingroup Network-General
782 *
783 * @param a Address to compare
784 * @param b Address to compare to.
785 *
786 * @return `< 0` - Address a is less than address b
787 * @return `0` - Address a is equal to address b
788 * @return `> 0` - Address a is greater than address b
789 */
790int net_addr_comp(const NETADDR *a, const NETADDR *b);
791
792/**
793 * Compares two network addresses ignoring port.
794 *
795 * @ingroup Network-General
796 *
797 * @param a Address to compare
798 * @param b Address to compare to.
799 *
800 * @return `< 0` - Address a is less than address b
801 * @return `0` - Address a is equal to address b
802 * @return `> 0` - Address a is greater than address b
803 */
804int net_addr_comp_noport(const NETADDR *a, const NETADDR *b);
805
806/**
807 * Turns a network address into a representative string.
808 *
809 * @ingroup Network-General
810 *
811 * @param addr Address to turn into a string.
812 * @param string Buffer to fill with the string.
813 * @param max_length Maximum size of the string.
814 * @param add_port add port to string or not
815 *
816 * @remark The string will always be zero terminated
817 */
818void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port);
819
820/**
821 * Turns url string into a network address struct.
822 * The url format is tw-0.6+udp://{ipaddr}[:{port}]
823 * ipaddr: can be ipv4 or ipv6
824 * port: is a optional internet protocol port
825 *
826 * This format is used for parsing the master server, be careful before changing it.
827 *
828 * Examples:
829 * tw-0.6+udp://127.0.0.1
830 * tw-0.6+udp://127.0.0.1:8303
831 *
832 * @param addr Address to fill in.
833 * @param string String to parse.
834 * @param host_buf Pointer to a buffer to write the host to
835 * It will include the port if one is included in the url
836 * It can also be set to NULL then it will be ignored
837 * @param host_buf_size Size of the host buffer or 0 if no host_buf pointer is given
838 *
839 * @return 0 on success,
840 * positive if the input wasn't a valid DDNet URL,
841 * negative if the input is a valid DDNet URL but the host part was not a valid IPv4/IPv6 address
842 */
843int net_addr_from_url(NETADDR *addr, const char *string, char *host_buf, size_t host_buf_size);
844
845/**
846 * Turns string into a network address.
847 *
848 * @param addr Address to fill in.
849 * @param string String to parse.
850 *
851 * @return 0 on success
852 */
853int net_addr_from_str(NETADDR *addr, const char *string);
854
855/**
856 * @defgroup Network-UDP
857 * @ingroup Network-General
858 */
859
860/*
861 Function: net_socket_type
862 Determine a socket's type.
863
864 Parameters:
865 sock - Socket whose type should be determined.
866
867 Returns:
868 The socket type, a bitset of `NETTYPE_IPV4`, `NETTYPE_IPV6` and
869 `NETTYPE_WEBSOCKET_IPV4`.
870*/
871int net_socket_type(NETSOCKET sock);
872
873/*
874 Function: net_udp_create
875 Creates a UDP socket and binds it to a port.
876
877 Parameters:
878 bindaddr - Address to bind the socket to.
879
880 Returns:
881 On success it returns an handle to the socket. On failure it
882 returns NETSOCKET_INVALID.
883*/
884NETSOCKET net_udp_create(NETADDR bindaddr);
885
886/**
887 * Sends a packet over an UDP socket.
888 *
889 * @ingroup Network-UDP
890 *
891 * @param sock Socket to use.
892 * @param addr Where to send the packet.
893 * @param data Pointer to the packet data to send.
894 * @param size Size of the packet.
895 *
896 * @return On success it returns the number of bytes sent. Returns -1
897 * on error.
898 */
899int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
900
901/*
902 Function: net_udp_recv
903 Receives a packet over an UDP socket.
904
905 Parameters:
906 sock - Socket to use.
907 addr - Pointer to an NETADDR that will receive the address.
908 data - Received data. Will be invalidated when this function is
909 called again.
910
911 Returns:
912 On success it returns the number of bytes received. Returns -1
913 on error.
914*/
915int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data);
916
917/**
918 * Closes an UDP socket.
919 *
920 * @ingroup Network-UDP
921 *
922 * @param sock Socket to close.
923 *
924 * @return 0 on success. -1 on error.
925 */
926int net_udp_close(NETSOCKET sock);
927
928/**
929 * @defgroup Network-TCP
930 * @ingroup Network-General
931 */
932
933/**
934 * Creates a TCP socket.
935 *
936 * @ingroup Network-TCP
937 *
938 * @param bindaddr Address to bind the socket to.
939 *
940 * @return On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID.
941 */
942NETSOCKET net_tcp_create(NETADDR bindaddr);
943
944/**
945 * Makes the socket start listening for new connections.
946 *
947 * @ingroup Network-TCP
948 *
949 * @param sock Socket to start listen to.
950 * @param backlog Size of the queue of incoming connections to keep.
951 *
952 * @return 0 on success.
953 */
954int net_tcp_listen(NETSOCKET sock, int backlog);
955
956/**
957 * Polls a listning socket for a new connection.
958 *
959 * @ingroup Network-TCP
960 *
961 * @param sock - Listning socket to poll.
962 * @param new_sock - Pointer to a socket to fill in with the new socket.
963 * @param addr - Pointer to an address that will be filled in the remote address (optional, can be NULL).
964 *
965 * @return A non-negative integer on success. Negative integer on failure.
966 */
967int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr);
968
969/**
970 * Connects one socket to another.
971 *
972 * @ingroup Network-TCP
973 *
974 * @param sock Socket to connect.
975 * @param addr Address to connect to.
976 *
977 * @return 0 on success.
978 *
979 */
980int net_tcp_connect(NETSOCKET sock, const NETADDR *addr);
981
982/**
983 * Sends data to a TCP stream.
984 *
985 * @ingroup Network-TCP
986 *
987 * @param sock Socket to send data to.
988 * @param data Pointer to the data to send.
989 * @param size Size of the data to send.
990 *
991 * @return Number of bytes sent. Negative value on failure.
992 */
993int net_tcp_send(NETSOCKET sock, const void *data, int size);
994
995/**
996 * Recvives data from a TCP stream.
997 *
998 * @ingroup Network-TCP
999 *
1000 * @param sock Socket to recvive data from.
1001 * @param data Pointer to a buffer to write the data to
1002 * @param max_size Maximum of data to write to the buffer.
1003 *
1004 * @return Number of bytes recvived. Negative value on failure. When in
1005 * non-blocking mode, it returns 0 when there is no more data to
1006 * be fetched.
1007 */
1008int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
1009
1010/**
1011 * Closes a TCP socket.
1012 *
1013 * @ingroup Network-TCP
1014 *
1015 * @param sock Socket to close.
1016 *
1017 * @return 0 on success. Negative value on failure.
1018 */
1019int net_tcp_close(NETSOCKET sock);
1020
1021#if defined(CONF_FAMILY_UNIX)
1022/**
1023 * @defgroup Network-Unix-Sockets
1024 * @ingroup Network-General
1025 */
1026
1027/**
1028 * Creates an unnamed unix datagram socket.
1029 *
1030 * @ingroup Network-Unix-Sockets
1031 *
1032 * @return On success it returns a handle to the socket. On failure it returns -1.
1033 */
1034UNIXSOCKET net_unix_create_unnamed();
1035
1036/**
1037 * Sends data to a Unix socket.
1038 *
1039 * @ingroup Network-Unix-Sockets
1040 *
1041 * @param sock Socket to use.
1042 * @param addr Where to send the packet.
1043 * @param data Pointer to the packet data to send.
1044 * @param size Size of the packet.
1045 *
1046 * @return Number of bytes sent. Negative value on failure.
1047 */
1048int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size);
1049
1050/**
1051 * Sets the unixsocketaddress for a path to a socket file.
1052 *
1053 * @ingroup Network-Unix-Sockets
1054 *
1055 * @param addr Pointer to the addressstruct to fill.
1056 * @param path Path to the (named) unix socket.
1057 */
1058void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path);
1059
1060/**
1061 * Closes a Unix socket.
1062 *
1063 * @ingroup Network-Unix-Sockets
1064 *
1065 * @param sock Socket to close.
1066 */
1067void net_unix_close(UNIXSOCKET sock);
1068
1069#elif defined(CONF_FAMILY_WINDOWS)
1070
1071/**
1072 * Formats a Windows error code as a human-readable string.
1073 *
1074 * @param error The Windows error code.
1075 *
1076 * @return A new std::string representing the error code.
1077 */
1078std::string windows_format_system_message(unsigned long error);
1079
1080#endif
1081
1082/**
1083 * @defgroup Strings
1084 *
1085 * String related functions.
1086 */
1087
1088/**
1089 * Appends a string to another.
1090 *
1091 * @ingroup Strings
1092 *
1093 * @param dst Pointer to a buffer that contains a string.
1094 * @param src String to append.
1095 * @param dst_size Size of the buffer of the dst string.
1096 *
1097 * @remark The strings are treated as zero-terminated strings.
1098 * @remark Guarantees that dst string will contain zero-termination.
1099 */
1100void str_append(char *dst, const char *src, int dst_size);
1101
1102/**
1103 * Appends a string to a fixed-size array of chars.
1104 *
1105 * @ingroup Strings
1106 *
1107 * @param dst Array that shall receive the string.
1108 * @param src String to append.
1109 *
1110 * @remark The strings are treated as zero-terminated strings.
1111 * @remark Guarantees that dst string will contain zero-termination.
1112 */
1113template<int N>
1114void str_append(char (&dst)[N], const char *src)
1115{
1116 str_append(dst, src, N);
1117}
1118
1119/**
1120 * Copies a string to another.
1121 *
1122 * @ingroup Strings
1123 *
1124 * @param dst Pointer to a buffer that shall receive the string.
1125 * @param src String to be copied.
1126 * @param dst_size Size of the buffer dst.
1127 *
1128 * @return Length of written string, even if it has been truncated
1129 *
1130 * @remark The strings are treated as zero-terminated strings.
1131 * @remark Guarantees that dst string will contain zero-termination.
1132 */
1133int str_copy(char *dst, const char *src, int dst_size);
1134
1135/**
1136 * Copies a string to a fixed-size array of chars.
1137 *
1138 * @ingroup Strings
1139 *
1140 * @param dst Array that shall receive the string.
1141 * @param src String to be copied.
1142 *
1143 * @remark The strings are treated as zero-terminated strings.
1144 * @remark Guarantees that dst string will contain zero-termination.
1145 */
1146template<int N>
1147void str_copy(char (&dst)[N], const char *src)
1148{
1149 str_copy(dst, src, N);
1150}
1151
1152/**
1153 * Truncates a utf8 encoded string to a given length.
1154 *
1155 * @ingroup Strings
1156 *
1157 * @param dst Pointer to a buffer that shall receive the string.
1158 * @param dst_size Size of the buffer dst.
1159 * @param str String to be truncated.
1160 * @param truncation_len Maximum codepoints in the returned string.
1161 *
1162 * @remark The strings are treated as utf8-encoded zero-terminated strings.
1163 * @remark Guarantees that dst string will contain zero-termination.
1164 */
1165void str_utf8_truncate(char *dst, int dst_size, const char *src, int truncation_len);
1166
1167/**
1168 * Truncates a string to a given length.
1169 *
1170 * @ingroup Strings
1171 *
1172 * @param dst Pointer to a buffer that shall receive the string.
1173 * @param dst_size Size of the buffer dst.
1174 * @param src String to be truncated.
1175 * @param truncation_len Maximum length of the returned string (not
1176 * counting the zero termination).
1177 *
1178 * @remark The strings are treated as zero-terminated strings.
1179 * @remark Guarantees that dst string will contain zero-termination.
1180 */
1181void str_truncate(char *dst, int dst_size, const char *src, int truncation_len);
1182
1183/**
1184 * Returns the length of a zero terminated string.
1185 *
1186 * @ingroup Strings
1187 *
1188 * @param str Pointer to the string.
1189 *
1190 * @return Length of string in bytes excluding the zero termination.
1191 */
1192int str_length(const char *str);
1193
1194/**
1195 * Performs printf formatting into a buffer.
1196 *
1197 * @ingroup Strings
1198 *
1199 * @param buffer Pointer to the buffer to receive the formatted string.
1200 * @param buffer_size Size of the buffer.
1201 * @param format printf formatting string.
1202 * @param args The variable argument list.
1203 *
1204 * @return Length of written string, even if it has been truncated.
1205 *
1206 * @remark See the C manual for syntax for the printf formatting string.
1207 * @remark The strings are treated as zero-terminated strings.
1208 * @remark Guarantees that buffer string will contain zero-termination.
1209 */
1210int str_format_v(char *buffer, int buffer_size, const char *format, va_list args)
1211 GNUC_ATTRIBUTE((format(printf, 3, 0)));
1212
1213/**
1214 * Performs printf formatting into a buffer.
1215 *
1216 * @ingroup Strings
1217 *
1218 * @param buffer Pointer to the buffer to receive the formatted string.
1219 * @param buffer_size Size of the buffer.
1220 * @param format printf formatting string.
1221 * @param ... Parameters for the formatting.
1222 *
1223 * @return Length of written string, even if it has been truncated.
1224 *
1225 * @remark See the C manual for syntax for the printf formatting string.
1226 * @remark The strings are treated as zero-terminated strings.
1227 * @remark Guarantees that buffer string will contain zero-termination.
1228 */
1229int str_format(char *buffer, int buffer_size, const char *format, ...)
1230 GNUC_ATTRIBUTE((format(printf, 3, 4)));
1231
1232#if !defined(CONF_DEBUG)
1233int str_format_int(char *buffer, size_t buffer_size, int value);
1234
1235template<typename... Args>
1236int str_format_opt(char *buffer, int buffer_size, const char *format, Args... args)
1237{
1238 return str_format(buffer, buffer_size, format, args...);
1239}
1240
1241template<>
1242inline int str_format_opt(char *buffer, int buffer_size, const char *format, int val)
1243{
1244 if(strcmp(format, "%d") == 0)
1245 {
1246 return str_format_int(buffer, buffer_size, val);
1247 }
1248 else
1249 {
1250 return str_format(buffer, buffer_size, format, val);
1251 }
1252}
1253
1254#define str_format str_format_opt
1255#endif
1256
1257/**
1258 * Trims specific number of words at the start of a string.
1259 *
1260 * @ingroup Strings
1261 *
1262 * @param str String to trim the words from.
1263 * @param words Count of words to trim.
1264 *
1265 * @return Trimmed string
1266 *
1267 * @remark The strings are treated as zero-terminated strings.
1268 * @remark Leading whitespace is always trimmed.
1269 */
1270const char *str_trim_words(const char *str, int words);
1271
1272/**
1273 * Check whether string has ASCII control characters.
1274 *
1275 * @ingroup Strings
1276 *
1277 * @param str String to check.
1278 *
1279 * @return Whether the string has ASCII control characters.
1280 *
1281 * @remark The strings are treated as zero-terminated strings.
1282 */
1283bool str_has_cc(const char *str);
1284
1285/**
1286 * Replaces all characters below 32 with whitespace.
1287 *
1288 * @ingroup Strings
1289 *
1290 * @param str String to sanitize.
1291 *
1292 * @remark The strings are treated as zero-terminated strings.
1293 */
1294void str_sanitize_cc(char *str);
1295
1296/**
1297 * Replaces all characters below 32 with whitespace with
1298 * exception to \t, \n and \r.
1299 *
1300 * @ingroup Strings
1301 *
1302 * @param str String to sanitize.
1303 *
1304 * @remark The strings are treated as zero-terminated strings.
1305 */
1306void str_sanitize(char *str);
1307
1308/**
1309 * Replaces all invalid filename characters with whitespace.
1310 *
1311 * @param str String to sanitize.
1312 *
1313 * @remark The strings are treated as zero-terminated strings.
1314 */
1315void str_sanitize_filename(char *str);
1316
1317/**
1318 * Removes leading and trailing spaces and limits the use of multiple spaces.
1319 *
1320 * @ingroup Strings
1321 *
1322 * @param str String to clean up
1323 *
1324 * @remark The strings are treated as zero-terminated strings.
1325 */
1326void str_clean_whitespaces(char *str);
1327
1328/**
1329 * Skips leading non-whitespace characters.
1330 *
1331 * @ingroup Strings
1332 *
1333 * @param str Pointer to the string.
1334 *
1335 * @return Pointer to the first whitespace character found
1336 * within the string.
1337 *
1338 * @remark The strings are treated as zero-terminated strings.
1339 * @remark Whitespace is defined according to str_isspace.
1340 */
1341char *str_skip_to_whitespace(char *str);
1342
1343/**
1344 * @ingroup Strings
1345 * @see str_skip_to_whitespace
1346 */
1347const char *str_skip_to_whitespace_const(const char *str);
1348
1349/**
1350 * Skips leading whitespace characters.
1351 *
1352 * @ingroup Strings
1353 *
1354 * @param str Pointer to the string.
1355 *
1356 * Pointer to the first non-whitespace character found
1357 * within the string.
1358 *
1359 * @remark The strings are treated as zero-terminated strings.
1360 * @remark Whitespace is defined according to str_isspace.
1361 */
1362char *str_skip_whitespaces(char *str);
1363
1364/**
1365 * @ingroup Strings
1366 * @see str_skip_whitespaces
1367 */
1368const char *str_skip_whitespaces_const(const char *str);
1369
1370/**
1371 * Compares to strings case insensitively.
1372 *
1373 * @ingroup Strings
1374 *
1375 * @param a String to compare.
1376 * @param b String to compare.
1377 *
1378 * @return `< 0` - String a is less than string b
1379 * @return `0` - String a is equal to string b
1380 * @return `> 0` - String a is greater than string b
1381 *
1382 * @remark Only guaranteed to work with a-z/A-Z.
1383 * @remark The strings are treated as zero-terminated strings.
1384 */
1385int str_comp_nocase(const char *a, const char *b);
1386
1387/**
1388 * Compares up to num characters of two strings case insensitively.
1389 *
1390 * @ingroup Strings
1391 *
1392 * @param a String to compare.
1393 * @param b String to compare.
1394 * @param num Maximum characters to compare
1395 *
1396 * @return `< 0` - String a is less than string b
1397 * @return `0` - String a is equal to string b
1398 * @return `> 0` - String a is greater than string b
1399 *
1400 * @remark Only guaranteed to work with a-z/A-Z.
1401 * (use str_utf8_comp_nocase_num for unicode support)
1402 * @remark The strings are treated as zero-terminated strings.
1403 */
1404int str_comp_nocase_num(const char *a, const char *b, int num);
1405
1406/**
1407 * Compares two strings case sensitive.
1408 *
1409 * @ingroup Strings
1410 *
1411 * @param a String to compare.
1412 * @param b String to compare.
1413 *
1414 * @return `< 0` - String a is less than string b
1415 * @return `0` - String a is equal to string b
1416 * @return `> 0` - String a is greater than string b
1417 *
1418 * @remark The strings are treated as zero-terminated strings.
1419 */
1420int str_comp(const char *a, const char *b);
1421
1422/**
1423 * Compares up to num characters of two strings case sensitive.
1424 *
1425 * @ingroup Strings
1426 *
1427 * @param a String to compare.
1428 * @param b String to compare.
1429 * @param num Maximum characters to compare
1430 *
1431 * @return `< 0` - String a is less than string b
1432 * @return `0` - String a is equal to string b
1433 * @return `> 0` - String a is greater than string b
1434 *
1435 * @remark The strings are treated as zero-terminated strings.
1436 */
1437int str_comp_num(const char *a, const char *b, int num);
1438
1439/**
1440 * Compares two strings case insensitive, digit chars will be compared as numbers.
1441 *
1442 * @ingroup Strings
1443 *
1444 * @param a String to compare.
1445 * @param b String to compare.
1446 *
1447 * @return `< 0` - String a is less than string b
1448 * @return `0` - String a is equal to string b
1449 * @return `> 0` - String a is greater than string b
1450 *
1451 * @remark The strings are treated as zero-terminated strings.
1452 */
1453int str_comp_filenames(const char *a, const char *b);
1454
1455/*
1456 Function: str_startswith_nocase
1457 Checks case insensitive whether the string begins with a certain prefix.
1458
1459 Parameter:
1460 str - String to check.
1461 prefix - Prefix to look for.
1462
1463 Returns:
1464 A pointer to the string str after the string prefix, or 0 if
1465 the string prefix isn't a prefix of the string str.
1466
1467 Remarks:
1468 - The strings are treated as zero-terminated strings.
1469*/
1470const char *str_startswith_nocase(const char *str, const char *prefix);
1471
1472/**
1473 * Checks case sensitive whether the string begins with a certain prefix.
1474 *
1475 * @ingroup Strings
1476 *
1477 * @param str String to check.
1478 * @param prefix Prefix to look for.
1479 *
1480 * @return A pointer to the string str after the string prefix, or 0 if
1481 * the string prefix isn't a prefix of the string str.
1482 *
1483 * @remark The strings are treated as zero-terminated strings.
1484 */
1485const char *str_startswith(const char *str, const char *prefix);
1486
1487/*
1488 Function: str_endswith_nocase
1489 Checks case insensitive whether the string ends with a certain suffix.
1490
1491 Parameter:
1492 str - String to check.
1493 suffix - Suffix to look for.
1494
1495 Returns:
1496 A pointer to the beginning of the suffix in the string str, or
1497 0 if the string suffix isn't a suffix of the string str.
1498
1499 Remarks:
1500 - The strings are treated as zero-terminated strings.
1501*/
1502const char *str_endswith_nocase(const char *str, const char *suffix);
1503
1504/*
1505 Function: str_endswith
1506 Checks case sensitive whether the string ends with a certain suffix.
1507
1508 Parameter:
1509 str - String to check.
1510 suffix - Suffix to look for.
1511
1512 Returns:
1513 A pointer to the beginning of the suffix in the string str, or
1514 0 if the string suffix isn't a suffix of the string str.
1515
1516 Remarks:
1517 - The strings are treated as zero-terminated strings.
1518*/
1519const char *str_endswith(const char *str, const char *suffix);
1520
1521/**
1522 * Computes the edit distance between two strings.
1523 *
1524 * @param a First string for the edit distance.
1525 * @param b Second string for the edit distance.
1526 *
1527 * @return The edit distance between the both strings.
1528 *
1529 * @remark The strings are treated as zero-terminated strings.
1530 */
1531int str_utf8_dist(const char *a, const char *b);
1532
1533/**
1534 * Computes the edit distance between two strings, allows buffers
1535 * to be passed in.
1536 *
1537 * @ingroup Strings
1538 *
1539 * @param a - First string for the edit distance.
1540 * @param b - Second string for the edit distance.
1541 * @param buf - Buffer for the function.
1542 * @param buf_len Length of the buffer, must be at least as long as
1543 * twice the length of both strings combined plus two.
1544 *
1545 * @return The edit distance between the both strings.
1546 *
1547 * @remark The strings are treated as zero-terminated strings.
1548 */
1549int str_utf8_dist_buffer(const char *a, const char *b, int *buf, int buf_len);
1550
1551/*
1552 Function: str_utf32_dist_buffer
1553 Computes the edit distance between two strings, allows buffers
1554 to be passed in.
1555
1556 Parameters:
1557 a - First string for the edit distance.
1558 a_len - Length of the first string.
1559 b - Second string for the edit distance.
1560 b_len - Length of the second string.
1561 buf - Buffer for the function.
1562 buf_len - Length of the buffer, must be at least as long as
1563 the length of both strings combined plus two.
1564
1565 Returns:
1566 The edit distance between the both strings.
1567
1568 Remarks:
1569 - The strings are treated as zero-terminated strings.
1570*/
1571int str_utf32_dist_buffer(const int *a, int a_len, const int *b, int b_len, int *buf, int buf_len);
1572
1573/*
1574 Function: str_find_nocase
1575 Finds a string inside another string case insensitively.
1576
1577 Parameters:
1578 haystack - String to search in
1579 needle - String to search for
1580
1581 Returns:
1582 A pointer into haystack where the needle was found.
1583 Returns NULL if needle could not be found.
1584
1585 Remarks:
1586 - Only guaranteed to work with a-z/A-Z.
1587 (use str_utf8_find_nocase for unicode support)
1588 - The strings are treated as zero-terminated strings.
1589*/
1590const char *str_find_nocase(const char *haystack, const char *needle);
1591
1592/*
1593 Function: str_find
1594 Finds a string inside another string case sensitive.
1595
1596 Parameters:
1597 haystack - String to search in
1598 needle - String to search for
1599
1600 Returns:
1601 A pointer into haystack where the needle was found.
1602 Returns NULL if needle could not be found.
1603
1604 Remarks:
1605 - The strings are treated as zero-terminated strings.
1606*/
1607const char *str_find(const char *haystack, const char *needle);
1608
1609/**
1610 * Finds the last occurrence of a character
1611 *
1612 * @ingroup Strings
1613 *
1614 * @param haystack String to search in
1615 * @param needle Character to search for
1616
1617 * @return A pointer into haystack where the needle was found.
1618 * Returns NULL if needle could not be found.
1619 *
1620 * @remark The strings are treated as zero-terminated strings.
1621 * @remark The zero-terminator character can also be found with this function.
1622 */
1623const char *str_rchr(const char *haystack, char needle);
1624
1625/**
1626 * Counts the number of occurrences of a character in a string.
1627 *
1628 * @ingroup Strings
1629 *
1630 * @param haystack String to count in
1631 * @param needle Character to count
1632
1633 * @return The number of characters in the haystack string matching
1634 * the needle character.
1635 *
1636 * @remark The strings are treated as zero-terminated strings.
1637 * @remark The number of zero-terminator characters cannot be counted.
1638 */
1639int str_countchr(const char *haystack, char needle);
1640
1641/**
1642 * Takes a datablock and generates a hex string of it, with spaces between bytes.
1643 *
1644 * @param dst Buffer to fill with hex data.
1645 * @param dst_size Size of the buffer (at least 3 * data_size + 1 to contain all data).
1646 * @param data Data to turn into hex.
1647 * @param data_size Size of the data.
1648 *
1649 * @remark The destination buffer will be zero-terminated.
1650 */
1651void str_hex(char *dst, int dst_size, const void *data, int data_size);
1652
1653/**
1654 * Takes a datablock and generates a hex string of it, in the C style array format,
1655 * i.e. with bytes formatted in 0x00-0xFF notation and commas with spaces between the bytes.
1656 * The output can be split over multiple lines by specifying the maximum number of bytes
1657 * that should be printed per line.
1658 *
1659 * @param dst Buffer to fill with hex data.
1660 * @param dst_size Size of the buffer (at least 6 * data_size + 1 to contain all data).
1661 * @param data Data to turn into hex.
1662 * @param data_size Size of the data.
1663 * @param bytes_per_line After this many printed bytes a newline will be printed.
1664 *
1665 * @remark The destination buffer will be zero-terminated.
1666 */
1667void str_hex_cstyle(char *dst, int dst_size, const void *data, int data_size, int bytes_per_line = 12);
1668
1669/*
1670 Function: str_hex_decode
1671 Takes a hex string *without spaces between bytes* and returns a
1672 byte array.
1673
1674 Parameters:
1675 dst - Buffer for the byte array
1676 dst_size - size of the buffer
1677 data - String to decode
1678
1679 Returns:
1680 2 - String doesn't exactly fit the buffer
1681 1 - Invalid character in string
1682 0 - Success
1683
1684 Remarks:
1685 - The contents of the buffer is only valid on success
1686*/
1687int str_hex_decode(void *dst, int dst_size, const char *src);
1688
1689/*
1690 Function: str_base64
1691 Takes a datablock and generates the base64 encoding of it.
1692
1693 Parameters:
1694 dst - Buffer to fill with base64 data
1695 dst_size - Size of the buffer
1696 data - Data to turn into base64
1697 data - Size of the data
1698
1699 Remarks:
1700 - The destination buffer will be zero-terminated
1701*/
1702void str_base64(char *dst, int dst_size, const void *data, int data_size);
1703
1704/*
1705 Function: str_base64_decode
1706 Takes a base64 string without any whitespace and correct
1707 padding and returns a byte array.
1708
1709 Parameters:
1710 dst - Buffer for the byte array
1711 dst_size - Size of the buffer
1712 data - String to decode
1713
1714 Returns:
1715 <0 - Error
1716 >= 0 - Success, length of the resulting byte buffer
1717
1718 Remarks:
1719 - The contents of the buffer is only valid on success
1720*/
1721int str_base64_decode(void *dst, int dst_size, const char *data);
1722
1723/*
1724 Function: str_timestamp
1725 Copies a time stamp in the format year-month-day_hour-minute-second to the string.
1726
1727 Parameters:
1728 buffer - Pointer to a buffer that shall receive the time stamp string.
1729 buffer_size - Size of the buffer.
1730
1731 Remarks:
1732 - Guarantees that buffer string will contain zero-termination.
1733*/
1734void str_timestamp(char *buffer, int buffer_size);
1735void str_timestamp_format(char *buffer, int buffer_size, const char *format)
1736 GNUC_ATTRIBUTE((format(strftime, 3, 0)));
1737void str_timestamp_ex(time_t time, char *buffer, int buffer_size, const char *format)
1738 GNUC_ATTRIBUTE((format(strftime, 4, 0)));
1739
1740/**
1741 * Parses a string into a timestamp following a specified format.
1742 *
1743 * @ingroup Timestamp
1744 *
1745 * @param string Pointer to the string to parse
1746 * @param format The time format to use (for example FORMAT_NOSPACE below)
1747 * @param timestamp Pointer to the timestamp result
1748 *
1749 * @return true on success, false if the string could not be parsed with the specified format
1750 *
1751 */
1752bool timestamp_from_str(const char *string, const char *format, time_t *timestamp)
1753 GNUC_ATTRIBUTE((format(strftime, 2, 0)));
1754
1755#define FORMAT_TIME "%H:%M:%S"
1756#define FORMAT_SPACE "%Y-%m-%d %H:%M:%S"
1757#define FORMAT_NOSPACE "%Y-%m-%d_%H-%M-%S"
1758
1759enum
1760{
1761 TIME_DAYS,
1762 TIME_HOURS,
1763 TIME_MINS,
1764 TIME_HOURS_CENTISECS,
1765 TIME_MINS_CENTISECS,
1766 TIME_SECS_CENTISECS,
1767};
1768
1769/*
1770 Function: str_times
1771 Formats a time string.
1772
1773 Parameters:
1774 centisecs - Time in centiseconds, minimum value clamped to 0
1775 format - Format of the time string, see enum above, for example TIME_DAYS
1776 buffer - Pointer to a buffer that shall receive the time stamp string.
1777 buffer_size - Size of the buffer.
1778
1779 Returns:
1780 Number of bytes written, -1 on invalid format or buffer_size <= 0
1781
1782 Remarks:
1783 - Guarantees that buffer string will contain zero-termination, assuming
1784 buffer_size > 0.
1785*/
1786int str_time(int64_t centisecs, int format, char *buffer, int buffer_size);
1787int str_time_float(float secs, int format, char *buffer, int buffer_size);
1788
1789/*
1790 Function: str_escape
1791 Escapes \ and " characters in a string.
1792
1793 Parameters:
1794 dst - Destination array pointer, gets increased, will point to
1795 the terminating null.
1796 src - Source array
1797 end - End of destination array
1798*/
1799void str_escape(char **dst, const char *src, const char *end);
1800
1801/**
1802 * @defgroup Filesystem
1803 *
1804 * Utilities for accessing the file system.
1805 */
1806
1807/**
1808 * Lists the files and folders in a directory.
1809 *
1810 * @ingroup Filesystem
1811 *
1812 * @param dir Directory to list.
1813 * @param cb Callback function to call for each entry.
1814 * @param type Type of the directory.
1815 * @param user Pointer to give to the callback.
1816 *
1817 * @remark The strings are treated as zero-terminated strings.
1818 */
1819void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user);
1820
1821/**
1822 * Lists the files and folders in a directory and gets additional file information.
1823 *
1824 * @ingroup Filesystem
1825 *
1826 * @param dir Directory to list.
1827 * @param cb Callback function to call for each entry.
1828 * @param type Type of the directory.
1829 * @param user Pointer to give to the callback.
1830 *
1831 * @remark The strings are treated as zero-terminated strings.
1832 */
1833void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user);
1834
1835/**
1836 * Creates a directory.
1837 *
1838 * @ingroup Filesystem
1839 *
1840 * @param path Directory to create.
1841 *
1842 * @return 0 on success. Negative value on failure.
1843 *
1844 * @remark Does not create several directories if needed. "a/b/c" will
1845 * result in a failure if b or a does not exist.
1846 *
1847 * @remark The strings are treated as zero-terminated strings.
1848 */
1849int fs_makedir(const char *path);
1850
1851/**
1852 * Removes a directory.
1853 *
1854 * @ingroup Filesystem
1855 *
1856 * @param path Directory to remove.
1857 *
1858 * @return 0 on success. Negative value on failure.
1859 *
1860 * @remark Cannot remove a non-empty directory.
1861 *
1862 * @remark The strings are treated as zero-terminated strings.
1863 */
1864int fs_removedir(const char *path);
1865
1866/**
1867 * Recursively creates parent directories for a file or directory.
1868 *
1869 * @ingroup Filesystem
1870 *
1871 * @param path File or directory for which to create parent directories.
1872 *
1873 * @return 0 on success. Negative value on failure.
1874 *
1875 * @remark The strings are treated as zero-terminated strings.
1876 */
1877int fs_makedir_rec_for(const char *path);
1878
1879/**
1880 * Fetches per user configuration directory.
1881 *
1882 * @ingroup Filesystem
1883 *
1884 * @param appname Name of the application.
1885 * @param path Buffer that will receive the storage path.
1886 * @param max Size of the buffer.
1887 *
1888 * @return 0 on success. Negative value on failure.
1889 *
1890 * @remark Returns ~/.appname on UNIX based systems.
1891 * @remark Returns ~/Library/Applications Support/appname on macOS.
1892 * @remark Returns %APPDATA%/Appname on Windows based systems.
1893 *
1894 * @remark The strings are treated as zero-terminated strings.
1895 */
1896int fs_storage_path(const char *appname, char *path, int max);
1897
1898/**
1899 * Checks if a file exists.
1900 *
1901 * @ingroup Filesystem
1902 *
1903 * @param path the path to check.
1904 *
1905 * @return 1 if a file with the given path exists,
1906 * 0 on failure or if the file does not exist.
1907 *
1908 * @remark The strings are treated as zero-terminated strings.
1909 */
1910int fs_is_file(const char *path);
1911
1912/**
1913 * Checks if a folder exists.
1914 *
1915 * @ingroup Filesystem
1916 *
1917 * @param path the path to check.
1918 *
1919 * @return 1 if a folder with the given path exists,
1920 * 0 on failure or if the folder does not exist.
1921 *
1922 * @remark The strings are treated as zero-terminated strings.
1923 */
1924int fs_is_dir(const char *path);
1925
1926/**
1927 * Checks whether a given path is relative or absolute.
1928 *
1929 * @ingroup Filesystem
1930 *
1931 * @param path Path to check.
1932 *
1933 * @return 1 if relative, 0 if absolute.
1934 *
1935 * @remark The strings are treated as zero-terminated strings.
1936 */
1937int fs_is_relative_path(const char *path);
1938
1939/**
1940 * Changes the current working directory.
1941 *
1942 * @ingroup Filesystem
1943 *
1944 * @param path New working directory path.
1945 *
1946 * @return 0 on success, 1 on failure.
1947 *
1948 * @remark The strings are treated as zero-terminated strings.
1949 */
1950int fs_chdir(const char *path);
1951
1952/**
1953 * Gets the current working directory.
1954 *
1955 * @ingroup Filesystem
1956 *
1957 * @param buffer Buffer that will receive the current working directory.
1958 * @param buffer_size Size of the buffer.
1959 *
1960 * @return Pointer to the buffer on success, nullptr on failure.
1961 *
1962 * @remark The strings are treated as zero-terminated strings.
1963 */
1964char *fs_getcwd(char *buffer, int buffer_size);
1965
1966/**
1967 * Gets the name of a file or folder specified by a path,
1968 * i.e. the last segment of the path.
1969 *
1970 * @ingroup Filesystem
1971 *
1972 * @param path Path from which to retrieve the filename.
1973 *
1974 * @return Filename of the path.
1975 *
1976 * @remark Supports forward and backward slashes as path segment separator.
1977 * @remark No distinction between files and folders is being made.
1978 * @remark The strings are treated as zero-terminated strings.
1979 */
1980const char *fs_filename(const char *path);
1981
1982/**
1983 * Splits a filename into name (without extension) and file extension.
1984 *
1985 * @ingroup Filesystem
1986 *
1987 * @param filename The filename to split.
1988 * @param name Buffer that will receive the name without extension, may be nullptr.
1989 * @param name_size Size of the name buffer (ignored if name is nullptr).
1990 * @param extension Buffer that will receive the extension, may be nullptr.
1991 * @param extension_size Size of the extension buffer (ignored if extension is nullptr).
1992 *
1993 * @remark Does NOT handle forward and backward slashes.
1994 * @remark No distinction between files and folders is being made.
1995 * @remark The strings are treated as zero-terminated strings.
1996 */
1997void fs_split_file_extension(const char *filename, char *name, size_t name_size, char *extension = nullptr, size_t extension_size = 0);
1998
1999/**
2000 * Get the parent directory of a directory.
2001 *
2002 * @ingroup Filesystem
2003 *
2004 * @param path Path of the directory. The parent will be store in this buffer as well.
2005 *
2006 * @return 0 on success, 1 on failure.
2007 *
2008 * @remark The strings are treated as zero-terminated strings.
2009 */
2010int fs_parent_dir(char *path);
2011
2012/**
2013 * Deletes a file.
2014 *
2015 * @ingroup Filesystem
2016 *
2017 * @param filename Path of the file to delete.
2018 *
2019 * @return 0 on success, 1 on failure.
2020 *
2021 * @remark The strings are treated as zero-terminated strings.
2022 * @remark Returns an error if the path specifies a directory name.
2023 */
2024int fs_remove(const char *filename);
2025
2026/**
2027 * Renames the file or directory. If the paths differ the file will be moved.
2028 *
2029 * @ingroup Filesystem
2030 *
2031 * @param oldname The current path of a file or directory.
2032 * @param newname The new path for the file or directory.
2033 *
2034 * @return 0 on success, 1 on failure.
2035 *
2036 * @remark The strings are treated as zero-terminated strings.
2037 */
2038int fs_rename(const char *oldname, const char *newname);
2039
2040/**
2041 * Gets the creation and the last modification date of a file or directory.
2042 *
2043 * @ingroup Filesystem
2044 *
2045 * @param name Path of a file or directory.
2046 * @param created Pointer where the creation time will be stored.
2047 * @param modified Pointer where the modification time will be stored.
2048 *
2049 * @return 0 on success, non-zero on failure.
2050 *
2051 * @remark The strings are treated as zero-terminated strings.
2052 * @remark Returned time is in seconds since UNIX Epoch.
2053 */
2054int fs_file_time(const char *name, time_t *created, time_t *modified);
2055
2056/*
2057 Group: Undocumented
2058*/
2059
2060/*
2061 Function: net_tcp_connect_non_blocking
2062
2063 DOCTODO: serp
2064*/
2065int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr);
2066
2067/*
2068 Function: net_set_non_blocking
2069
2070 DOCTODO: serp
2071*/
2072int net_set_non_blocking(NETSOCKET sock);
2073
2074/*
2075 Function: net_set_non_blocking
2076
2077 DOCTODO: serp
2078*/
2079int net_set_blocking(NETSOCKET sock);
2080
2081/*
2082 Function: net_errno
2083
2084 DOCTODO: serp
2085*/
2086int net_errno();
2087
2088/*
2089 Function: net_would_block
2090
2091 DOCTODO: serp
2092*/
2093int net_would_block();
2094
2095int net_socket_read_wait(NETSOCKET sock, int time);
2096
2097/**
2098 * Swaps the endianness of data. Each element is swapped individually by reversing its bytes.
2099 *
2100 * @param data Pointer to data to be swapped.
2101 * @param elem_size Size in bytes of each element.
2102 * @param num Number of elements.
2103 *
2104 * @remark The caller must ensure that the data is at least `elem_size * num` bytes in size.
2105 */
2106void swap_endian(void *data, unsigned elem_size, unsigned num);
2107
2108typedef struct
2109{
2110 uint64_t sent_packets;
2111 uint64_t sent_bytes;
2112 uint64_t recv_packets;
2113 uint64_t recv_bytes;
2114} NETSTATS;
2115
2116void net_stats(NETSTATS *stats);
2117
2118int str_toint(const char *str);
2119bool str_toint(const char *str, int *out);
2120int str_toint_base(const char *str, int base);
2121unsigned long str_toulong_base(const char *str, int base);
2122int64_t str_toint64_base(const char *str, int base = 10);
2123float str_tofloat(const char *str);
2124bool str_tofloat(const char *str, float *out);
2125
2126/**
2127 * Determines whether a character is whitespace.
2128 *
2129 * @ingroup Strings
2130 *
2131 * @param c the character to check
2132 *
2133 * @return 1 if the character is whitespace, 0 otherwise.
2134 *
2135 * @remark The following characters are considered whitespace: ' ', '\n', '\r', '\t'
2136 */
2137int str_isspace(char c);
2138
2139char str_uppercase(char c);
2140
2141bool str_isnum(char c);
2142
2143int str_isallnum(const char *str);
2144
2145int str_isallnum_hex(const char *str);
2146
2147unsigned str_quickhash(const char *str);
2148
2149int str_utf8_to_skeleton(const char *str, int *buf, int buf_len);
2150
2151/*
2152 Function: str_utf8_comp_confusable
2153 Compares two strings for visual appearance.
2154
2155 Parameters:
2156 str1 - String to compare.
2157 str2 - String to compare.
2158
2159 Returns:
2160 0 if the strings are confusable.
2161 !=0 otherwise.
2162*/
2163int str_utf8_comp_confusable(const char *str1, const char *str2);
2164
2165/*
2166 Function: str_utf8_tolower
2167 Converts the given Unicode codepoint to lowercase (locale insensitive).
2168
2169 Parameters:
2170 code - Unicode codepoint to convert.
2171
2172 Returns:
2173 Lowercase codepoint
2174*/
2175int str_utf8_tolower(int code);
2176
2177/*
2178 Function: str_utf8_comp_nocase
2179 Compares two utf8 strings case insensitively.
2180
2181 Parameters:
2182 a - String to compare.
2183 b - String to compare.
2184
2185 Returns:
2186 <0 - String a is less than string b
2187 0 - String a is equal to string b
2188 >0 - String a is greater than string b
2189*/
2190int str_utf8_comp_nocase(const char *a, const char *b);
2191
2192/*
2193 Function: str_utf8_comp_nocase_num
2194 Compares up to num bytes of two utf8 strings case insensitively.
2195
2196 Parameters:
2197 a - String to compare.
2198 b - String to compare.
2199 num - Maximum bytes to compare
2200
2201 Returns:
2202 <0 - String a is less than string b
2203 0 - String a is equal to string b
2204 >0 - String a is greater than string b
2205*/
2206int str_utf8_comp_nocase_num(const char *a, const char *b, int num);
2207
2208/*
2209 Function: str_utf8_find_nocase
2210 Finds a utf8 string inside another utf8 string case insensitively.
2211
2212 Parameters:
2213 haystack - String to search in
2214 needle - String to search for
2215 end - A pointer that will be set to a pointer into haystack directly behind the
2216 last character where the needle was found. Will be set to nullptr if needle
2217 could not be found. Optional parameter.
2218
2219 Returns:
2220 A pointer into haystack where the needle was found.
2221 Returns NULL if needle could not be found.
2222
2223 Remarks:
2224 - The strings are treated as zero-terminated strings.
2225*/
2226const char *str_utf8_find_nocase(const char *haystack, const char *needle, const char **end = nullptr);
2227
2228/*
2229 Function: str_utf8_isspace
2230 Checks whether the given Unicode codepoint renders as space.
2231
2232 Parameters:
2233 code - Unicode codepoint to check.
2234
2235 Returns:
2236 0 if the codepoint does not render as space, != 0 if it does.
2237*/
2238int str_utf8_isspace(int code);
2239
2240int str_utf8_isstart(char c);
2241
2242/*
2243 Function: str_utf8_skip_whitespaces
2244 Skips leading characters that render as spaces.
2245
2246 Parameters:
2247 str - Pointer to the string.
2248
2249 Returns:
2250 Pointer to the first non-whitespace character found
2251 within the string.
2252
2253 Remarks:
2254 - The strings are treated as zero-terminated strings.
2255*/
2256const char *str_utf8_skip_whitespaces(const char *str);
2257
2258/*
2259 Function: str_utf8_trim_right
2260 Removes trailing characters that render as spaces by modifying
2261 the string in-place.
2262
2263 Parameters:
2264 param - Pointer to the string.
2265
2266 Remarks:
2267 - The strings are treated as zero-terminated strings.
2268 - The string is modified in-place.
2269*/
2270void str_utf8_trim_right(char *param);
2271
2272/*
2273 Function: str_utf8_rewind
2274 Moves a cursor backwards in an utf8 string
2275
2276 Parameters:
2277 str - utf8 string
2278 cursor - position in the string
2279
2280 Returns:
2281 New cursor position.
2282
2283 Remarks:
2284 - Won't move the cursor less then 0
2285*/
2286int str_utf8_rewind(const char *str, int cursor);
2287
2288/*
2289 Function: str_utf8_fix_truncation
2290 Fixes truncation of a Unicode character at the end of a UTF-8
2291 string.
2292
2293 Returns:
2294 The new string length.
2295
2296 Parameters:
2297 str - utf8 string
2298*/
2299int str_utf8_fix_truncation(char *str);
2300
2301/*
2302 Function: str_utf8_forward
2303 Moves a cursor forwards in an utf8 string
2304
2305 Parameters:
2306 str - utf8 string
2307 cursor - position in the string
2308
2309 Returns:
2310 New cursor position.
2311
2312 Remarks:
2313 - Won't move the cursor beyond the zero termination marker
2314*/
2315int str_utf8_forward(const char *str, int cursor);
2316
2317/*
2318 Function: str_utf8_decode
2319 Decodes a utf8 codepoint
2320
2321 Parameters:
2322 ptr - Pointer to a utf8 string. This pointer will be moved forward.
2323
2324 Returns:
2325 The Unicode codepoint. -1 for invalid input and 0 for end of string.
2326
2327 Remarks:
2328 - This function will also move the pointer forward.
2329 - You may call this function again after an error occurred.
2330*/
2331int str_utf8_decode(const char **ptr);
2332
2333/*
2334 Function: str_utf8_encode
2335 Encode an utf8 character
2336
2337 Parameters:
2338 ptr - Pointer to a buffer that should receive the data. Should be able to hold at least 4 bytes.
2339
2340 Returns:
2341 Number of bytes put into the buffer.
2342
2343 Remarks:
2344 - Does not do zero termination of the string.
2345*/
2346int str_utf8_encode(char *ptr, int chr);
2347
2348/*
2349 Function: str_utf8_check
2350 Checks if a strings contains just valid utf8 characters.
2351
2352 Parameters:
2353 str - Pointer to a possible utf8 string.
2354
2355 Returns:
2356 0 - invalid characters found.
2357 1 - only valid characters found.
2358
2359 Remarks:
2360 - The string is treated as zero-terminated utf8 string.
2361*/
2362int str_utf8_check(const char *str);
2363
2364/*
2365 Function: str_utf8_stats
2366 Determines the byte size and utf8 character count of a utf8 string.
2367
2368 Parameters:
2369 str - Pointer to the string.
2370 max_size - Maximum number of bytes to count.
2371 max_count - Maximum number of utf8 characters to count.
2372 size - Pointer to store size (number of non-zero bytes) of the string.
2373 count - Pointer to store count of utf8 characters of the string.
2374
2375 Remarks:
2376 - The string is treated as zero-terminated utf8 string.
2377 - It's the user's responsibility to make sure the bounds are aligned.
2378*/
2379void str_utf8_stats(const char *str, size_t max_size, size_t max_count, size_t *size, size_t *count);
2380
2381/**
2382 * Converts a byte offset of a utf8 string to the utf8 character offset.
2383 *
2384 * @param text Pointer to the string.
2385 * @param byte_offset Offset in bytes.
2386 *
2387 * @return Offset in utf8 characters. Clamped to the maximum length of the string in utf8 characters.
2388 *
2389 * @remark The string is treated as a zero-terminated utf8 string.
2390 * @remark It's the user's responsibility to make sure the bounds are aligned.
2391 */
2392size_t str_utf8_offset_bytes_to_chars(const char *str, size_t byte_offset);
2393
2394/**
2395 * Converts a utf8 character offset of a utf8 string to the byte offset.
2396 *
2397 * @param text Pointer to the string.
2398 * @param char_offset Offset in utf8 characters.
2399 *
2400 * @return Offset in bytes. Clamped to the maximum length of the string in bytes.
2401 *
2402 * @remark The string is treated as a zero-terminated utf8 string.
2403 * @remark It's the user's responsibility to make sure the bounds are aligned.
2404 */
2405size_t str_utf8_offset_chars_to_bytes(const char *str, size_t char_offset);
2406
2407/*
2408 Function: str_next_token
2409 Writes the next token after str into buf, returns the rest of the string.
2410
2411 Parameters:
2412 str - Pointer to string.
2413 delim - Delimiter for tokenization.
2414 buffer - Buffer to store token in.
2415 buffer_size - Size of the buffer.
2416
2417 Returns:
2418 Pointer to rest of the string.
2419
2420 Remarks:
2421 - The token is always null-terminated.
2422*/
2423const char *str_next_token(const char *str, const char *delim, char *buffer, int buffer_size);
2424
2425/*
2426 Function: str_in_list
2427 Checks if needle is in list delimited by delim
2428
2429 Parameters:
2430 list - List
2431 delim - List delimiter.
2432 needle - Item that is being looked for.
2433
2434 Returns:
2435 1 - Item is in list.
2436 0 - Item isn't in list.
2437*/
2438int str_in_list(const char *list, const char *delim, const char *needle);
2439
2440/**
2441 * Packs 4 big endian bytes into an unsigned.
2442 *
2443 * @param bytes Pointer to an array of bytes that will be packed.
2444 *
2445 * @return The packed unsigned.
2446 *
2447 * @remark Assumes the passed array is least 4 bytes in size.
2448 * @remark Assumes unsigned is 4 bytes in size.
2449 *
2450 * @see uint_to_bytes_be
2451 */
2452unsigned bytes_be_to_uint(const unsigned char *bytes);
2453
2454/**
2455 * Packs an unsigned into 4 big endian bytes.
2456 *
2457 * @param bytes Pointer to an array where the bytes will be stored.
2458 * @param value The values that will be packed into the array.
2459 *
2460 * @remark Assumes the passed array is least 4 bytes in size.
2461 * @remark Assumes unsigned is 4 bytes in size.
2462 *
2463 * @see bytes_be_to_uint
2464 */
2465void uint_to_bytes_be(unsigned char *bytes, unsigned value);
2466
2467/**
2468 * @defgroup Shell
2469 * Shell, process management, OS specific functionality.
2470 */
2471
2472/**
2473 * Returns the ID of the current process.
2474 *
2475 * @ingroup Shell
2476 *
2477 * @return PID of the current process.
2478 */
2479int pid();
2480
2481/**
2482 * Fixes the command line arguments to be encoded in UTF-8 on all systems.
2483 *
2484 * @ingroup Shell
2485 *
2486 * @param argc A pointer to the argc parameter that was passed to the main function.
2487 * @param argv A pointer to the argv parameter that was passed to the main function.
2488 *
2489 * @remark You need to call @link cmdline_free @endlink once you're no longer using the results.
2490 */
2491void cmdline_fix(int *argc, const char ***argv);
2492
2493/**
2494 * Frees memory that was allocated by @link cmdline_fix @endlink.
2495 *
2496 * @ingroup Shell
2497 *
2498 * @param argc The argc obtained from `cmdline_fix`.
2499 * @param argv The argv obtained from `cmdline_fix`.
2500 */
2501void cmdline_free(int argc, const char **argv);
2502
2503#if defined(CONF_FAMILY_WINDOWS)
2504/**
2505 * A handle for a process.
2506 *
2507 * @ingroup Shell
2508 */
2509typedef void *PROCESS;
2510/**
2511 * A handle that denotes an invalid process.
2512 *
2513 * @ingroup Shell
2514 */
2515constexpr PROCESS INVALID_PROCESS = nullptr;
2516#else
2517/**
2518 * A handle for a process.
2519 *
2520 * @ingroup Shell
2521 */
2522typedef pid_t PROCESS;
2523/**
2524 * A handle that denotes an invalid process.
2525 *
2526 * @ingroup Shell
2527 */
2528constexpr PROCESS INVALID_PROCESS = 0;
2529#endif
2530
2531/**
2532 * Determines the initial window state when using @link shell_execute @endlink
2533 * to execute a process.
2534 *
2535 * @ingroup Shell
2536 *
2537 * @remark Currently only supported on Windows.
2538 */
2539enum class EShellExecuteWindowState
2540{
2541 /**
2542 * The process window is opened in the foreground and activated.
2543 */
2544 FOREGROUND,
2545
2546 /**
2547 * The process window is opened in the background without focus.
2548 */
2549 BACKGROUND,
2550};
2551
2552/**
2553 * Executes a given file.
2554 *
2555 * @ingroup Shell
2556 *
2557 * @param file The file to execute.
2558 * @param window_state The window state how the process window should be shown.
2559 *
2560 * @return Handle of the new process, or @link INVALID_PROCESS @endlink on error.
2561 */
2562PROCESS shell_execute(const char *file, EShellExecuteWindowState window_state);
2563
2564/**
2565 * Sends kill signal to a process.
2566 *
2567 * @ingroup Shell
2568 *
2569 * @param process Handle of the process to kill.
2570 *
2571 * @return `1` on success, `0` on error.
2572 */
2573int kill_process(PROCESS process);
2574
2575/**
2576 * Checks if a process is alive.
2577 *
2578 * @ingroup Shell
2579 *
2580 * @param process Handle/PID of the process.
2581 *
2582 * @return `true` if the process is currently running,
2583 * `false` if the process is not running (dead).
2584 */
2585bool is_process_alive(PROCESS process);
2586
2587/**
2588 * Opens a link in the browser.
2589 *
2590 * @ingroup Shell
2591 *
2592 * @param link The link to open in a browser.
2593 *
2594 * @return `1` on success, `0` on failure.
2595 *
2596 * @remark The strings are treated as zero-terminated strings.
2597 * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
2598 */
2599int open_link(const char *link);
2600
2601/**
2602 * Opens a file or directory with default program.
2603 *
2604 * @ingroup Shell
2605 *
2606 * @param path The path to open.
2607 *
2608 * @return `1` on success, `0` on failure.
2609 *
2610 * @remark The strings are treated as zero-terminated strings.
2611 * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
2612 */
2613int open_file(const char *path);
2614
2615/**
2616 * @defgroup Secure-Random
2617 * Secure random number generation.
2618 */
2619
2620/**
2621 * Generates a null-terminated password of length `2 * random_length`.
2622 *
2623 * @ingroup Secure-Random
2624 *
2625 * @param buffer Pointer to the start of the output buffer.
2626 * @param length Length of the buffer.
2627 * @param random Pointer to a randomly-initialized array of shorts.
2628 * @param random_length Length of the short array.
2629 */
2630void generate_password(char *buffer, unsigned length, const unsigned short *random, unsigned random_length);
2631
2632/**
2633 * Initializes the secure random module.
2634 * You *MUST* check the return value of this function.
2635 *
2636 * @ingroup Secure-Random
2637 *
2638 * @return `0` on success.
2639 */
2640[[nodiscard]] int secure_random_init();
2641
2642/**
2643 * Uninitializes the secure random module.
2644 *
2645 * @ingroup Secure-Random
2646 *
2647 * @return `0` on success.
2648 */
2649int secure_random_uninit();
2650
2651/**
2652 * Fills the buffer with the specified amount of random password characters.
2653 *
2654 * @ingroup Secure-Random
2655 *
2656 * @param buffer Pointer to the start of the buffer.
2657 * @param length Length of the buffer.
2658 * @param pw_length Length of the desired password.
2659 *
2660 * @remark The desired password length must be greater or equal to 6,
2661 * even and smaller or equal to 128.
2662 */
2663void secure_random_password(char *buffer, unsigned length, unsigned pw_length);
2664
2665/**
2666 * Fills the buffer with the specified amount of random bytes.
2667 *
2668 * @ingroup Secure-Random
2669 *
2670 * @param buffer Pointer to the start of the buffer.
2671 * @param length Length of the buffer.
2672 */
2673void secure_random_fill(void *bytes, unsigned length);
2674
2675/**
2676 * Returns random `int`.
2677 *
2678 * @ingroup Secure-Random
2679 *
2680 * @return Random int.
2681 *
2682 * @remark Can be used as a replacement for the `rand` function.
2683 */
2684int secure_rand();
2685
2686/**
2687 * Returns a random nonnegative integer below the given number,
2688 * with a uniform distribution.
2689 *
2690 * @ingroup Secure-Random
2691 *
2692 * @param below Upper limit (exclusive) of integers to return.
2693 *
2694 * @return Random nonnegative below the given number.
2695 */
2696int secure_rand_below(int below);
2697
2698/**
2699 * Returns a human-readable version string of the operating system.
2700 *
2701 * @ingroup Shell
2702 *
2703 * @param version Buffer to use for the output.
2704 * @param length Length of the output buffer.
2705 *
2706 * @return `true` on success, `false` on failure.
2707 */
2708bool os_version_str(char *version, size_t length);
2709
2710/**
2711 * Returns a string of the preferred locale of the user / operating system.
2712 * The string conforms to [RFC 3066](https://www.ietf.org/rfc/rfc3066.txt)
2713 * and only contains the characters `a`-`z`, `A`-`Z`, `0`-`9` and `-`.
2714 * If the preferred locale could not be determined this function
2715 * falls back to the locale `"en-US"`.
2716 *
2717 * @ingroup Shell
2718 *
2719 * @param locale Buffer to use for the output.
2720 * @param length Length of the output buffer.
2721 *
2722 * @remark The destination buffer will be zero-terminated.
2723 */
2724void os_locale_str(char *locale, size_t length);
2725
2726#if defined(CONF_EXCEPTION_HANDLING)
2727/**
2728 * @defgroup Exception-Handling
2729 * Exception handling (crash logging).
2730 */
2731
2732/**
2733 * Initializes the exception handling module.
2734 *
2735 * @ingroup Exception-Handling
2736 */
2737void init_exception_handler();
2738
2739/**
2740 * Sets the filename for writing the crash log.
2741 *
2742 * @ingroup Exception-Handling
2743 *
2744 * @param log_file_path Absolute path to which crash log file should be written.
2745 */
2746void set_exception_handler_log_file(const char *log_file_path);
2747#endif
2748
2749/**
2750 * Fetches a sample from a high resolution timer and converts it in nanoseconds.
2751 *
2752 * @ingroup Time
2753 *
2754 * @return Current value of the timer in nanoseconds.
2755 */
2756std::chrono::nanoseconds time_get_nanoseconds();
2757
2758int net_socket_read_wait(NETSOCKET sock, std::chrono::nanoseconds nanoseconds);
2759
2760/**
2761 * Fixes the command line arguments to be encoded in UTF-8 on all systems.
2762 * This is a RAII wrapper for @link cmdline_fix @endlink and @link cmdline_free @endlink.
2763 *
2764 * @ingroup Shell
2765 */
2766class CCmdlineFix
2767{
2768 int m_Argc;
2769 const char **m_ppArgv;
2770
2771public:
2772 CCmdlineFix(int *pArgc, const char ***pppArgv)
2773 {
2774 cmdline_fix(argc: pArgc, argv: pppArgv);
2775 m_Argc = *pArgc;
2776 m_ppArgv = *pppArgv;
2777 }
2778 ~CCmdlineFix()
2779 {
2780 cmdline_free(argc: m_Argc, argv: m_ppArgv);
2781 }
2782};
2783
2784#if defined(CONF_FAMILY_WINDOWS)
2785/**
2786 * Converts a UTF-8 encoded string to a wide character string
2787 * for use with the Windows API.
2788 *
2789 * @ingroup Shell
2790 *
2791 * @param str The UTF-8 encoded string to convert.
2792 *
2793 * @return The argument as a wide character string.
2794 *
2795 * @remark The argument string must be zero-terminated.
2796 * @remark Fails with assertion error if passed UTF-8 is invalid.
2797 */
2798std::wstring windows_utf8_to_wide(const char *str);
2799
2800/**
2801 * Converts a wide character string obtained from the Windows API
2802 * to a UTF-8 encoded string.
2803 *
2804 * @ingroup Shell
2805 *
2806 * @param wide_str The wide character string to convert.
2807 *
2808 * @return The argument as a UTF-8 encoded string, wrapped in an optional.
2809 * The optional is empty, if the wide string contains invalid codepoints.
2810 *
2811 * @remark The argument string must be zero-terminated.
2812 */
2813std::optional<std::string> windows_wide_to_utf8(const wchar_t *wide_str);
2814
2815/**
2816 * This is a RAII wrapper to initialize/uninitialize the Windows COM library,
2817 * which may be necessary for using the @link open_file @endlink and
2818 * @link open_link @endlink functions.
2819 * Must be used on every thread. It's automatically used on threads created
2820 * with @link thread_init @endlink. Pass `true` to the constructor on threads
2821 * that own a window (i.e. pump a message queue).
2822 *
2823 * @ingroup Shell
2824 */
2825class CWindowsComLifecycle
2826{
2827public:
2828 CWindowsComLifecycle(bool HasWindow);
2829 ~CWindowsComLifecycle();
2830};
2831
2832/**
2833 * Registers a protocol handler.
2834 *
2835 * @ingroup Shell
2836 *
2837 * @param protocol_name The name of the protocol.
2838 * @param executable The absolute path of the executable that will be associated with the protocol.
2839 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
2840 *
2841 * @return `true` on success, `false` on failure.
2842 *
2843 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
2844 */
2845bool shell_register_protocol(const char *protocol_name, const char *executable, bool *updated);
2846
2847/**
2848 * Registers a file extension.
2849 *
2850 * @ingroup Shell
2851 *
2852 * @param extension The file extension, including the leading dot.
2853 * @param description A readable description for the file extension.
2854 * @param executable_name A unique name that will used to describe the application.
2855 * @param executable The absolute path of the executable that will be associated with the file extension.
2856 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
2857 *
2858 * @return `true` on success, `false` on failure.
2859 *
2860 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
2861 */
2862bool shell_register_extension(const char *extension, const char *description, const char *executable_name, const char *executable, bool *updated);
2863
2864/**
2865 * Registers an application.
2866 *
2867 * @ingroup Shell
2868 *
2869 * @param name Readable name of the application.
2870 * @param executable The absolute path of the executable being registered.
2871 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
2872 *
2873 * @return `true` on success, `false` on failure.
2874 *
2875 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
2876 */
2877bool shell_register_application(const char *name, const char *executable, bool *updated);
2878
2879/**
2880 * Unregisters a protocol or file extension handler.
2881 *
2882 * @ingroup Shell
2883 *
2884 * @param shell_class The shell class to delete.
2885 * For protocols this is the name of the protocol.
2886 * For file extensions this is the program ID associated with the file extension.
2887 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
2888 *
2889 * @return `true` on success, `false` on failure.
2890 *
2891 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
2892 */
2893bool shell_unregister_class(const char *shell_class, bool *updated);
2894
2895/**
2896 * Unregisters an application.
2897 *
2898 * @ingroup Shell
2899 *
2900 * @param executable The absolute path of the executable being unregistered.
2901 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
2902 *
2903 * @return `true` on success, `false` on failure.
2904 *
2905 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
2906 */
2907bool shell_unregister_application(const char *executable, bool *updated);
2908
2909/**
2910 * Notifies the system that a protocol or file extension has been changed and the shell needs to be updated.
2911 *
2912 * @ingroup Shell
2913 *
2914 * @remark This is a potentially expensive operation, so it should only be called when necessary.
2915 */
2916void shell_update();
2917#endif
2918
2919template<>
2920struct std::hash<NETADDR>
2921{
2922 size_t operator()(const NETADDR &Addr) const noexcept;
2923};
2924
2925#endif
2926