]> git.sur5r.net Git - openldap/commitdiff
ITS#8097 nssov: update nss-pam-ldapd files to 0.9.4
authorRyan Tandy <ryan@nardis.ca>
Wed, 7 Jan 2015 15:45:23 +0000 (07:45 -0800)
committerQuanah Gibson-Mount <quanah@openldap.org>
Fri, 17 Apr 2015 18:18:23 +0000 (13:18 -0500)
contrib/slapd-modules/nssov/nss-pam-ldapd/README
contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h
contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h
contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd.h
contrib/slapd-modules/nssov/nss-pam-ldapd/tio.c
contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h

index 39198dd998116e5a5feac2434408bb8d71fb9ac7..4176ad7d63d0756b25a41e3d92e9dd9a276f1769 100644 (file)
@@ -1,4 +1,4 @@
-These files were pulled from the nss-pam-ldapd project version 0.8.12.
+These files were pulled from the nss-pam-ldapd project version 0.9.4.
 Copyright notices are in the individual files.
 
 This is not the full distribution of nss-pam-ldapd, and does not
@@ -10,6 +10,6 @@ If your system already has the nss-pam-ldapd stub libraries
 installed, make sure the versions match the version number
 shown above. Otherwise, there may be incompatible differences in
 the protocols being used. Currently nssov requires at least
-version 0.8.11. If your system's version is older, you will need
+version 0.9.0. If your system's version is older, you will need
 to install the client-side stubs from source.
 
index 0bc0f30d90e5a8c6767dfdb97e360da0ab125bd6..83f1777f22f5ff2693dea810805924f513fd6585 100644 (file)
@@ -1,7 +1,7 @@
 /*
    attrs.h - wrapper macros for the gcc __attribute__(()) directive
 
-   Copyright (C) 2007, 2008 Arthur de Jong
+   Copyright (C) 2007, 2008, 2012 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,7 @@
 #define COMPAT__ATTRS_H 1
 
 /* macro for testing the version of GCC */
-#define GCC_VERSION(major,minor) \
+#define GCC_VERSION(major, minor)                                           \
   ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
 
 /* These are macros to use some gcc-specific flags in case the're available
@@ -34,7 +34,7 @@
 
 /* this is used to flag function parameters that are not used in the function
    body. */
-#if GCC_VERSION(3,0)
+#if GCC_VERSION(3, 0)
 #define UNUSED(x)   x __attribute__((__unused__))
 #else
 #define UNUSED(x)   x
 
 /* this is used to add extra format checking to the function calls as if this
    was a printf()-like function */
-#if GCC_VERSION(3,0)
-#define LIKE_PRINTF(format_idx,arg_idx) \
-                    __attribute__((__format__(__printf__,format_idx,arg_idx)))
+#if GCC_VERSION(3, 0)
+#define LIKE_PRINTF(format_idx, arg_idx)                                    \
+                    __attribute__((__format__(__printf__, format_idx, arg_idx)))
 #else
-#define LIKE_PRINTF(format_idx,arg_idx) /* no attribute */
+#define LIKE_PRINTF(format_idx, arg_idx) /* no attribute */
 #endif
 
-/* indicates that the function is "pure": it's result is purely based on
+/* indicates that the function is "pure": its result is purely based on
    the parameters and has no side effects or used static data */
-#if GCC_VERSION(3,0)
+#if GCC_VERSION(3, 0)
 #define PURE        __attribute__((__pure__))
 #else
 #define PURE        /* no attribute */
 
 /* the function returns a new data structure that has been freshly
    allocated */
-#if GCC_VERSION(3,0)
+#if GCC_VERSION(3, 0)
 #define LIKE_MALLOC __attribute__((__malloc__))
 #else
 #define LIKE_MALLOC /* no attribute */
 #endif
 
 /* the function's return value should be used by the caller */
-#if GCC_VERSION(3,4)
+#if GCC_VERSION(3, 4)
 #define MUST_USE    __attribute__((__warn_unused_result__))
 #else
 #define MUST_USE    /* no attribute */
 #endif
 
 /* the function's return value should be used by the caller */
-#if GCC_VERSION(2,5)
+#if GCC_VERSION(2, 5)
 #define NORETURN    __attribute__((__noreturn__))
 #else
 #define NORETURN    /* no attribute */
index 1252158c6dab97f94657da8b3271017097e2f107..649be890ccffa24f1b17530dab16b059341329ed 100644 (file)
@@ -2,7 +2,7 @@
    nslcd-prot.h - helper macros for reading and writing in protocol streams
 
    Copyright (C) 2006 West Consulting
-   Copyright (C) 2006, 2007, 2009 Arthur de Jong
+   Copyright (C) 2006-2014 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,9 @@
 #ifndef COMMON__NSLCD_PROT_H
 #define COMMON__NSLCD_PROT_H 1
 
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
 #include "tio.h"
 
 /* If you use these macros you should define the following macros to
 /* define a debugging macro to output logging */
 #include <string.h>
 #include <errno.h>
-#define DEBUG_PRINT(fmt,arg) \
-  fprintf(stderr,"%s:%d:%s: " fmt "\n",__FILE__,__LINE__,__PRETTY_FUNCTION__,arg);
+#define DEBUG_PRINT(fmt, arg)                                               \
+  fprintf(stderr, "%s:%d:%s: " fmt "\n", __FILE__, __LINE__,                \
+          __PRETTY_FUNCTION__, arg);
 #else /* DEBUG_PROT */
 /* define an empty debug macro to disable logging */
-#define DEBUG_PRINT(fmt,arg)
+#define DEBUG_PRINT(fmt, arg)
 #endif /* not DEBUG_PROT */
 
 #ifdef DEBUG_PROT_DUMP
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif /* HAVE_STDINT_H */
-static void debug_dump(const void *ptr,size_t size)
+static void debug_dump(const void *ptr, size_t size)
 {
   int i;
-  for (i=0;i<size;i++)
-    fprintf(stderr," %02x",((const uint8_t *)ptr)[i]);
-  fprintf(stderr,"\n");
+  for (i = 0; i < size; i++)
+    fprintf(stderr, " %02x", ((const uint8_t *)ptr)[i]);
+  fprintf(stderr, "\n");
 }
-#define DEBUG_DUMP(ptr,size) \
-  fprintf(stderr,"%s:%d:%s:",__FILE__,__LINE__,__PRETTY_FUNCTION__); \
-  debug_dump(ptr,size);
+#define DEBUG_DUMP(ptr, size)                                               \
+  fprintf(stderr, "%s:%d:%s:", __FILE__, __LINE__, __PRETTY_FUNCTION__);    \
+  debug_dump(ptr, size);
 #else /* DEBUG_PROT_DUMP */
 /* define an empty debug macro to disable logging */
-#define DEBUG_DUMP(ptr,size)
+#define DEBUG_DUMP(ptr, size)
 #endif /* not DEBUG_PROT_DUMP */
 
 
@@ -77,76 +81,76 @@ static void debug_dump(const void *ptr,size_t size)
    int32_t tmpint32; - temporary variable
    */
 
-#define WRITE(fp,ptr,size) \
-  DEBUG_PRINT("WRITE       : var="__STRING(ptr)" size=%d",(int)size); \
-  DEBUG_DUMP(ptr,size); \
-  if (tio_write(fp,ptr,(size_t)size)) \
-  { \
-    DEBUG_PRINT("WRITE       : var="__STRING(ptr)" error: %s",strerror(errno)); \
-    ERROR_OUT_WRITEERROR(fp); \
+#define WRITE(fp, ptr, size)                                                \
+  DEBUG_PRINT("WRITE       : var="__STRING(ptr)" size=%d", (int)size);      \
+  DEBUG_DUMP(ptr, size);                                                    \
+  if (tio_write(fp, ptr, (size_t)size))                                     \
+  {                                                                         \
+    DEBUG_PRINT("WRITE       : var="__STRING(ptr)" error: %s",              \
+                strerror(errno));                                           \
+    ERROR_OUT_WRITEERROR(fp);                                               \
   }
 
-#define WRITE_TYPE(fp,field,type) \
-  WRITE(fp,&(field),sizeof(type))
-
-#define WRITE_INT32(fp,i) \
-  DEBUG_PRINT("WRITE_INT32 : var="__STRING(i)" int32=%d",(int)i); \
-  tmpint32=(int32_t)(i); \
-  WRITE_TYPE(fp,tmpint32,int32_t)
-
-#define WRITE_STRING(fp,str) \
-  DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"",(str)); \
-  if ((str)==NULL) \
-  { \
-    WRITE_INT32(fp,0); \
-  } \
-  else \
-  { \
-    WRITE_INT32(fp,strlen(str)); \
-    if (tmpint32>0) \
-      { WRITE(fp,(str),tmpint32); } \
+#define WRITE_INT32(fp, i)                                                  \
+  DEBUG_PRINT("WRITE_INT32 : var="__STRING(i)" int32=%08x", (int)i);        \
+  tmpint32 = htonl((int32_t)(i));                                           \
+  WRITE(fp, &tmpint32, sizeof(int32_t))
+
+#define WRITE_STRING(fp, str)                                               \
+  DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"", (str));    \
+  if ((str) == NULL)                                                        \
+  {                                                                         \
+    WRITE_INT32(fp, 0);                                                     \
+  }                                                                         \
+  else                                                                      \
+  {                                                                         \
+    WRITE_INT32(fp, strlen(str));                                           \
+    tmpint32 = ntohl(tmpint32);                                             \
+    if (tmpint32 > 0)                                                       \
+    {                                                                       \
+      WRITE(fp, (str), tmpint32);                                           \
+    }                                                                       \
   }
 
