* ends with a slash. Otherwise, a pointer within \a name is returned. Caller
* must not free the result.
*/
-__must_check const char *para_basename(const char *name)
+__must_check char *para_basename(const char *name)
{
- const char *ret;
+ char *ret;
if (!name || !*name)
return NULL;
ret = strrchr(name, '/');
if (!ret)
- return name;
+ return (char *)name;
ret++;
return ret;
}
buf[n - 1] = '\0';
}
-/**
- * Get a random filename.
- *
- * This is by no means a secure way to create temporary files in a hostile
- * directory like \p /tmp. However, it is OK to use for temp files, fifos,
- * sockets that are created in ~/.paraslash. Result must be freed by the
- * caller.
- *
- * \return A pointer to a random filename.
- */
-__must_check __malloc char *para_tmpname(void)
-{
- struct timeval now;
- unsigned int seed;
-
- gettimeofday(&now, NULL);
- seed = now.tv_usec;
- srand(seed);
- return make_message("%08i", rand());
-}
-
/**
* Get the logname of the current user.
*
private_data);
}
+#define hex(a) (hexchar[(a) & 15])
+static void write_size_header(char *buf, int n)
+{
+ static char hexchar[] = "0123456789abcdef";
+
+ buf[0] = hex(n >> 12);
+ buf[1] = hex(n >> 8);
+ buf[2] = hex(n >> 4);
+ buf[3] = hex(n);
+ buf[4] = ' ';
+}
+
+int read_size_header(const char *buf)
+{
+ int i, len = 0;
+
+ for (i = 0; i < 4; i++) {
+ unsigned char c = buf[i];
+ len <<= 4;
+ if (c >= '0' && c <= '9') {
+ len += c - '0';
+ continue;
+ }
+ if (c >= 'a' && c <= 'f') {
+ len += c - 'a' + 10;
+ continue;
+ }
+ return -E_SIZE_PREFIX;
+ }
+ if (buf[4] != ' ')
+ return -E_SIZE_PREFIX;
+ return len;
+}
+
/**
* Safely print into a buffer at a given offset.
*
* private_data pointer of \a b are passed to the \a max_size_handler of \a b.
* If this function succeeds, i.e. returns a non-negative value, the offset of
* \a b is reset to zero and the given data is written to the beginning of the
- * buffer.
+ * buffer. If \a max_size_handler() returns a negative value, this value is
+ * returned by \a para_printf().
*
* Upon return, the offset of \a b is adjusted accordingly so that subsequent
* calls to this function append data to what is already contained in the
* initial buffer is allocated.
*
* \return The number of bytes printed into the buffer (not including the
- * terminating \p NULL byte).
+ * terminating \p NULL byte) on success, negative on errors. If there is no
+ * size-bound on \a b, i.e. if \p b->max_size is zero, this function never
+ * fails.
*
* \sa make_message(), vsnprintf(3).
*/
__printf_2_3 int para_printf(struct para_buffer *b, const char *fmt, ...)
{
- int ret;
+ int ret, sz_off = (b->flags & PBF_SIZE_PREFIX)? 5 : 0;
if (!b->buf) {
b->buf = para_malloc(128);
char *p = b->buf + b->offset;
size_t size = b->size - b->offset;
va_list ap;
- if (size) {
+
+ if (size > sz_off) {
va_start(ap, fmt);
- ret = vsnprintf(p, size, fmt, ap);
+ ret = vsnprintf(p + sz_off, size - sz_off, fmt, ap);
va_end(ap);
- if (ret > -1 && ret < size) { /* success */
- b->offset += ret;
- return ret;
+ if (ret > -1 && ret < size - sz_off) { /* success */
+ b->offset += ret + sz_off;
+ if (sz_off)
+ write_size_header(p, ret);
+ return ret + sz_off;
}
}
/* check if we may grow the buffer */