serval-dna/os.h
Andrew Bettison bacba19dc1 Refactor manifest: specific setter functions
Replace generic rhizome_manifest_set() and rhizome_manifest_set_ll()
with per-field setter functions, eg, rhizome_manifest_set_filesize().
Struct rhizome_manifest elements for all known fields, to replace the
use of rhizome_manifest_get() and rhizome_manifest_get_ll() everywhere:
sender, recipient, service, name, date, bundle_key.

Add boolean validity flags for binary blob types, to avoid having to compare
with many bytes of all-zero to detect presence, eg, has_sender, has_recipient,
has_author, has_bundle_key.  These maintained by the setter functions.

Rename existing manifest struct elements to be the same as their field
names: fileLength -> filesize, journalTail -> tail.

More use of unsigned int, size_t and uint64_t for payload sizes, offsets, byte
counts, etc. especially in rhizome_store.c and meshms.c.  More uniform use of
size_t to dimension memory buffers.  Fix some printf(3) style format strings
for 64-bit correctness on 32-bit systems.  Use new constant RHIZOME_SIZE_UNSET
instead of -1 to indicate unknown dimension, and explicitly assert its absence
before comparisons and arithmetic, for safety.

Replace some 'int' loop variables with 'unsigned' where appropriate.

Fix bugs discovered in MeshMS bundle private/public key generation and
bundle secret key handling for export/extract commands.

Instrument the first MeshMS test case to aid debugging.

New debug config flag: debug.manifest logs all modifications to all manifest
fields by setter functions.

Rename debug config flag: debug.rhizome_bind -> debug.rhizome_sql_bind.
2013-11-04 19:17:49 +10:30

127 lines
4.3 KiB
C

/*
Serval DNA native Operating System interface
Copyright (C) 2012 Serval Project Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SERVALDNA_OS_H
#define __SERVALDNA_OS_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef __SERVALDNA_OS_INLINE
# if __GNUC__ && !__GNUC_STDC_INLINE__
# define __SERVALDNA_OS_INLINE extern inline
# else
# define __SERVALDNA_OS_INLINE inline
# endif
#endif
/* All wall clock times in the Serval daemon are represented in milliseconds
* since the Unix epoch. The gettime_ms() function uses gettimeofday(2) to
* return this value when called. The time_ms_t typedef should be used
* wherever this time value is handled or stored.
*
* This type could perfectly well be unsigned, but is defined as signed to
* avoid the need to cast or define a special signed timedelta_ms_t type at **
* (1):
*
* static time_ms_t then = 0;
* time_ms_t now = gettime_ms();
* time_ms_t ago = now - then; // ** (1)
* if (then && ago < 0) {
* ... time going backwards ...
* } else {
* ... time has advanced ...
* then = now;
* }
*/
typedef int64_t time_ms_t;
#define PRItime_ms_t PRId64
time_ms_t gettime_ms();
time_ms_t sleep_ms(time_ms_t milliseconds);
#ifndef HAVE_BZERO
__SERVALDNA_OS_INLINE void bzero(void *buf, size_t len) {
memset(buf, 0, len);
}
#endif
#ifndef HAVE_BCOPY
__SERVALDNA_OS_INLINE void bcopy(void *src, void *dst, size_t len) {
memcpy(dst, src, len);
}
#endif
#ifndef HAVE_BCMP
__SERVALDNA_OS_INLINE int bcmp(const void *s1, const void *s2, size_t n) {
// bcmp() is only an equality test, not an order test, so its return value
// is not specified as negative or positive, only non-zero. Hoewver
// memcmp() is an order test. We deliberately discard negative return
// values from memcmp(), to avoid misleading developers into assuming that
// bcmp() is an ordering operator and writing code that depends on that,
// which of course would fail on platforms with a native bcmp() function.
return memcmp(s1, s2, n) != 0;
}
#endif
/* The "e" variants log the error before returning -1.
*/
int mkdirs(const char *path, mode_t mode);
int emkdirs(const char *path, mode_t mode);
int mkdirsn(const char *path, size_t len, mode_t mode);
int emkdirsn(const char *path, size_t len, mode_t mode);
void srandomdev();
int urandombytes(unsigned char *buf, size_t len);
/* Read the symbolic link into the supplied buffer and add a terminating nul.
* Logs an ERROR and returns -1 if the buffer is too short to hold the link
* content and the terminating nul. If readlink(2) returns an error, then logs
* an ERROR and returns -1. Otherwise, returns the number of bytes read,
* including the terminating nul, ie, returns what readlink(2) returns plus
* one. If the 'len' argument is given as zero, then returns the number of
* bytes that would be read, by calling lstat(2) instead of readlink(2), plus
* one for the terminating nul. Beware of the following race condition: a
* symbolic link may be altered between calling the lstat(2) and readlink(2),
* so the following apparently overflow-proof code may still fail from a buffer
* overflow in the second call to read_symlink():
*
* char *readlink_malloc(const char *path) {
* ssize_t len = read_symlink(path, NULL, 0);
* if (len == -1)
* return NULL;
* char *buf = malloc(len);
* if (buf == NULL)
* return NULL;
* if (read_symlink(path, buf, len) == -1) {
* free(buf);
* return NULL;
* }
* return buf;
* }
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
ssize_t read_symlink(const char *path, char *buf, size_t len);
#endif //__SERVALDNA_OS_H