-#define WRITE_STRINGLIST(fp,arr) \
-  if ((arr)==NULL) \
-  { \
-    DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",0); \
-    WRITE_INT32(fp,0); \
-  } \
-  else \
-  { \
-    /* first determin length of array */ \
-    for (tmp3int32=0;(arr)[tmp3int32]!=NULL;tmp3int32++) \
-      /*noting*/ ; \
-    /* write number of strings */ \
-    DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \
-    WRITE_TYPE(fp,tmp3int32,int32_t); \
-    /* write strings */ \
-    for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \
-    { \
-      WRITE_STRING(fp,(arr)[tmp2int32]); \
-    } \
+#define WRITE_STRINGLIST(fp, arr)                                           \
+  if ((arr) == NULL)                                                        \
+  {                                                                         \
+    DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d", 0);             \
+    WRITE_INT32(fp, 0);                                                     \
+  }                                                                         \
+  else                                                                      \
+  {                                                                         \
+    /* first determine length of array */                                   \
+    for (tmp3int32 = 0; (arr)[tmp3int32] != NULL; tmp3int32++)              \
+      /* noting */ ;                                                        \
+    /* write number of strings */                                           \
+    DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d", (int)tmp3int32); \
+    WRITE_INT32(fp, tmp3int32);                                             \
+    /* write strings */                                                     \
+    for (tmp2int32 = 0; tmp2int32 < tmp3int32; tmp2int32++)                 \
+    {                                                                       \
+      WRITE_STRING(fp, (arr)[tmp2int32]);                                   \
+    }                                                                       \
   }
 
-#define WRITE_STRINGLIST_EXCEPT(fp,arr,not) \
-  /* first determin length of array */ \
-  tmp3int32=0; \
-  for (tmp2int32=0;(arr)[tmp2int32]!=NULL;tmp2int32++) \
-    if (strcmp((arr)[tmp2int32],(not))!=0) \
-      tmp3int32++; \
-  /* write number of strings (mius one because we intend to skip one) */ \
-  DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \
-  WRITE_TYPE(fp,tmp3int32,int32_t); \
-  /* write strings */ \
-  for (tmp2int32=0;(arr)[tmp2int32]!=NULL;tmp2int32++) \
-  { \
-    if (strcmp((arr)[tmp2int32],(not))!=0) \
-    { \
-      WRITE_STRING(fp,(arr)[tmp2int32]); \
-    } \
+#define WRITE_STRINGLIST_EXCEPT(fp, arr, not)                               \
+  /* first determine length of array */                                     \
+  tmp3int32 = 0;                                                            \
+  for (tmp2int32 = 0; (arr)[tmp2int32] != NULL; tmp2int32++)                \
+    if (strcmp((arr)[tmp2int32], (not)) != 0)                               \
+      tmp3int32++;                                                          \
+  /* write number of strings (mius one because we intend to skip one) */    \
+  DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d", (int)tmp3int32);  \
+  WRITE_INT32(fp, tmp3int32);                                               \
+  /* write strings */                                                       \
+  for (tmp2int32 = 0; (arr)[tmp2int32] != NULL; tmp2int32++)                \
+  {                                                                         \
+    if (strcmp((arr)[tmp2int32], (not)) != 0)                               \
+    {                                                                       \
+      WRITE_STRING(fp, (arr)[tmp2int32]);                                   \
+    }                                                                       \
   }
 
-
 /* READ macros, used for reading data, on read error they will
    call the ERROR_OUT_READERROR or ERROR_OUT_BUFERROR macro
    these macros may require the availability of the following
@@ -154,42 +158,43 @@ static void debug_dump(const void *ptr,size_t size)
    int32_t tmpint32; - temporary variable
    */
 
-#define READ(fp,ptr,size) \
-  if (tio_read(fp,ptr,(size_t)size)) \
-  { \
-    DEBUG_PRINT("READ       : var="__STRING(ptr)" error: %s",strerror(errno)); \
-    ERROR_OUT_READERROR(fp); \
-  } \
-  DEBUG_PRINT("READ       : var="__STRING(ptr)" size=%d",(int)size); \
-  DEBUG_DUMP(ptr,size);
-
-#define READ_TYPE(fp,field,type) \
-  READ(fp,&(field),sizeof(type))
-
-#define READ_INT32(fp,i) \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  i=tmpint32; \
-  DEBUG_PRINT("READ_INT32 : var="__STRING(i)" int32=%d",(int)i);
+#define READ(fp, ptr, size)                                                 \
+  if (tio_read(fp, ptr, (size_t)size))                                      \
+  {                                                                         \
+    DEBUG_PRINT("READ       : var="__STRING(ptr)" error: %s",               \
+                strerror(errno));                                           \
+    ERROR_OUT_READERROR(fp);                                                \
+  }                                                                         \
+  DEBUG_PRINT("READ       : var="__STRING(ptr)" size=%d", (int)(size));     \
+  DEBUG_DUMP(ptr, size);
+
+#define READ_INT32(fp, i)                                                   \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  (i) = (int32_t)ntohl(tmpint32);                                           \
+  DEBUG_PRINT("READ_INT32 : var="__STRING(i)" int32==%08x", (int)(i));
 
 /* read a string in a fixed-size "normal" buffer */
-#define READ_STRING(fp,buffer) \
-  /* read the size of the string */ \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" strlen=%d",tmpint32); \
-  /* check if read would fit */ \
-  if (((size_t)tmpint32)>=sizeof(buffer)) \
-  { \
-    /* will not fit */ \
-    tmpint32=(tmpint32-sizeof(buffer))+1; \
-    DEBUG_PRINT("READ       : buffer %d bytes too small",tmpint32); \
-    ERROR_OUT_BUFERROR(fp); \
-  } \
-  /* read string from the stream */ \
-  if (tmpint32>0) \
-    { READ(fp,buffer,(size_t)tmpint32); } \
-  /* null-terminate string in buffer */ \
-  buffer[tmpint32]='\0'; \
-  DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" string=\"%s\"",buffer);
+#define READ_STRING(fp, buffer)                                             \
+  /* read the size of the string */                                         \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" strlen=%d", tmpint32);   \
+  /* check if read would fit */                                             \
+  if (((size_t)tmpint32) >= sizeof(buffer))                                 \
+  {                                                                         \
+    /* will not fit */                                                      \
+    tmpint32 = (tmpint32 - sizeof(buffer)) + 1;                             \
+    DEBUG_PRINT("READ       : buffer %d bytes too small", tmpint32);        \
+    ERROR_OUT_BUFERROR(fp);                                                 \
+  }                                                                         \
+  /* read string from the stream */                                         \
+  if (tmpint32 > 0)                                                         \
+  {                                                                         \
+    READ(fp, buffer, (size_t)tmpint32);                                     \
+  }                                                                         \
+  /* null-terminate string in buffer */                                     \
+  buffer[tmpint32] = '\0';                                                  \
+  DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" string=\"%s\"", buffer);
 
 
 /* READ BUF macros that read data into a pre-allocated buffer.
@@ -202,116 +207,123 @@ static void debug_dump(const void *ptr,size_t size)
    */
 
 /* current position in the buffer */
-#define BUF_CUR \
-  (buffer+bufptr)
+#define BUF_CUR                                                             \
+  (buffer + bufptr)
 
 /* check that the buffer has sz bytes left in it */
