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
#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 */
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
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.
*/
/* 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); \
}
-/* These are functions and macors for performing common operations in
+/* These are functions and macros for performing common operations in
the nslcd request/response protocol. */
/* returns a socket to the server or NULL on error (see errno),
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 */