-
-static int getextattr_size(char *rbuf, int *rbuflen, char *uname, int oflag, char *attruname)
-{
- int ret, attrdirfd;
- uint32_t attrsize;
- struct stat st;
-
- LOG(log_debug7, logtype_afpd, "getextattr_size(%s): attribute: \"%s\"", uname, attruname);
-
- if ( -1 == (attrdirfd = attropen(uname, ".", O_RDONLY | oflag))) {
- if (errno == ELOOP) {
- /* its a symlink and client requested O_NOFOLLOW */
- LOG(log_debug, logtype_afpd, "getextattr_size(%s): encountered symlink with kXAttrNoFollow", uname);
-
- *(uint32_t *)rbuf = 0;
- *rbuflen += 4;
-
- return AFP_OK;
- }
- LOG(log_error, logtype_afpd, "getextattr_size: attropen error: %s", strerror(errno));
- return AFPERR_MISC;
- }
-
- if ( -1 == (fstatat(attrdirfd, attruname, &st, 0))) {
- LOG(log_error, logtype_afpd, "getextattr_size: fstatat error: %s", strerror(errno));
- ret = AFPERR_MISC;
- goto exit;
- }
- attrsize = (st.st_size > MAX_EA_SIZE) ? MAX_EA_SIZE : st.st_size;
-
- /* Start building reply packet */
-
- LOG(log_debug7, logtype_afpd, "getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, attrsize);
-
- /* length of attribute data */
- *(uint32_t *)rbuf = htonl((uint32_t)attrsize);
- *rbuflen += 4;
-
- ret = AFP_OK;
-
-exit:
- close(attrdirfd);
- return ret;
-}
-
-static int getextattr_content(char *rbuf, int *rbuflen, char *uname, int oflag, char *attruname, int maxreply)
-{
- int ret, attrdirfd;
- size_t toread, okread = 0, len;
- uint32_t *datalength;
- struct stat st;
-
- if ( -1 == (attrdirfd = attropen(uname, attruname, O_RDONLY | oflag))) {
- if (errno == ELOOP) {
- /* its a symlink and client requested O_NOFOLLOW */
- LOG(log_debug, logtype_afpd, "getextattr_content(%s): encountered symlink with kXAttrNoFollow", uname);
-
- *(uint32_t *)rbuf = 0;
- *rbuflen += 4;
-
- return AFP_OK;
- }
- LOG(log_error, logtype_afpd, "getextattr_content(%s): attropen error: %s", attruname, strerror(errno));
- return AFPERR_MISC;
- }
-
- if ( -1 == (fstat(attrdirfd, &st))) {
- LOG(log_error, logtype_afpd, "getextattr_content(%s): fstatat error: %s", attruname,strerror(errno));
- ret = AFPERR_MISC;
- goto exit;
- }
-
- /* Start building reply packet */
-
- maxreply -= MAX_REPLY_EXTRA_BYTES;
- if (maxreply > MAX_EA_SIZE)
- maxreply = MAX_EA_SIZE;
-
- /* But never send more than the client requested */
- toread = (maxreply < st.st_size) ? maxreply : st.st_size;
-
- LOG(log_debug7, logtype_afpd, "getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply);
-
- /* remember where we must store length of attribute data in rbuf */
- datalength = (uint32_t *)rbuf;
- rbuf += 4;
- *rbuflen += 4;
-
- while (1) {
- len = read(attrdirfd, rbuf, toread);
- if (len == -1) {
- LOG(log_error, logtype_afpd, "getextattr_content(%s): read error: %s", attruname, strerror(errno));
- ret = AFPERR_MISC;
- goto exit;
- }
- okread += len;
- rbuf += len;
- *rbuflen += len;
- if ((len == 0) || (okread == toread))
- break;
- }
-
- *datalength = htonl((uint32_t)okread);
-
- ret = AFP_OK;
-
-exit:
- close(attrdirfd);
- return ret;
-}
-