-#define BUF_CHECK(fp,sz) \
-  if ((bufptr+(size_t)(sz))>buflen) \
-  { \
-    /* will not fit */ \
-    tmpint32=bufptr+(sz)-(buflen); \
-    DEBUG_PRINT("READ       : buffer %d bytes too small",tmpint32); \
-    ERROR_OUT_BUFERROR(fp); \
+#define BUF_CHECK(fp, sz)                                                   \
+  if ((bufptr + (size_t)(sz)) > buflen)                                     \
+  {                                                                         \
+    /* will not fit */                                                      \
+    tmpint32 = bufptr + (sz) - (buflen);                                    \
+    DEBUG_PRINT("READ       : buffer %d bytes too small", tmpint32);        \
+    ERROR_OUT_BUFERROR(fp);                                                 \
   }
 
 /* move the buffer pointer */
-#define BUF_SKIP(sz) \
-  bufptr+=(size_t)(sz);
+#define BUF_SKIP(sz)                                                        \
+  bufptr += (size_t)(sz);
 
 /* move BUF_CUR foreward so that it is aligned to the specified
    type width */
-#define BUF_ALIGN(fp,type) \
-  /* figure out number of bytes to skip foreward */ \
-  tmp2int32=(sizeof(type)-((BUF_CUR-(char *)NULL)%sizeof(type)))%sizeof(type); \
-  /* check and skip */ \
-  BUF_CHECK(fp,tmp2int32); \
+#define BUF_ALIGN(fp, type)                                                 \
+  /* figure out number of bytes to skip foreward */                         \
+  tmp2int32 = (sizeof(type) - ((BUF_CUR - (char *)NULL) % sizeof(type)))    \
+              % sizeof(type);                                               \
+  /* check and skip */                                                      \
+  BUF_CHECK(fp, tmp2int32);                                                 \
   BUF_SKIP(tmp2int32);
 
 /* allocate a piece of the buffer to store an array in */
-#define BUF_ALLOC(fp,ptr,type,num) \
-  /* align to the specified type width */ \
-  BUF_ALIGN(fp,type); \
-  /* check that we have enough room */ \
-  BUF_CHECK(fp,(size_t)(num)*sizeof(type)); \
-  /* store the pointer */ \
-  (ptr)=(type *)BUF_CUR; \
-  /* reserve the space */ \
-  BUF_SKIP((size_t)(num)*sizeof(type));
+#define BUF_ALLOC(fp, ptr, type, num)                                       \
+  /* align to the specified type width */                                   \
+  BUF_ALIGN(fp, type);                                                      \
+  /* check that we have enough room */                                      \
+  BUF_CHECK(fp, (size_t)(num) * sizeof(type));                              \
+  /* store the pointer */                                                   \
+  (ptr) = (type *)BUF_CUR;                                                  \
+  /* reserve the space */                                                   \
+  BUF_SKIP((size_t)(num) * sizeof(type));
 
 /* read a binary blob into the buffer */
-#define READ_BUF(fp,ptr,sz) \
-  /* check that there is enough room and read */ \
-  BUF_CHECK(fp,sz); \
-  READ(fp,BUF_CUR,(size_t)sz); \
-  /* store pointer and skip */ \
-  (ptr)=BUF_CUR; \
+#define READ_BUF(fp, ptr, sz)                                               \
+  /* check that there is enough room and read */                            \
+  BUF_CHECK(fp, sz);                                                        \
+  READ(fp, BUF_CUR, (size_t)sz);                                            \
+  /* store pointer and skip */                                              \
+  (ptr) = BUF_CUR;                                                          \
   BUF_SKIP(sz);
 
 /* read string in the buffer (using buffer, buflen and bufptr)
    and store the actual location of the string in field */
-#define READ_BUF_STRING(fp,field) \
-  /* read the size of the string */ \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" strlen=%d",tmpint32); \
-  /* check if read would fit */ \
-  BUF_CHECK(fp,tmpint32+1); \
-  /* read string from the stream */ \
-  if (tmpint32>0) \
-    { READ(fp,BUF_CUR,(size_t)tmpint32); } \
-  /* null-terminate string in buffer */ \
-  BUF_CUR[tmpint32]='\0'; \
-  DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" string=\"%s\"",BUF_CUR); \
-  /* prepare result */ \
-  (field)=BUF_CUR; \
-  BUF_SKIP(tmpint32+1);
+#define READ_BUF_STRING(fp, field)                                          \
+  /* read the size of the string */                                         \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" strlen=%d", tmpint32); \
+  /* check if read would fit */                                             \
+  BUF_CHECK(fp, tmpint32 + 1);                                              \
+  /* read string from the stream */                                         \
+  if (tmpint32 > 0)                                                         \
+  {                                                                         \
+    READ(fp, BUF_CUR, (size_t)tmpint32);                                    \
+  }                                                                         \
+  /* null-terminate string in buffer */                                     \
+  BUF_CUR[tmpint32] = '\0';                                                 \
+  DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" string=\"%s\"", BUF_CUR); \
+  /* prepare result */                                                      \
+  (field) = BUF_CUR;                                                        \
+  BUF_SKIP(tmpint32 + 1);
 
 /* read an array from a stram and store it as a null-terminated
    array list (size for the array is allocated) */
