/* * gfs_readdir_emit_int: internal routine to emit directory entry * * st - the current readdir state, which must have d_ino/ed_ino * and d_name/ed_name set * uiop - caller-supplied uio pointer * next - the offset of the next entry */ static int gfs_readdir_emit_int(gfs_readdir_state_t *st, uio_t *uiop, offset_t next, int *ncookies, u_long **cookies) { int reclen, namlen; dirent64_t *dp; boolean_t extended = (st->grd_flags & VNODE_READDIR_EXTENDED); dp = st->grd_dirent; namlen = strlen(dp->d_name); reclen = DIRENT_RECLEN(namlen, extended); dprintf("trying to add '%s': extended %d isascii %d: next %lld\n", dp->d_name, st->grd_flags & VNODE_READDIR_EXTENDED, is_ascii_str(dp->d_name), next); if (reclen > uio_resid(uiop)) { /* * Error if no entries were returned yet */ if (uio_resid(uiop) == st->grd_oresid) return (EINVAL); return (-1); } if (extended) { // d_fileno // /* NOTE: d_seekoff is the offset for the *next* entry */ //next = &(dp->d_seekoff); dp->d_seekoff = next; dp->d_type = DT_DIR; dp->d_namlen = namlen; dp->d_reclen = (ushort_t)reclen; } else { /* XXX: This can change in the future. */ dp->d_type = DT_DIR; dp->d_namlen = namlen; dp->d_reclen = (ushort_t)reclen; } if (uiomove((caddr_t)st->grd_dirent, reclen, UIO_READ, uiop)) return (EFAULT); uio_setoffset(uiop, next); if (*cookies != NULL) { **cookies = next; (*cookies)++; (*ncookies)--; KASSERT(*ncookies >= 0, ("ncookies=%d", *ncookies)); } dprintf("Copied out %d bytes\n", reclen); return (0); }
static int display_unicode_string(tvbuff_t *tvb, proto_tree *tree, int offset, char **data) { char *str, *p; int len; int charoffset; guint16 character; /* display a unicode string from the tree and return new offset */ /* * Get the length of the string. */ len = 0; while (tvb_get_ntohs(tvb, offset + len) != '\0') len += 2; len += 2; /* count the '\0' too */ /* * Allocate a buffer for the string; "len" is the length in * bytes, not the length in characters. */ str = ep_alloc(len/2); /* - this assumes the string is just ISO 8859-1 */ charoffset = offset; p = str; while ((character = tvb_get_ntohs(tvb, charoffset)) != '\0') { *p++ = (char) character; charoffset += 2; } *p = '\0'; if (!is_ascii_str((const guint8 *) str, len / 2)) { *str = '\0'; } proto_tree_add_string(tree, hf_hdr_val_unicode, tvb, offset, len, str); if (data) *data = str; return offset+len; }
static gint pop3_getauth_apop_send(Pop3Session *session) { gchar *start, *end; gchar *apop_str; gchar md5sum[33]; cm_return_val_if_fail(session->user != NULL, -1); cm_return_val_if_fail(session->pass != NULL, -1); session->state = POP3_GETAUTH_APOP; if ((start = strchr(session->greeting, '<')) == NULL) { log_error(LOG_PROTOCOL, _("Required APOP timestamp not found " "in greeting\n")); session->error_val = PS_PROTOCOL; return -1; } if ((end = strchr(start, '>')) == NULL || end == start + 1) { log_error(LOG_PROTOCOL, _("Timestamp syntax error in greeting\n")); session->error_val = PS_PROTOCOL; return -1; } *(end + 1) = '\0'; if (!is_ascii_str(start)) { log_error(LOG_PROTOCOL, _("Timestamp syntax error in greeting (not ASCII)\n")); session->error_val = PS_PROTOCOL; return -1; } apop_str = g_strconcat(start, session->pass, NULL); md5_hex_digest(md5sum, apop_str); g_free(apop_str); pop3_gen_send(session, "APOP %s %s", session->user, md5sum); return PS_SUCCESS; }
void nameattrpack(attrinfo_t *aip, const char *name, int namelen) { void *varbufptr; struct attrreference * attr_refptr; u_int32_t attrlen; size_t nfdlen, freespace; varbufptr = *aip->ai_varbufpp; attr_refptr = (struct attrreference *)(*aip->ai_attrbufpp); freespace = (char*)aip->ai_varbufend - (char*)varbufptr; /* * Mac OS X: non-ascii names are UTF-8 NFC on disk * so convert to NFD before exporting them. */ namelen = strlen(name); if (is_ascii_str(name) || utf8_normalizestr((const u_int8_t *)name, namelen, (u_int8_t *)varbufptr, &nfdlen, freespace, UTF_DECOMPOSED) != 0) { /* ASCII or normalization failed, just copy zap name. */ strncpy((char *)varbufptr, name, MIN(freespace, namelen+1)); } else { /* Normalization succeeded (already in buffer). */ namelen = nfdlen; } attrlen = namelen + 1; attr_refptr->attr_dataoffset = (char *)varbufptr - (char *)attr_refptr; attr_refptr->attr_length = attrlen; /* * Advance beyond the space just allocated and * round up to the next 4-byte boundary: */ varbufptr = ((char *)varbufptr) + attrlen + ((4 - (attrlen & 3)) & 3); ++attr_refptr; *aip->ai_attrbufpp = attr_refptr; *aip->ai_varbufpp = varbufptr; }
static int dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo) { proto_tree *hdrs_tree = NULL; proto_tree *hdr_tree = NULL; proto_item *hdr = NULL; proto_item *handle_item; gint item_length = -1; guint8 hdr_id, i; if (tvb_length_remaining(tvb, offset) > 0) { proto_item *hdrs; hdrs = proto_tree_add_text(tree, tvb, offset, item_length, "Headers"); hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs); } else { return offset; } while (tvb_length_remaining(tvb, offset) > 0) { hdr_id = tvb_get_guint8(tvb, offset); switch(0xC0 & hdr_id) { case 0x00: /* null terminated unicode */ item_length = tvb_get_ntohs(tvb, offset+1); break; case 0x40: /* byte sequence */ item_length = tvb_get_ntohs(tvb, offset+1); break; case 0x80: /* 1 byte */ item_length = 2; break; case 0xc0: /* 4 bytes */ item_length = 5; break; } hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s", val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown")); hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr); proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; switch(0xC0 & hdr_id) { case 0x00: /* null terminated unicode */ { proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if ((item_length - 3) > 0) { char *str; display_unicode_string(tvb, hdr_tree, offset, &str); proto_item_append_text(hdr_tree, " (\"%s\")", str); col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str); } else { col_append_str(pinfo->cinfo, COL_INFO, " \"\""); } offset += item_length - 3; } break; case 0x40: /* byte sequence */ proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA); if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */ for(i=0; target_vals[i].strptr != NULL; i++) { if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) { proto_item_append_text(handle_item, ": %s", target_vals[i].strptr); proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr); col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr); } } } if (!tvb_strneql(tvb, offset, "<?xml", 5)) { tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(xml_handle, next_tvb, pinfo, tree); } else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3)) { proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3)); col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3)); } offset += item_length - 3; break; case 0x80: /* 1 byte */ proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset)); proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 0xc0: /* 4 bytes */ proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset)); proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; break; default: break; } } return offset; }
zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, int flag) #endif { zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_dirlock_t *dl; uint64_t zoid; int error; vnode_t *vp; #ifdef __APPLE__ char *name; u_int8_t *nfc_name = NULL; /* NFC form of name */ int nfc_namesize = 0; #endif *zpp = NULL; *dlpp = NULL; #ifdef __APPLE__ /* Note: cnp will be NULL for ZXATTR case */ name = cnp ? cnp->cn_nameptr : ""; if (cnp) ASSERT(name[cnp->cn_namelen] == '\0'); #endif /* * Verify that we are not trying to lock '.', '..', or '.zfs' */ if ((name[0] == '.') && ((name[1] == '\0') || ((name[1] == '.') && (name[2] == '\0'))) || zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) return (EEXIST); #ifdef __APPLE__ /* * Mac OS X: store non-ascii names in UTF-8 NFC (pre-composed) on disk. * * The NFC name ptr is stored in dl->dl_name (allocated here) * and its freed by zfs_dirent_unlock (since dl_namesize != 0). * * Since NFC size will not expand, we can allocate the same sized buffer. */ if (!is_ascii_str(name)) { size_t outlen; nfc_namesize = strlen(name) + 1; nfc_name = kmem_alloc(nfc_namesize, KM_SLEEP); if (utf8_normalizestr((const u_int8_t *)name, nfc_namesize, nfc_name, &outlen, nfc_namesize, UTF_PRECOMPOSED) == 0) { /* Normalization succeeded, switch to NFC name. */ name = (char *)nfc_name; } else { /* Normalization failed, just use input name as-is. */ kmem_free(nfc_name, nfc_namesize); nfc_name = NULL; } } #endif /* * Wait until there are no locks on this name. */ rw_enter(&dzp->z_name_lock, RW_READER); mutex_enter(&dzp->z_lock); for (;;) { if (dzp->z_unlinked) { mutex_exit(&dzp->z_lock); rw_exit(&dzp->z_name_lock); #ifdef __APPLE__ /* Release any unused NFC name before returning */ if (nfc_name) { kmem_free(nfc_name, nfc_namesize); } #endif return (ENOENT); } for (dl = dzp->z_dirlocks; dl != NULL; dl = dl->dl_next) if (strcmp(name, dl->dl_name) == 0) break; if (dl == NULL) { /* * Allocate a new dirlock and add it to the list. */ dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP); cv_init(&dl->dl_cv, NULL, CV_DEFAULT, NULL); dl->dl_name = name; dl->dl_sharecnt = 0; dl->dl_namesize = 0; dl->dl_dzp = dzp; dl->dl_next = dzp->z_dirlocks; dzp->z_dirlocks = dl; #ifdef __APPLE__ /* * Keep the NFC name around in dir lock by tagging it * (setting nfc_namesize). */ if (nfc_name) { dl->dl_namesize = nfc_namesize; nfc_name = NULL; /* its now part of the dir lock */ } #endif break; } if ((flag & ZSHARED) && dl->dl_sharecnt != 0) break; cv_wait(&dl->dl_cv, &dzp->z_lock); dl=NULL; } #ifdef __APPLE__ /* * Release any unused NFC name (ie if we found a pre-existing lock entry) */ if (nfc_name) { kmem_free(nfc_name, nfc_namesize); nfc_name = NULL; } #endif if ((flag & ZSHARED) && ++dl->dl_sharecnt > 1 && dl->dl_namesize == 0) { /* * We're the second shared reference to dl. Make a copy of * dl_name in case the first thread goes away before we do. * Note that we initialize the new name before storing its * pointer into dl_name, because the first thread may load * dl->dl_name at any time. He'll either see the old value, * which is his, or the new shared copy; either is OK. */ dl->dl_namesize = strlen(dl->dl_name) + 1; name = kmem_alloc(dl->dl_namesize, KM_SLEEP); bcopy(dl->dl_name, name, dl->dl_namesize); dl->dl_name = name; } mutex_exit(&dzp->z_lock); /* * We have a dirlock on the name. (Note that it is the dirlock, * not the dzp's z_lock, that protects the name in the zap object.) * See if there's an object by this name; if so, put a hold on it. */ if (flag & ZXATTR) { error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &zoid, sizeof (zoid)); if (error == 0) error = (zoid == 0 ? ENOENT : 0); } else { #ifdef __APPLE__ /* * Lookup an entry in the vnode name cache * * If the lookup succeeds, the vnode is returned in *vpp, * and a status of -1 is returned. * * If the lookup determines that the name does not exist * (negative caching), a status of ENOENT is returned. * * If the lookup fails, a status of zero is returned. */ switch ( cache_lookup(ZTOV(dzp), &vp, cnp) ) { case -1: break; case ENOENT: vp = DNLC_NO_VNODE; break; default: vp = NULLVP; } #else vp = dnlc_lookup(ZTOV(dzp), name); #endif /* __APPLE__ */ if (vp == DNLC_NO_VNODE) { VN_RELE(vp); error = ENOENT; } else if (vp) { if (flag & ZNEW) { zfs_dirent_unlock(dl); VN_RELE(vp); return (EEXIST); } *dlpp = dl; *zpp = VTOZ(vp); return (0); } else { error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, 8, 1, &zoid); zoid = ZFS_DIRENT_OBJ(zoid); if (error == ENOENT) #ifdef __APPLE__ /* * Add a negative entry into the VFS name cache */ if ((flag & ZNEW) == 0 && (dzp->z_pflags & ZFS_XATTR) == 0 && (cnp) && (cnp->cn_flags & MAKEENTRY) && (cnp->cn_nameiop != CREATE) && (cnp->cn_nameiop != RENAME)) { cache_enter(ZTOV(dzp), NULLVP, cnp); } #else dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE); #endif /* __APPLE__ */ } } if (error) { if (error != ENOENT || (flag & ZEXISTS)) { zfs_dirent_unlock(dl); return (error); } } else { if (flag & ZNEW) { zfs_dirent_unlock(dl); return (EEXIST); } //error = zfs_zget_sans_vnode(zfsvfs, zoid, zpp); error = zfs_zget(zfsvfs, zoid, zpp); if (error) { zfs_dirent_unlock(dl); return (error); } else { // Should this be here? //printf("zfs_dir attach 1\n"); //zfs_attach_vnode(*zpp); } if (!(flag & ZXATTR)) #ifdef __APPLE__ if (cnp && cnp->cn_flags & MAKEENTRY) cache_enter(ZTOV(dzp), ZTOV(*zpp), cnp); #else dnlc_update(ZTOV(dzp), name, ZTOV(*zpp)); #endif /* __APPLE__ */ } *dlpp = dl; return (0); }