1 #include <sys/socket.h>
15 "/var/run/nscd/socket"
18 FILE *__nscd_query(int32_t req
, const char *key
, int32_t *buf
, size_t len
, int *swap
)
23 int32_t req_buf
[REQ_LEN
] = {
26 strnlen(key
,LOGIN_NAME_MAX
)+1
29 .msg_iov
= (struct iovec
[]){
30 {&req_buf
, sizeof(req_buf
)},
31 {(char*)key
, strlen(key
)+1}
35 int errno_save
= errno
;
42 fd
= socket(PF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
, 0);
43 if (fd
< 0) return NULL
;
45 if(!(f
= fdopen(fd
, "r"))) {
50 if (req_buf
[2] > LOGIN_NAME_MAX
)
53 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
54 /* If there isn't a running nscd we simulate a "not found"
55 * result and the caller is responsible for calling
56 * fclose on the (unconnected) socket. The value of
57 * errno must be left unchanged in this case. */
58 if (errno
== EACCES
|| errno
== ECONNREFUSED
|| errno
== ENOENT
) {
65 if (sendmsg(fd
, &msg
, MSG_NOSIGNAL
) < 0)
68 if (!fread(buf
, len
, 1, f
)) {
69 /* If the VERSION entry mismatches nscd will disconnect. The
70 * most likely cause is that the endianness mismatched. So, we
71 * byteswap and try once more. (if we already swapped, just
74 if (ferror(f
)) goto error
;
77 for (i
= 0; i
< sizeof(req_buf
)/sizeof(req_buf
[0]); i
++) {
78 req_buf
[i
] = bswap_32(req_buf
[i
]);
89 for (i
= 0; i
< len
/sizeof(buf
[0]); i
++) {
90 buf
[i
] = bswap_32(buf
[i
]);
94 /* The first entry in every nscd response is the version number. This
95 * really shouldn't happen, and is evidence of some form of malformed
98 if(buf
[0] != NSCDVERSION
) {