-#define READ_BUF_STRINGLIST(fp,arr) \
-  /* read the number of entries */ \
-  READ_TYPE(fp,tmp3int32,int32_t); \
-  DEBUG_PRINT("READ_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \
-  /* allocate room for *char[num+1] */ \
-  BUF_ALLOC(fp,arr,char *,tmp3int32+1); \
-  /* read all entries */ \
-  for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \
-  { \
-    READ_BUF_STRING(fp,(arr)[tmp2int32]); \
-  } \
-  /* set last entry to NULL */ \
-  (arr)[tmp2int32]=NULL;
+#define READ_BUF_STRINGLIST(fp, arr)                                        \
+  /* read the number of entries */                                          \
+  READ(fp, &tmp3int32, sizeof(int32_t));                                    \
+  tmp3int32 = ntohl(tmp3int32);                                             \
+  DEBUG_PRINT("READ_STRLST: var="__STRING(arr)" num=%d", (int)tmp3int32);   \
+  /* allocate room for *char[num + 1] */                                      \
+  BUF_ALLOC(fp, arr, char *, tmp3int32 + 1);                                \
+  /* read all entries */                                                    \
+  for (tmp2int32 = 0; tmp2int32 < tmp3int32; tmp2int32++)                   \
+  {                                                                         \
+    READ_BUF_STRING(fp, (arr)[tmp2int32]);                                  \
+  }                                                                         \
+  /* set last entry to NULL */                                              \
+  (arr)[tmp2int32] = NULL;
 
 
 /* SKIP macros for skipping over certain parts of the protocol stream. */
 
 /* skip a number of bytes foreward */
-#define SKIP(fp,sz) \
-  DEBUG_PRINT("READ       : skip %d bytes",(int)(sz)); \
-  /* read (skip) the specified number of bytes */ \
-  if (tio_skip(fp,sz)) \
-  { \
-    DEBUG_PRINT("READ       : skip error: %s",strerror(errno)); \
-    ERROR_OUT_READERROR(fp); \
+#define SKIP(fp, sz)                                                        \
+  DEBUG_PRINT("READ       : skip %d bytes", (int)(sz));                     \
+  /* read (skip) the specified number of bytes */                           \
+  if (tio_skip(fp, sz))                                                     \
+  {                                                                         \
+    DEBUG_PRINT("READ       : skip error: %s", strerror(errno));            \
+    ERROR_OUT_READERROR(fp);                                                \
   }
 
 /* read a string from the stream but don't do anything with the result */
-#define SKIP_STRING(fp) \
-  /* read the size of the string */ \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  DEBUG_PRINT("READ_STRING: skip %d bytes",(int)tmpint32); \
-  /* read (skip) the specified number of bytes */ \
-  SKIP(fp,tmpint32);
+#define SKIP_STRING(fp)                                                     \
+  /* read the size of the string */                                         \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  DEBUG_PRINT("READ_STRING: skip %d bytes", (int)tmpint32);                 \
+  /* read (skip) the specified number of bytes */                           \
+  SKIP(fp, tmpint32);
 
 /* skip a list of strings */
-#define SKIP_STRINGLIST(fp) \
-  /* read the number of entries */ \
-  READ_TYPE(fp,tmp3int32,int32_t); \
-  DEBUG_PRINT("READ_STRLST: skip %d strings",(int)tmp3int32); \
-  /* read all entries */ \
-  for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \
-  { \
-    SKIP_STRING(fp); \
+#define SKIP_STRINGLIST(fp)                                                 \
+  /* read the number of entries */                                          \
+  READ(fp, &tmp3int32, sizeof(int32_t));                                    \
+  tmp3int32 = ntohl(tmp3int32);                                             \
+  DEBUG_PRINT("READ_STRLST: skip %d strings", (int)tmp3int32);              \
+  /* read all entries */                                                    \
+  for (tmp2int32 = 0; tmp2int32 < tmp3int32; tmp2int32++)                   \
+  {                                                                         \
+    SKIP_STRING(fp);                                                        \
   }
 
 
@@ -324,35 +336,46 @@ TFILE *nslcd_client_open(void)
   MUST_USE;
 
 /* generic request code */
-#define NSLCD_REQUEST(fp,action,writefn) \
-  /* open a client socket */ \
-  if ((fp=nslcd_client_open())==NULL) \
-    { ERROR_OUT_OPENERROR } \
-  /* write a request header with a request code */ \
-  WRITE_INT32(fp,(int32_t)NSLCD_VERSION) \
-  WRITE_INT32(fp,(int32_t)action) \
-  /* write the request parameters (if any) */ \
-  writefn; \
-  /* flush the stream */ \
-  if (tio_flush(fp)<0) \
-  { \
-    DEBUG_PRINT("WRITE_FLUSH : error: %s",strerror(errno)); \
-    ERROR_OUT_WRITEERROR(fp); \
-  } \
-  /* read and check response version number */ \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  if (tmpint32!=(int32_t)NSLCD_VERSION) \
-    { ERROR_OUT_READERROR(fp) } \
-  /* read and check response request number */ \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  if (tmpint32!=(int32_t)(action)) \
-    { ERROR_OUT_READERROR(fp) }
+#define NSLCD_REQUEST(fp, action, writefn)                                  \
+  /* open a client socket */                                                \
+  if ((fp = nslcd_client_open()) == NULL)                                   \
+  {                                                                         \
+    ERROR_OUT_OPENERROR;                                                    \
+  }                                                                         \
+  /* write a request header with a request code */                          \
+  WRITE_INT32(fp, (int32_t)NSLCD_VERSION)                                   \
+  WRITE_INT32(fp, (int32_t)action)                                          \
+  /* write the request parameters (if any) */                               \
+  writefn;                                                                  \
+  /* flush the stream */                                                    \
+  if (tio_flush(fp) < 0)                                                    \
+  {                                                                         \
+    DEBUG_PRINT("WRITE_FLUSH : error: %s", strerror(errno));                \
+    ERROR_OUT_WRITEERROR(fp);                                               \
+  }                                                                         \
+  /* read and check response version number */                              \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  if (tmpint32 != (int32_t)NSLCD_VERSION)                                   \
+  {                                                                         \
+    ERROR_OUT_READERROR(fp);                                                \
+  }                                                                         \
+  /* read and check response request number */                              \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  if (tmpint32 != (int32_t)(action))                                        \
+  {                                                                         \
+    ERROR_OUT_READERROR(fp);                                                \
+  }
 
 /* Read the response code (the result code of the query) from
    the stream. */
-#define READ_RESPONSE_CODE(fp) \
-  READ_TYPE(fp,tmpint32,int32_t); \
-  if (tmpint32!=(int32_t)NSLCD_RESULT_BEGIN) \
-    { ERROR_OUT_NOSUCCESS(fp) }
+#define READ_RESPONSE_CODE(fp)                                              \
+  READ(fp, &tmpint32, sizeof(int32_t));                                     \
+  tmpint32 = ntohl(tmpint32);                                               \
+  if (tmpint32 != (int32_t)NSLCD_RESULT_BEGIN)                              \
+  {                                                                         \
+    ERROR_OUT_NOSUCCESS(fp);                                                \
+  }
 
 #endif /* not COMMON__NSLCD_PROT_H */
index ebbba7471e3fe209c9dfc0b4d3249dd9d23afd02..c9857d695b50acd7992e2eed0087223a306ee761 100644 (file)
@@ -2,7 +2,7 @@
    nslcd.h - file describing client/server protocol
 
    Copyright (C) 2006 West Consulting
-   Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012 Arthur de Jong
+   Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012, 2013 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    Furthermore the ADDRESS compound data type is defined as:
      INT32  type of address: e.g. AF_INET or AF_INET6
      INT32  lenght of address
-     RAW    the address itself in network byte order
+     RAW    the address itself
    With the ADDRESSLIST using the same construct as with STRINGLIST.
 
-   The protocol uses host-byte order for all types (except in the raw
-   address above).
+   The protocol uses network byte order for all types.
 */
 
-/* The current version of the protocol. Note that version 1
-   is experimental and this version will be used until a
-   1.0 release of nss-pam-ldapd is made. */
-#define NSLCD_VERSION 1
+/* The current version of the protocol. This protocol should only be
+   updated with major backwards-incompatible changes. */
+#define NSLCD_VERSION 0x00000002
 
 /* Get a NSLCD configuration option. There is one request parameter:
     INT32   NSLCD_CONFIG_*
   the result value is:
     STRING  value, interpretation depending on request */
-#define NSLCD_ACTION_CONFIG_GET        20006
+#define NSLCD_ACTION_CONFIG_GET        0x00010001
 
 /* return the message, if any, that is presented to the user when password
    modification through PAM is prohibited */
-#define NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE  852
+#define NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE 1
 
 /* Email alias (/etc/aliases) NSS requests. The result values for a
    single entry are:
      STRING      alias name
      STRINGLIST  alias rcpts */
-#define NSLCD_ACTION_ALIAS_BYNAME       4001
-#define NSLCD_ACTION_ALIAS_ALL          4002
+#define NSLCD_ACTION_ALIAS_BYNAME      0x00020001
+#define NSLCD_ACTION_ALIAS_ALL         0x00020008
 
 /* Ethernet address/name mapping NSS requests. The result values for a
    single entry are:
      STRING            ether name
      TYPE(uint8_t[6])  ether address */
-#define NSLCD_ACTION_ETHER_BYNAME       3001
-#define NSLCD_ACTION_ETHER_BYETHER      3002
-#define NSLCD_ACTION_ETHER_ALL          3005
+#define NSLCD_ACTION_ETHER_BYNAME      0x00030001
+#define NSLCD_ACTION_ETHER_BYETHER     0x00030002
+#define NSLCD_ACTION_ETHER_ALL         0x00030008
 
 /* Group and group membership related NSS requests. The result values
    for a single entry are:
      STRING       group name
      STRING       group password
-     TYPE(gid_t)  group id
+     INT32        group id
      STRINGLIST   members (usernames) of the group
      (not that the BYMEMER call returns an emtpy members list) */
-#define NSLCD_ACTION_GROUP_BYNAME       5001
-#define NSLCD_ACTION_GROUP_BYGID        5002
-#define NSLCD_ACTION_GROUP_BYMEMBER     5003
-#define NSLCD_ACTION_GROUP_ALL          5004
+#define NSLCD_ACTION_GROUP_BYNAME      0x00040001
+#define NSLCD_ACTION_GROUP_BYGID       0x00040002
+#define NSLCD_ACTION_GROUP_BYMEMBER    0x00040006
+#define NSLCD_ACTION_GROUP_ALL         0x00040008
 
 /* Hostname (/etc/hosts) lookup NSS requests. The result values
    for an entry are:
      STRING       host name
      STRINGLIST   host aliases
      ADDRESSLIST  host addresses */
-#define NSLCD_ACTION_HOST_BYNAME        6001
-#define NSLCD_ACTION_HOST_BYADDR        6002
-#define NSLCD_ACTION_HOST_ALL           6005
-
-/* Netgroup NSS request return a number of results. Result values
-   can be either a reference to another netgroup:
+#define NSLCD_ACTION_HOST_BYNAME       0x00050001
+#define NSLCD_ACTION_HOST_BYADDR       0x00050002
+#define NSLCD_ACTION_HOST_ALL          0x00050008
+
+/* Netgroup NSS result entries contain a number of parts. A result entry
+   starts with:
+     STRING  netgroup name
+   followed by zero or more references to other netgroups or netgroup
+   triples. A reference to another netgroup looks like:
      INT32   NSLCD_NETGROUP_TYPE_NETGROUP
      STRING  other netgroup name
-   or a netgroup triple:
+   A a netgroup triple looks like:
      INT32   NSLCD_NETGROUP_TYPE_TRIPLE
      STRING  host
      STRING  user
-     STRING  domain */
-#define NSLCD_ACTION_NETGROUP_BYNAME   12001
-#define NSLCD_NETGROUP_TYPE_NETGROUP 123
-#define NSLCD_NETGROUP_TYPE_TRIPLE   456
+     STRING  domain
+   A netgroup result entry is terminated by:
+     INT32   NSLCD_NETGROUP_TYPE_END
+   */
+#define NSLCD_ACTION_NETGROUP_BYNAME   0x00060001
+#define NSLCD_ACTION_NETGROUP_ALL      0x00060008
+#define NSLCD_NETGROUP_TYPE_NETGROUP 1
+#define NSLCD_NETGROUP_TYPE_TRIPLE   2
+#define NSLCD_NETGROUP_TYPE_END      3
 
 /* Network name (/etc/networks) NSS requests. Result values for a single
    entry are:
      STRING       network name
      STRINGLIST   network aliases
      ADDRESSLIST  network addresses */
-#define NSLCD_ACTION_NETWORK_BYNAME     8001
-#define NSLCD_ACTION_NETWORK_BYADDR     8002
-#define NSLCD_ACTION_NETWORK_ALL        8005
+#define NSLCD_ACTION_NETWORK_BYNAME    0x00070001
+#define NSLCD_ACTION_NETWORK_BYADDR    0x00070002
+#define NSLCD_ACTION_NETWORK_ALL       0x00070008
 
 /* User account (/etc/passwd) NSS requests. Result values are:
      STRING       user name
      STRING       user password
-     TYPE(uid_t)  user id
-     TYPE(gid_t)  group id
+     INT32        user id
+     INT32        group id
      STRING       gecos information
      STRING       home directory
      STRING       login shell */
-#define NSLCD_ACTION_PASSWD_BYNAME      1001
-#define NSLCD_ACTION_PASSWD_BYUID       1002
-#define NSLCD_ACTION_PASSWD_ALL         1004
+#define NSLCD_ACTION_PASSWD_BYNAME     0x00080001
+#define NSLCD_ACTION_PASSWD_BYUID      0x00080002
+#define NSLCD_ACTION_PASSWD_ALL        0x00080008
 
 /* Protocol information requests. Result values are:
      STRING      protocol name
      STRINGLIST  protocol aliases
      INT32       protocol number */
-#define NSLCD_ACTION_PROTOCOL_BYNAME    9001
-#define NSLCD_ACTION_PROTOCOL_BYNUMBER  9002
-#define NSLCD_ACTION_PROTOCOL_ALL       9003
+#define NSLCD_ACTION_PROTOCOL_BYNAME   0x00090001
+#define NSLCD_ACTION_PROTOCOL_BYNUMBER 0x00090002
+#define NSLCD_ACTION_PROTOCOL_ALL      0x00090008
 
 /* RPC information requests. Result values are:
      STRING      rpc name
      STRINGLIST  rpc aliases
      INT32       rpc number */
-#define NSLCD_ACTION_RPC_BYNAME        10001
-#define NSLCD_ACTION_RPC_BYNUMBER      10002
-#define NSLCD_ACTION_RPC_ALL           10003
+#define NSLCD_ACTION_RPC_BYNAME        0x000a0001
+#define NSLCD_ACTION_RPC_BYNUMBER      0x000a0002
+#define NSLCD_ACTION_RPC_ALL           0x000a0008
 
-/* Service (/etc/services) information requests. Result values are:
+/* Service (/etc/services) information requests. The BYNAME and BYNUMBER
+   requests contain an extra protocol string in the request which, if not
+   blank, will filter the services by this protocol. Result values are:
      STRING      service name
      STRINGLIST  service aliases
      INT32       service (port) number
      STRING      service protocol */
-#define NSLCD_ACTION_SERVICE_BYNAME    11001
-#define NSLCD_ACTION_SERVICE_BYNUMBER  11002
-#define NSLCD_ACTION_SERVICE_ALL       11005
+#define NSLCD_ACTION_SERVICE_BYNAME    0x000b0001
+#define NSLCD_ACTION_SERVICE_BYNUMBER  0x000b0002
+#define NSLCD_ACTION_SERVICE_ALL       0x000b0008
 
 /* Extended user account (/etc/shadow) information requests. Result
    values for a single entry are:
      INT32   inact
      INT32   expire
      INT32   flag */
-#define NSLCD_ACTION_SHADOW_BYNAME      2001
-#define NSLCD_ACTION_SHADOW_ALL         2005
+#define NSLCD_ACTION_SHADOW_BYNAME     0x000c0001
+#define NSLCD_ACTION_SHADOW_ALL        0x000c0008
 
 /* PAM-related requests. The request parameters for all these requests
    begin with:
      STRING  user name
-     STRING  DN (if value is known already, otherwise empty)
      STRING  service name
-   all requests, except the SESSION requests start the result value with:
-     STRING  user name (cannonical name)
-     STRING  DN (can be used to speed up requests)
-   Some functions may return an authorisation message. This message, if
-   supplied will be used by the PAM module instead of a message that is
-   generated by the PAM module itself. */
+     STRING  ruser
+     STRING  rhost
+     STRING  tty
+   If the user is not known in LDAP no result may be returned (immediately
+   return NSLCD_RESULT_END instead of a PAM error code). */
 
 /* PAM authentication check request. The extra request values are:
      STRING  password
-   and the result value ends with:
+   and the result value consists of:
      INT32   authc NSLCD_PAM_* result code
+     STRING  user name (the cannonical user name)
      INT32   authz NSLCD_PAM_* result code
      STRING  authorisation error message
    If the username is empty in this request an attempt is made to
-   authenticate as the administrator (set using rootpwmoddn). The returned DN
-   is that of the administrator. */
-#define NSLCD_ACTION_PAM_AUTHC         20001
-
-/* PAM authorisation check request. The extra request values are:
-     STRING ruser
-     STRING rhost
-     STRING tty
-   and the result value ends with:
+   authenticate as the administrator (set using rootpwmoddn).
+   Some authorisation checks are already done during authentication so the
+   response also includes authorisation information. */
+#define NSLCD_ACTION_PAM_AUTHC         0x000d0001
+
+/* PAM authorisation check request. The result value consists of:
      INT32   authz NSLCD_PAM_* result code
-     STRING  authorisation error message */
-#define NSLCD_ACTION_PAM_AUTHZ         20002
-
-/* PAM session open and close requests. These requests have the following
-   extra request values:
-     STRING tty
-     STRING rhost
-     STRING ruser
-     INT32 session id (ignored for SESS_O)
-   and these calls only return the session ID:
-     INT32 session id
-   The SESS_C must contain the ID that is retured by SESS_O to close the
-   correct session. */
-#define NSLCD_ACTION_PAM_SESS_O        20003
-#define NSLCD_ACTION_PAM_SESS_C        20004
+     STRING  authorisation error message
+   The authentication check may have already returned some authorisation
+   information. The authorisation error message, if supplied, will be used
+   by the PAM module instead of a message that is generated by the PAM
+   module itself. */
+#define NSLCD_ACTION_PAM_AUTHZ         0x000d0002
+
+/* PAM session open request. The result value consists of:
+     STRING   session id
+   This session id may be used to close this session with. */
+#define NSLCD_ACTION_PAM_SESS_O        0x000d0003
+
+/* PAM session close request. This request has the following
+   extra request value:
+     STRING   session id
+   and this calls only returns an empty response value. */
+#define NSLCD_ACTION_PAM_SESS_C        0x000d0004
 
 /* PAM password modification request. This requests has the following extra
    request values:
-     STRING old password
-     STRING new password
+     INT32   asroot: 0=oldpasswd is user passwd, 1=oldpasswd is root passwd
+     STRING  old password
+     STRING  new password
    and returns there extra result values:
-     INT32   authz NSLCD_PAM_* result code
-     STRING  authorisation error message
-   In this request the DN may be set to the administrator's DN. In this
-   case old password should be the administrator's password. This allows
-   the administrator to change any user's password. */
-#define NSLCD_ACTION_PAM_PWMOD         20005
+     INT32   NSLCD_PAM_* result code
+     STRING  error message */
+#define NSLCD_ACTION_PAM_PWMOD         0x000d0005
+
+/* User information change request. This request allows one to change
+   their full name and other information. The request parameters for this
+   request are:
+     STRING  user name
+     INT32   asroot: 0=passwd is user passwd, 1=passwd is root passwd
+     STRING  password
+   followed by one or more of the below, terminated by NSLCD_USERMOD_END
+     INT32   NSLCD_USERMOD_*
+     STRING  new value
+   the response consists of one or more of the entries below, terminated
+   by NSLCD_USERMOD_END:
+     INT32   NSLCD_USERMOD_*
+     STRING  response
+   (if the response is blank, the change went OK, otherwise the string
+   contains an error message)
+   */
+#define NSLCD_ACTION_USERMOD           0x000e0001
+
+/* These are the possible values for the NSLCD_ACTION_USERMOD operation
+   above. */
+#define NSLCD_USERMOD_END        0 /* end of change values */
+#define NSLCD_USERMOD_RESULT     1 /* global result value */
+#define NSLCD_USERMOD_FULLNAME   2 /* full name */
+#define NSLCD_USERMOD_ROOMNUMBER 3 /* room number */
+#define NSLCD_USERMOD_WORKPHONE  4 /* office phone number */
+#define NSLCD_USERMOD_HOMEPHONE  5 /* home phone number */
+#define NSLCD_USERMOD_OTHER      6 /* other info */
+#define NSLCD_USERMOD_HOMEDIR    7 /* home directory */
+#define NSLCD_USERMOD_SHELL      8 /* login shell */
 
 /* Request result codes. */
-#define NSLCD_RESULT_BEGIN                 0
-#define NSLCD_RESULT_END                   3
+#define NSLCD_RESULT_BEGIN 1
+#define NSLCD_RESULT_END   2
 
 /* Partial list of PAM result codes. */
 #define NSLCD_PAM_SUCCESS             0 /* everything ok */
index 31764c707c1676aa0ab64ec89fb52a183d7dcbe6..11ad4f7c5e670afd293334dbd580b13769a98e3c 100644 (file)
@@ -2,7 +2,7 @@
    tio.c - timed io functions
    This file is part of the nss-pam-ldapd library.
 
-   Copyright (C) 2007, 2008, 2010, 2011, 2012 Arthur de Jong
+   Copyright (C) 2007-2014 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,6 @@
    02110-1301 USA
 */
 
-//#include "config.h"
 #include "portable.h"
 
 #ifdef HAVE_STDINT_H
@@ -37,6 +36,7 @@
 #include <stdio.h>
 #include <limits.h>
 #include <poll.h>
+#include <time.h>
 
 #include "tio.h"
 
@@ -76,124 +76,117 @@ struct tio_fileinfo {
 #endif /* DEBUG_TIO_STATS */
 };
 
-/* build a timeval for comparison to when the operation should be finished */
-static inline void tio_get_deadline(struct timeval *deadline,int timeout)
-{
-  if (gettimeofday(deadline,NULL))
-  {
-    /* just blank it in case of errors */
-    deadline->tv_sec=0;
-    deadline->tv_usec=0;
-    return;
-  }
-  deadline->tv_sec+=timeout/1000;
-  deadline->tv_sec+=(timeout%1000)*1000;
-}
+/* some older versions of Solaris don't provide CLOCK_MONOTONIC but do have
+   a CLOCK_HIGHRES that has the same properties we need */
+#ifndef CLOCK_MONOTONIC
+#ifdef CLOCK_HIGHRES
+#define CLOCK_MONOTONIC CLOCK_HIGHRES
+#endif /* CLOCK_HIGHRES */
+#endif /* not CLOCK_MONOTONIC */
 
-/* update the timeout to the value that is remaining before deadline
-   returns non-zero if there is no more time before the deadline */
-static inline int tio_time_remaining(const struct timeval *deadline)
+/* update the timeout to the value that is remaining before the deadline
+   returns the number of milliseconds before the deadline (or a negative
+   value of the deadline has expired) */
+static inline int tio_time_remaining(struct timespec *deadline, int timeout)
 {
-  struct timeval tv;
-  /* get the current time */
-  if (gettimeofday(&tv,NULL))
+  struct timespec tv;
+  /* if this is the first call, set the deadline and return the full time */
+  if ((deadline->tv_sec == 0) && (deadline->tv_nsec == 0))
   {
-    /* 1 second default if gettimeofday() is broken */
-    return 1000;
+    if (clock_gettime(CLOCK_MONOTONIC, deadline) == 0)
+    {
+      deadline->tv_sec += timeout / 1000;
+      deadline->tv_nsec += (timeout % 1000) * 1000000;
+    }
+    return timeout;
   }
-  /* calculate time remaining in miliseconds */
-  return (deadline->tv_sec-tv.tv_sec)*1000 + (deadline->tv_usec-tv.tv_usec)/1000;
+  /* get the current time (fall back to full time on error) */
+  if (clock_gettime(CLOCK_MONOTONIC, &tv))
+    return timeout;
+  /* calculate time remaining in milliseconds */
+  return (deadline->tv_sec - tv.tv_sec) * 1000 +
+         (deadline->tv_nsec - tv.tv_nsec) / 1000000;
 }
 
 /* open a new TFILE based on the file descriptor */
-TFILE *tio_fdopen(int fd,int readtimeout,int writetimeout,
-                  size_t initreadsize,size_t maxreadsize,
-                  size_t initwritesize,size_t maxwritesize)
+TFILE *tio_fdopen(int fd, int readtimeout, int writetimeout,
+                  size_t initreadsize, size_t maxreadsize,
+                  size_t initwritesize, size_t maxwritesize)
 {
   struct tio_fileinfo *fp;
-  fp=(struct tio_fileinfo *)malloc(sizeof(struct tio_fileinfo));
-  if (fp==NULL)
+  fp = (struct tio_fileinfo *)malloc(sizeof(struct tio_fileinfo));
+  if (fp == NULL)
     return NULL;
-  fp->fd=fd;
+  fp->fd = fd;
   /* initialize read buffer */
-  fp->readbuffer.buffer=(uint8_t *)malloc(initreadsize);
-  if (fp->readbuffer.buffer==NULL)
+  fp->readbuffer.buffer = (uint8_t *)malloc(initreadsize);
+  if (fp->readbuffer.buffer == NULL)
   {
     free(fp);
     return NULL;
   }
-  fp->readbuffer.size=initreadsize;
-  fp->readbuffer.maxsize=maxreadsize;
-  fp->readbuffer.start=0;
-  fp->readbuffer.len=0;
+  fp->readbuffer.size = initreadsize;
+  fp->readbuffer.maxsize = maxreadsize;
+  fp->readbuffer.start = 0;
+  fp->readbuffer.len = 0;
   /* initialize write buffer */
-  fp->writebuffer.buffer=(uint8_t *)malloc(initwritesize);
-  if (fp->writebuffer.buffer==NULL)
+  fp->writebuffer.buffer = (uint8_t *)malloc(initwritesize);
+  if (fp->writebuffer.buffer == NULL)
   {
     free(fp->readbuffer.buffer);
     free(fp);
     return NULL;
   }
-  fp->writebuffer.size=initwritesize;
-  fp->writebuffer.maxsize=maxwritesize;
-  fp->writebuffer.start=0;
-  fp->writebuffer.len=0;
+  fp->writebuffer.size = initwritesize;
+  fp->writebuffer.maxsize = maxwritesize;
+  fp->writebuffer.start = 0;
+  fp->writebuffer.len = 0;
   /* initialize other attributes */
-  fp->readtimeout=readtimeout;
-  fp->writetimeout=writetimeout;
-  fp->read_resettable=0;
+  fp->readtimeout = readtimeout;
+  fp->writetimeout = writetimeout;
+  fp->read_resettable = 0;
 #ifdef DEBUG_TIO_STATS
-  fp->byteswritten=0;
-  fp->bytesread=0;
+  fp->byteswritten = 0;
+  fp->bytesread = 0;
 #endif /* DEBUG_TIO_STATS */
   return fp;
 }
 
 /* wait for any activity on the specified file descriptor using
    the specified deadline */
-static int tio_wait(TFILE *fp,int readfd,const struct timeval *deadline)
+static int tio_wait(int fd, short events, int timeout,
+                    struct timespec *deadline)
 {
-  int timeout;
+  int t;
   struct pollfd fds[1];
   int rv;
   while (1)
   {
+    fds[0].fd = fd;
+    fds[0].events = events;
     /* figure out the time we need to wait */
-    if ((timeout=tio_time_remaining(deadline))<0)
+    if ((t = tio_time_remaining(deadline, timeout)) < 0)
     {
-      errno=ETIME;
+      errno = ETIME;
       return -1;
     }
+    /* sanitiy check for moving clock */
+    if (t > timeout)
+      t = timeout;
     /* wait for activity */
-    if (readfd)
-    {
-      fds[0].fd=fp->fd;
-      fds[0].events=POLLIN;
-      /* santiy check for moving clock */
-      if (timeout>fp->readtimeout)
-        timeout=fp->readtimeout;
-    }
-    else
-    {
-      fds[0].fd=fp->fd;
-      fds[0].events=POLLOUT;
-      /* santiy check for moving clock */
-      if (timeout>fp->writetimeout)
-        timeout=fp->writetimeout;
-    }
-    rv=poll(fds,1,timeout);
-    if (rv>0)
+    rv = poll(fds, 1, t);
+    if (rv > 0)
       return 0; /* we have activity */
-    else if (rv==0)
+    else if (rv == 0)
     {
       /* no file descriptors were available within the specified time */
-      errno=ETIME;
+      errno = ETIME;
       return -1;
     }
-    else if (errno!=EINTR)
+    else if ((errno != EINTR) && (errno != EAGAIN))
       /* some error ocurred */
       return -1;
-    /* we just try again on EINTR */
+    /* we just try again on EINTR or EAGAIN */
   }
 }
 
@@ -201,93 +194,92 @@ static int tio_wait(TFILE *fp,int readfd,const struct timeval *deadline)
    if no data was read in the specified time an error is returned */
 int tio_read(TFILE *fp, void *buf, size_t count)
 {
-  struct timeval deadline;
+  struct timespec deadline = {0, 0};
   int rv;
   uint8_t *tmp;
   size_t newsz;
   size_t len;
   /* have a more convenient storage type for the buffer */
-  uint8_t *ptr=(uint8_t *)buf;
-  /* build a time by which we should be finished */
-  tio_get_deadline(&deadline,fp->readtimeout);
+  uint8_t *ptr = (uint8_t *)buf;
   /* loop until we have returned all the needed data */
   while (1)
   {
     /* check if we have enough data in the buffer */
     if (fp->readbuffer.len >= count)
     {
-      if (count>0)
+      if (count > 0)
       {
-        if (ptr!=NULL)
-          memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,count);
+        if (ptr != NULL)
+          memcpy(ptr, fp->readbuffer.buffer + fp->readbuffer.start, count);
         /* adjust buffer position */
-        fp->readbuffer.start+=count;
-        fp->readbuffer.len-=count;
+        fp->readbuffer.start += count;
+        fp->readbuffer.len -= count;
       }
       return 0;
     }
     /* empty what we have and continue from there */
-    if (fp->readbuffer.len>0)
+    if (fp->readbuffer.len > 0)
     {
-      if (ptr!=NULL)
+      if (ptr != NULL)
       {
-        memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len);
-        ptr+=fp->readbuffer.len;
+        memcpy(ptr, fp->readbuffer.buffer + fp->readbuffer.start,
+               fp->readbuffer.len);
+        ptr += fp->readbuffer.len;
       }
-      count-=fp->readbuffer.len;
-      fp->readbuffer.start+=fp->readbuffer.len;
-      fp->readbuffer.len=0;
+      count -= fp->readbuffer.len;
+      fp->readbuffer.start += fp->readbuffer.len;
+      fp->readbuffer.len = 0;
     }
     /* after this point until the read fp->readbuffer.len is 0 */
     if (!fp->read_resettable)
     {
       /* the stream is not resettable, re-use the buffer */
-      fp->readbuffer.start=0;
+      fp->readbuffer.start = 0;
     }
-    else if (fp->readbuffer.start>=(fp->readbuffer.size-4))
+    else if (fp->readbuffer.start >= (fp->readbuffer.size - 4))
     {
       /* buffer is running empty, try to grow buffer */
-      if (fp->readbuffer.size<fp->readbuffer.maxsize)
+      if (fp->readbuffer.size < fp->readbuffer.maxsize)
       {
-        newsz=fp->readbuffer.size*2;
-        if (newsz>fp->readbuffer.maxsize)
-          newsz=fp->readbuffer.maxsize;
-        tmp=realloc(fp->readbuffer.buffer,newsz);
-        if (tmp!=NULL)
+        newsz = fp->readbuffer.size * 2;
+        if (newsz > fp->readbuffer.maxsize)
+          newsz = fp->readbuffer.maxsize;
+        tmp = realloc(fp->readbuffer.buffer, newsz);
+        if (tmp != NULL)
         {
-          fp->readbuffer.buffer=tmp;
-          fp->readbuffer.size=newsz;
+          fp->readbuffer.buffer = tmp;
+          fp->readbuffer.size = newsz;
         }
       }
       /* if buffer still does not contain enough room, clear resettable */
-      if (fp->readbuffer.start>=(fp->readbuffer.size-4))
+      if (fp->readbuffer.start >= (fp->readbuffer.size - 4))
       {
-        fp->readbuffer.start=0;
-        fp->read_resettable=0;
+        fp->readbuffer.start = 0;
+        fp->read_resettable = 0;
       }
     }
     /* wait until we have input */
-    if (tio_wait(fp,1,&deadline))
+    if (tio_wait(fp->fd, POLLIN, fp->readtimeout, &deadline))
       return -1;
     /* read the input in the buffer */
-    len=fp->readbuffer.size-fp->readbuffer.start;
+    len = fp->readbuffer.size - fp->readbuffer.start;
 #ifdef SSIZE_MAX
-    if (len>SSIZE_MAX)
-      len=SSIZE_MAX;
+    if (len > SSIZE_MAX)
+      len = SSIZE_MAX;
 #endif /* SSIZE_MAX */
-    rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,len);
+    rv = read(fp->fd, fp->readbuffer.buffer + fp->readbuffer.start, len);
     /* check for errors */
-    if (rv==0)
+    if (rv == 0)
     {
-      errno=ECONNRESET;
+      errno = ECONNRESET;
       return -1;
     }
-    else if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))
-      return -1; /* something went wrong with the read */
-    /* skip the read part in the buffer */
-    fp->readbuffer.len=rv;
+    else if ((rv < 0) && (errno != EINTR) && (errno != EAGAIN))
+      return -1;        /* something went wrong with the read */
+    else if (rv > 0)
+      fp->readbuffer.len = rv;  /* skip the read part in the buffer */
 #ifdef DEBUG_TIO_STATS
-    fp->bytesread+=rv;
+    fp->bytesread += rv;
 #endif /* DEBUG_TIO_STATS */
   }
 }
@@ -295,45 +287,37 @@ int tio_read(TFILE *fp, void *buf, size_t count)
 /* Read and discard the specified number of bytes from the stream. */
 int tio_skip(TFILE *fp, size_t count)
 {
-  return tio_read(fp,NULL,count);
+  return tio_read(fp, NULL, count);
 }
 
 /* Read all available data from the stream and empty the read buffer. */
-int tio_skipall(TFILE *fp)
+int tio_skipall(TFILE *fp, int timeout)
 {
-  struct pollfd fds[1];
+  struct timespec deadline = {0, 0};
   int rv;
   size_t len;
   /* clear the read buffer */
-  fp->readbuffer.start=0;
-  fp->readbuffer.len=0;
-  fp->read_resettable=0;
+  fp->readbuffer.start = 0;
+  fp->readbuffer.len = 0;
+  fp->read_resettable = 0;
   /* read until we can't read no more */
-  len=fp->readbuffer.size;
+  len = fp->readbuffer.size;
 #ifdef SSIZE_MAX
-  if (len>SSIZE_MAX)
-    len=SSIZE_MAX;
+  if (len > SSIZE_MAX)
+    len = SSIZE_MAX;
 #endif /* SSIZE_MAX */
   while (1)
   {
-    /* see if any data is available */
-    fds[0].fd=fp->fd;
-    fds[0].events=POLLIN;
-    rv=poll(fds,1,0);
-    /* check the poll() result */
-    if (rv==0)
-      return 0; /* no file descriptor ready */
-    if ((rv<0)&&((errno==EINTR)||(errno==EAGAIN)))
-      continue; /* interrupted, try again */
-    if (rv<0)
-      return -1; /* something went wrong */
+    /* wait until we have input */
+    if (tio_wait(fp->fd, POLLIN, timeout, &deadline))
+      return -1;
     /* read data from the stream */
-    rv=read(fp->fd,fp->readbuffer.buffer,len);
-    if (rv==0)
+    rv = read(fp->fd, fp->readbuffer.buffer, len);
+    if (rv == 0)
       return 0; /* end-of-file */
-    if ((rv<0)&&(errno==EWOULDBLOCK))
+    if ((rv < 0) && (errno == EWOULDBLOCK))
       return 0; /* we've ready everything we can without blocking */
-    if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))
+    if ((rv < 0) && (errno != EINTR) && (errno != EAGAIN))
       return -1; /* something went wrong with the read */
   }
 }
@@ -345,46 +329,50 @@ static int tio_writebuf(TFILE *fp)
   int rv;
   /* write the buffer */
 #ifdef MSG_NOSIGNAL
-  rv=send(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len,MSG_NOSIGNAL);
+  rv = send(fp->fd, fp->writebuffer.buffer + fp->writebuffer.start,
+            fp->writebuffer.len, MSG_NOSIGNAL);
 #else /* not MSG_NOSIGNAL */
   /* on platforms that cannot use send() with masked signals, we change the
      signal mask and change it back after the write (note that there is a
      race condition here) */
-  struct sigaction act,oldact;
+  struct sigaction act, oldact;
   /* set up sigaction */
-  memset(&act,0,sizeof(struct sigaction));
-  act.sa_sigaction=NULL;
-  act.sa_handler=SIG_IGN;
+  memset(&act, 0, sizeof(struct sigaction));
+  act.sa_sigaction = NULL;
+  act.sa_handler = SIG_IGN;
   sigemptyset(&act.sa_mask);
-  act.sa_flags=SA_RESTART;
+  act.sa_flags = SA_RESTART;
   /* ignore SIGPIPE */
-  if (sigaction(SIGPIPE,&act,&oldact)!=0)
+  if (sigaction(SIGPIPE, &act, &oldact) != 0)
     return -1; /* error setting signal handler */
   /* write the buffer */
-  rv=write(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len);
+  rv = write(fp->fd, fp->writebuffer.buffer + fp->writebuffer.start,
+             fp->writebuffer.len);
   /* restore the old handler for SIGPIPE */
-  if (sigaction(SIGPIPE,&oldact,NULL)!=0)
+  if (sigaction(SIGPIPE, &oldact, NULL) != 0)
     return -1; /* error restoring signal handler */
 #endif
   /* check for errors */
-  if ((rv==0)||((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)))
+  if ((rv == 0) || ((rv < 0) && (errno != EINTR) && (errno != EAGAIN)))
     return -1; /* something went wrong with the write */
   /* skip the written part in the buffer */
-  if (rv>0)
+  if (rv > 0)
   {
-    fp->writebuffer.start+=rv;
-    fp->writebuffer.len-=rv;
+    fp->writebuffer.start += rv;
+    fp->writebuffer.len -= rv;
 #ifdef DEBUG_TIO_STATS
-    fp->byteswritten+=rv;
+    fp->byteswritten += rv;
 #endif /* DEBUG_TIO_STATS */
     /* reset start if len is 0 */
-    if (fp->writebuffer.len==0)
-      fp->writebuffer.start=0;
+    if (fp->writebuffer.len == 0)
+      fp->writebuffer.start = 0;
     /* move contents of the buffer to the front if it will save enough room */
-    if (fp->writebuffer.start>=(fp->writebuffer.size/4))
+    if (fp->writebuffer.start >= (fp->writebuffer.size / 4))
     {
-      memmove(fp->writebuffer.buffer,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len);
-      fp->writebuffer.start=0;
+      memmove(fp->writebuffer.buffer,
+              fp->writebuffer.buffer + fp->writebuffer.start,
+              fp->writebuffer.len);
+      fp->writebuffer.start = 0;
     }
   }
   return 0;
@@ -393,14 +381,12 @@ static int tio_writebuf(TFILE *fp)
 /* write all the data in the buffer to the stream */
 int tio_flush(TFILE *fp)
 {
-  struct timeval deadline;
-  /* build a time by which we should be finished */
-  tio_get_deadline(&deadline,fp->writetimeout);
+  struct timespec deadline = {0, 0};
   /* loop until we have written our buffer */
   while (fp->writebuffer.len > 0)
   {
     /* wait until we can write */
-    if (tio_wait(fp,0,&deadline))
+    if (tio_wait(fp->fd, POLLOUT, fp->writetimeout, &deadline))
       return -1;
     /* write one block */
     if (tio_writebuf(fp))
@@ -415,16 +401,16 @@ static int tio_flush_nonblock(TFILE *fp)
 {
   struct pollfd fds[1];
   int rv;
-  /* wait for activity */
-  fds[0].fd=fp->fd;
-  fds[0].events=POLLOUT;
-  rv=poll(fds,1,0);
+  /* see if we can write without blocking */
+  fds[0].fd = fp->fd;
+  fds[0].events = POLLOUT;
+  rv = poll(fds, 1, 0);
   /* check if any file descriptors were ready (timeout) or we were
      interrupted */
-  if ((rv==0)||((rv<0)&&(errno==EINTR)))
+  if ((rv == 0) || ((rv < 0) && ((errno == EINTR) || (errno == EAGAIN))))
     return 0;
   /* any other errors? */
-  if (rv<0)
+  if (rv < 0)
     return -1;
   /* so file descriptor will accept writes */
   return tio_writebuf(fp);
@@ -435,44 +421,46 @@ int tio_write(TFILE *fp, const void *buf, size_t count)
   size_t fr;
   uint8_t *tmp;
   size_t newsz;
-  const uint8_t *ptr=(const uint8_t *)buf;
+  const uint8_t *ptr = (const uint8_t *)buf;
   /* keep filling the buffer until we have bufferred everything */
-  while (count>0)
+  while (count > 0)
   {
     /* figure out free size in buffer */
-    fr=fp->writebuffer.size-(fp->writebuffer.start+fp->writebuffer.len);
+    fr = fp->writebuffer.size - (fp->writebuffer.start + fp->writebuffer.len);
     if (count <= fr)
     {
       /* the data fits in the buffer */
-      memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,count);
-      fp->writebuffer.len+=count;
+      memcpy(fp->writebuffer.buffer + fp->writebuffer.start +
+             fp->writebuffer.len, ptr, count);
+      fp->writebuffer.len += count;
       return 0;
     }
     else if (fr > 0)
     {
       /* fill the buffer with data that will fit */
-      memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,fr);
-      fp->writebuffer.len+=fr;
-      ptr+=fr;
-      count-=fr;
+      memcpy(fp->writebuffer.buffer + fp->writebuffer.start +
+             fp->writebuffer.len, ptr, fr);
+      fp->writebuffer.len += fr;
+      ptr += fr;
+      count -= fr;
     }
     /* try to flush some of the data that is in the buffer */
     if (tio_flush_nonblock(fp))
       return -1;
     /* if we have room now, try again */
-    if (fp->writebuffer.size>(fp->writebuffer.start+fp->writebuffer.len))
+    if (fp->writebuffer.size > (fp->writebuffer.start + fp->writebuffer.len))
       continue;
     /* try to grow the buffer */
-    if (fp->writebuffer.size<fp->writebuffer.maxsize)
+    if (fp->writebuffer.size < fp->writebuffer.maxsize)
     {
-      newsz=fp->writebuffer.size*2;
-      if (newsz>fp->writebuffer.maxsize)
-        newsz=fp->writebuffer.maxsize;
-      tmp=realloc(fp->writebuffer.buffer,newsz);
-      if (tmp!=NULL)
+      newsz = fp->writebuffer.size * 2;
+      if (newsz > fp->writebuffer.maxsize)
+        newsz = fp->writebuffer.maxsize;
+      tmp = realloc(fp->writebuffer.buffer, newsz);
+      if (tmp != NULL)
       {
-        fp->writebuffer.buffer=tmp;
-        fp->writebuffer.size=newsz;
+        fp->writebuffer.buffer = tmp;
+        fp->writebuffer.size = newsz;
         continue; /* try again */
       }
     }
@@ -487,15 +475,18 @@ int tio_close(TFILE *fp)
 {
   int retv;
   /* write any buffered data */
-  retv=tio_flush(fp);
+  retv = tio_flush(fp);
 #ifdef DEBUG_TIO_STATS
   /* dump statistics to stderr */
-  fprintf(stderr,"DEBUG_TIO_STATS READ=%d WRITTEN=%d\n",fp->bytesread,fp->byteswritten);
+  fprintf(stderr, "DEBUG_TIO_STATS READ=%d WRITTEN=%d\n", fp->bytesread,
+          fp->byteswritten);
 #endif /* DEBUG_TIO_STATS */
   /* close file descriptor */
   if (close(fp->fd))
-    retv=-1;
+    retv = -1;
   /* free any allocated buffers */
+  memset(fp->readbuffer.buffer, 0, fp->readbuffer.size);
+  memset(fp->writebuffer.buffer, 0, fp->writebuffer.size);
   free(fp->readbuffer.buffer);
   free(fp->writebuffer.buffer);
   /* free the tio struct itself */
@@ -507,13 +498,14 @@ int tio_close(TFILE *fp)
 void tio_mark(TFILE *fp)
 {
   /* move any data in the buffer to the start of the buffer */
-  if ((fp->readbuffer.start>0)&&(fp->readbuffer.len>0))
+  if ((fp->readbuffer.start > 0) && (fp->readbuffer.len > 0))
   {
-    memmove(fp->readbuffer.buffer,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len);
-    fp->readbuffer.start=0;
+    memmove(fp->readbuffer.buffer,
+            fp->readbuffer.buffer + fp->readbuffer.start, fp->readbuffer.len);
+    fp->readbuffer.start = 0;
   }
   /* mark the stream as resettable */
-  fp->read_resettable=1;
+  fp->read_resettable = 1;
 }
 
 int tio_reset(TFILE *fp)
@@ -522,7 +514,7 @@ int tio_reset(TFILE *fp)
   if (!fp->read_resettable)
     return -1;
   /* reset the buffer */
-  fp->readbuffer.len+=fp->readbuffer.start;
-  fp->readbuffer.start=0;
+  fp->readbuffer.len += fp->readbuffer.start;
+  fp->readbuffer.start = 0;
   return 0;
 }
index eaebf88a2d727d674bb1ab0d445edd244ad6c73b..95f981255cb13352eaffc8dc5ca72522b5dcc643 100644 (file)
@@ -2,7 +2,7 @@
    tio.h - timed io functions
    This file is part of the nss-pam-ldapd library.
 
-   Copyright (C) 2007, 2008, 2010, 2012 Arthur de Jong
+   Copyright (C) 2007, 2008, 2010, 2012, 2013 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -47,22 +47,22 @@ typedef struct tio_fileinfo TFILE;
 
 /* Open a new TFILE based on the file descriptor. The timeout is set for any
    operation (value in milliseconds). */
-TFILE *tio_fdopen(int fd,int readtimeout,int writetimeout,
-                  size_t initreadsize,size_t maxreadsize,
-                  size_t initwritesize,size_t maxwritesize)
+TFILE *tio_fdopen(int fd, int readtimeout, int writetimeout,
+                  size_t initreadsize, size_t maxreadsize,
+                  size_t initwritesize, size_t maxwritesize)
   LIKE_MALLOC MUST_USE;
 
 /* Read the specified number of bytes from the stream. */
-int tio_read(TFILE *fp,void *buf,size_t count);
+int tio_read(TFILE *fp, void *buf, size_t count);
 
 /* Read and discard the specified number of bytes from the stream. */
-int tio_skip(TFILE *fp,size_t count);
+int tio_skip(TFILE *fp, size_t count);
 
 /* Read all available data from the stream and empty the read buffer. */
-int tio_skipall(TFILE *fp);
+int tio_skipall(TFILE *fp, int timeout);
 
 /* Write the specified buffer to the stream. */
-int tio_write(TFILE *fp,const void *buf,size_t count);
+int tio_write(TFILE *fp, const void *buf, size_t count);
 
 /* Write out all buffered data to the stream. */
 int tio_flush(TFILE *fp);