Beispiel #1
0
void HRA_dissoc_a(SV *self, SV *attr, char *t, SV *value)
{
    SV *aobj = attr_get(self, attr, t, 0);
    if(!aobj) {
        return;
    }
    HR_DEBUG("Dissoc called");
    attr_delete_value_from_attrhash(aobj, value);
    attr_delete_from_vhash(aobj, value);
}
Beispiel #2
0
static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
			     enum wlantest_ctrl_attr attr)
{
	u8 *addr;
	size_t addr_len;
	addr = attr_get(buf, buflen, attr, &addr_len);
	if (addr && addr_len != ETH_ALEN)
		addr = NULL;
	return addr;
}
Beispiel #3
0
void HRA_unlink_a(SV *self, SV* attr, char *t)
{
    HR_DEBUG("UNLINK_ATTR");
    SV *aobj = attr_get(self, attr, t, 0);
    if(!aobj) {
        return;
    }
    attr_destroy_trigger(SvRV(aobj), NULL, NULL);
    HR_DEBUG("UNLINK_ATTR DONE");
}
static int cmd_info_bss(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[100], *end, *pos;
    int rlen, i;
    size_t len;
    char info[100];

    if (argc != 2) {
        printf("bss_info needs at two arguments: "
               "field name and BSSID\n");
        return -1;
    }

    pos = buf;
    end = buf + sizeof(buf);
    WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS);
    pos += 4;

    for (i = 0; bss_infos[i].name; i++) {
        if (os_strcasecmp(bss_infos[i].name, argv[0]) == 0)
            break;
    }
    if (bss_infos[i].name == NULL) {
        printf("Unknown BSS info '%s'\n", argv[0]);
        printf("Info fields:");
        for (i = 0; bss_infos[i].name; i++)
            printf(" %s", bss_infos[i].name);
        printf("\n");
        return -1;
    }

    pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO,
                        bss_infos[i].num);
    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
    if (hwaddr_aton(argv[1], pos) < 0) {
        printf("Invalid BSSID '%s'\n", argv[1]);
        return -1;
    }
    pos += ETH_ALEN;

    rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
    if (pos == NULL)
        return -1;
    if (len >= sizeof(info))
        len = sizeof(info) - 1;
    os_memcpy(info, pos, len);
    info[len] = '\0';
    printf("%s\n", info);
    return 0;
}
Beispiel #5
0
static int stat_cache_attr_get(buffer *buf, char *name) {
	int attrlen;
	int ret;

	buffer_string_prepare_copy(buf, 1023);
	attrlen = buf->size - 1;
	if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
		buffer_commit(buf, attrlen);
	}
	return ret;
}
Beispiel #6
0
static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	enum wlantest_sta_info info;
	u8 buf[4 + 108], *end, *pos;
	char resp[100];

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	info = WPA_GET_BE32(addr);

	resp[0] = '\0';
	switch (info) {
	case WLANTEST_STA_INFO_PROTO:
		info_print_proto(resp, sizeof(resp), sta->proto);
		break;
	case WLANTEST_STA_INFO_PAIRWISE:
		info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
		break;
	case WLANTEST_STA_INFO_KEY_MGMT:
		info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
		break;
	case WLANTEST_STA_INFO_RSN_CAPAB:
		info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
		break;
	case WLANTEST_STA_INFO_STATE:
		info_print_state(resp, sizeof(resp), sta->state);
		break;
	case WLANTEST_STA_INFO_GTK:
		info_print_gtk(resp, sizeof(resp), sta);
		break;
	default:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
	ctrl_send(wt, sock, buf, pos - buf);
}
Beispiel #7
0
static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
				  size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct wlantest_sta *sta2;
	struct wlantest_tdls *tdls;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;
	int found = 0;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
	if (sta == NULL || sta2 == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	addr = attr_get(cmd, clen, WLANTEST_ATTR_TDLS_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_TDLS_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
		if (tdls->init == sta && tdls->resp == sta2) {
			found = 1;
			break;
		}
	}

	if (!found) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    tdls->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}
Beispiel #8
0
ssize_t sys_lgetxattr (const char *path, const char *uname, void *value, size_t size)
{
	const char *name = prefix(uname);

#if defined(HAVE_LGETXATTR)
	return lgetxattr(path, name, value, size);
#elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
	int options = XATTR_NOFOLLOW;
	return getxattr(path, name, value, size, 0, options);
#elif defined(HAVE_LGETEA)
	return lgetea(path, name, value, size);
#elif defined(HAVE_EXTATTR_GET_LINK)
	ssize_t retval;

	retval = extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0);
    if (retval == -1) {
        LOG(log_maxdebug, logtype_default, "extattr_get_link(): %s",
            strerror(errno));
        return -1;
    }
    if (size == 0)
        /* Only interested in size of xattr */
        return retval;
    if (retval > size) {
        errno = ERANGE;
        return -1;
    }
    return extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, value, size);

#elif defined(HAVE_ATTR_GET)
	int retval, flags = ATTR_DONTFOLLOW;
	int valuelength = (int)size;
	char *attrname = strchr(name,'.') + 1;
	
	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;

	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);

	return retval ? retval : valuelength;
#elif defined(HAVE_ATTROPEN)
	ssize_t ret = -1;
	int attrfd = solaris_attropen(path, name, O_RDONLY | O_NOFOLLOW, 0);
	if (attrfd >= 0) {
		ret = solaris_read_xattr(attrfd, value, size);
		close(attrfd);
	}
	return ret;
#else
	errno = ENOSYS;
	return -1;
#endif
}
Beispiel #9
0
static int stat_cache_attr_get(buffer *buf, char *name) {
	int attrlen;
	int ret;

	attrlen = 1024;
	buffer_prepare_copy(buf, attrlen);
	attrlen--;
	if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
		buf->used = attrlen + 1;
		buf->ptr[attrlen] = '\0';
	}
	return ret;
}
static int cmd_get_bss_counter(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[100], *end, *pos;
    int rlen, i;
    size_t len;

    if (argc != 2) {
        printf("get_bss_counter needs at two arguments: "
               "counter name and BSSID\n");
        return -1;
    }

    pos = buf;
    end = buf + sizeof(buf);
    WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_BSS_COUNTER);
    pos += 4;

    for (i = 0; bss_counters[i].name; i++) {
        if (os_strcasecmp(bss_counters[i].name, argv[0]) == 0)
            break;
    }
    if (bss_counters[i].name == NULL) {
        printf("Unknown BSS counter '%s'\n", argv[0]);
        printf("Counters:");
        for (i = 0; bss_counters[i].name; i++)
            printf(" %s", bss_counters[i].name);
        printf("\n");
        return -1;
    }

    pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_COUNTER,
                        bss_counters[i].num);
    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
    if (hwaddr_aton(argv[1], pos) < 0) {
        printf("Invalid BSSID '%s'\n", argv[1]);
        return -1;
    }
    pos += ETH_ALEN;

    rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
    if (pos == NULL || len != 4)
        return -1;
    printf("%u\n", WPA_GET_BE32(pos));
    return 0;
}
Beispiel #11
0
/**
 * @brief
 *	get memory information.
 *
 * @param[in] pathname - pathname
 * @param[out] memp - memory info
 *
 */
void
get_mem(char *pathname, int *memp)
{
	int len;
	char info[512];
	invent_meminfo_t *meminfo;

	len = sizeofinfo;
	if (attr_get(pathname, INFO_LBL_DETAIL_INVENT, info, &len, 0) == 0) {
		meminfo = (invent_meminfo_t *)info;
		*memp = (int)meminfo->im_size;

	}
	return;
}
Beispiel #12
0
// Utility function for fatal errors
void Screen::_two_second_error(const char* errstr)
{
  attr_t attrs; //used in attr_(get|set)
  short pair; //used in attr_(get|set)
  attr_get(&attrs,&pair,NULL);//save terminal state
  attron(COLOR_PAIR(c_error)|A_BLINK);
  //Locate message in center of screen if room, else (0,0)
  int maxlen,maxwid;
  mvprintw(screenHeight>1 ? screenHeight/2 : 0, //y-coordinate for message
      screenWidth>std::strlen(errstr) ? screenWidth/2-strlen(errstr)/2 : 0, //x-coordinate for message
      errstr);
  ::refresh();
  attr_set(attrs,pair,NULL);//restore terminal state
  sleep(2);
}
Beispiel #13
0
int exec_initialize (flux_t *h, uint32_t rank, attr_t *attrs)
{
    flux_subprocess_server_t *s = NULL;
    const char *local_uri;

    if (attr_get (attrs, "local-uri", &local_uri, NULL) < 0)
        goto cleanup;
    if (!(s = flux_subprocess_server_start (h, "cmb", local_uri, rank)))
        goto cleanup;
    flux_aux_set (h, "flux::exec", s, exec_finalize);
    return 0;
cleanup:
    flux_subprocess_server_stop (s);
    return -1;
}
/*
This function prints the cash the player has with optional prefix as 
well as screen coordinates.

Please note that offsetx is the offset from the right of the screen, y is 
the offset from the top as always.
*/
void printfunds(int y, int offsetx, const char* prefix)
{
   char moneystr[50];
   char prefixbuffer[50];

   if(prefix==NULL)
   {
      strncpy(prefixbuffer,"",50);
   }
   else
   {
      strncpy(prefixbuffer,prefix,50);
   }

   sprintf(moneystr,"$%d",ledger.get_funds());

   //Save screen coordinates for later.
   int begy,begx;
   getyx(stdscr,begy,begx);

   //Save color and brightness information for later.
   short colorpair;
   short front, back;
   char dim;

   attr_t attrs;
   attr_get(&attrs,&colorpair,NULL);
   if((attrs & WA_DIM)==0)
      dim=0;
   else
      dim=1;
   pair_content(colorpair,&front,&back);


   //Move, set color, and write.
   move(y,80-strlen(moneystr)-strlen(prefixbuffer)-offsetx);
   addstr(prefixbuffer);
   set_color(COLOR_GREEN,COLOR_BLACK,1);
   addstr(moneystr);

   //Recover old settings
   move(begy,begx);
   set_color(front,back,dim);
}
static int cmd_get_rx_tid(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[100], *end, *pos;
    int rlen;
    size_t len;

    if (argc != 3) {
        printf("get_tx_tid needs three arguments: "
               "BSSID, STA address, and TID\n");
        return -1;
    }

    pos = buf;
    end = buf + sizeof(buf);
    WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_RX_TID);
    pos += 4;

    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
    if (hwaddr_aton(argv[0], pos) < 0) {
        printf("Invalid BSSID '%s'\n", argv[0]);
        return -1;
    }
    pos += ETH_ALEN;

    pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
    if (hwaddr_aton(argv[1], pos) < 0) {
        printf("Invalid STA address '%s'\n", argv[1]);
        return -1;
    }
    pos += ETH_ALEN;

    pos = attr_add_be32(pos, end, WLANTEST_ATTR_TID, atoi(argv[2]));

    rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
    if (pos == NULL || len != 4)
        return -1;
    printf("%u\n", WPA_GET_BE32(pos));
    return 0;
}
Beispiel #16
0
ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
{
#if defined(HAVE_LGETXATTR)
	return lgetxattr(path, name, value, size);
#elif defined(HAVE_ATTR_GET)
	int retval, flags = ATTR_DONTFOLLOW;
	int valuelength = (int)size;
	char *attrname = strchr(name,'.') +1;
	
	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;

	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);

	return retval ? retval : valuelength;
#else
	errno = ENOSYS;
	return -1;
#endif
}
Beispiel #17
0
int runlevel_register_attrs (runlevel_t *r, attr_t *attrs)
{
    const char *val;

    if (attr_add_active (attrs, "init.run-level",
                         FLUX_ATTRFLAG_READONLY,
                         runlevel_attr_get, NULL, r) < 0)
        return -1;

    if (attr_get (attrs, "init.mode", &val, NULL) == 0) {

        if (runlevel_set_mode (r, val) < 0
                || attr_delete (attrs, "init.mode", true) < 0)
            return -1;
    }
    if (attr_add_active (attrs, "init.mode", 0,
                         runlevel_attr_get, runlevel_attr_set, r) < 0)
        return -1;

    return 0;
}
Beispiel #18
0
static struct wlantest_bss * ctrl_get_bss(struct wlantest *wt, int sock,
					  u8 *cmd, size_t clen)
{
	struct wlantest_bss *bss;
	u8 *pos;
	size_t len;

	pos = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &len);
	if (pos == NULL || len != ETH_ALEN) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return NULL;
	}

	bss = bss_find(wt, pos);
	if (bss == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return NULL;
	}

	return bss;
}
static int cmd_list_sta(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[100], *pos;
    u8 *addr;
    size_t len;
    int rlen, i;

    if (argc < 1) {
        printf("list_sta needs one argument: BSSID\n");
        return -1;
    }

    pos = buf;
    WPA_PUT_BE32(pos, WLANTEST_CTRL_LIST_STA);
    pos += 4;
    WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
    pos += 4;
    WPA_PUT_BE32(pos, ETH_ALEN);
    pos += 4;
    if (hwaddr_aton(argv[0], pos) < 0) {
        printf("Invalid BSSID '%s'\n", argv[0]);
        return -1;
    }
    pos += ETH_ALEN;

    rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    addr = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_STA_ADDR, &len);
    if (addr == NULL)
        return -1;

    for (i = 0; i < len / ETH_ALEN; i++)
        printf(MACSTR " ", MAC2STR(addr + ETH_ALEN * i));
    printf("\n");

    return 0;
}
Beispiel #20
0
/* Return the current color/attribute as a single value such that the
   first digit is a hex value for fg color, and the second is an octal
   digit for bg color. This won't ever be larger than 255. */
unsigned char cur_color( void )
{
    attr_t atr_code;        /*< Our attribute code. */
    short col_code;         /*< Our color code. */
    unsigned char report;   /*< The report code. */
    
    if ( !colors )
        return 1;
    
    /* Get the parameters. */
    attr_get( &atr_code, &col_code, NULL );
    col_code --;
    
    /* Do the maths. */
    report = col_code / 8;
    if ( atr_code & A_BOLD )
        report += 8;
    report *= 16;
    report += col_code % 8;
    
    return report;
}
Beispiel #21
0
void puttext(int left, int top, int right, int bottom, unsigned char *str)
{
    int orig_y, orig_x;
    attr_t attrs;
    short pair;
    getyx(stdscr, orig_y, orig_x);
    attr_get(&attrs, &pair, NULL);
    for (int y = top - 1; y <= bottom - 1; y++)
    {
        for (int x = left - 1; x <= right - 1; x++)
        {
            unsigned char chr = *str++;
            unsigned char col = *str++;
            wchar_t w = cp437[chr];
            if (w == 0) w = (wchar_t)' ';
            textcolor(col);
            mvaddnwstr(y, x, &w, 1);
        }
    }
    attr_set(attrs, pair, NULL);
    move(orig_y, orig_x);
}
Beispiel #22
0
int Window::fill(int attrs, int x, int y, int w, int h)
{
  attr_t battrs;
  short pair;

  if (attr_get(&battrs, &pair, NULL) == ERR)
    return ERR;

  if (attron(attrs) == ERR)
    return ERR;

  int realw = getmaxx();
  int realh = getmaxy();

  for (int i = x; i < realw && i < x + w; i++)
    for (int j = y; j < realh && j < y + h; j++)
      mvwaddch(p->win, j, i, ' ');

  if (attr_set(battrs, pair, NULL) == ERR)
    return ERR;

  return OK;
}
static int cmd_list_bss(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[4];
    u8 *bssid;
    size_t len;
    int rlen, i;

    WPA_PUT_BE32(buf, WLANTEST_CTRL_LIST_BSS);
    rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    bssid = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_BSSID, &len);
    if (bssid == NULL)
        return -1;

    for (i = 0; i < len / ETH_ALEN; i++)
        printf(MACSTR " ", MAC2STR(bssid + ETH_ALEN * i));
    printf("\n");

    return 0;
}
static int cmd_version(int s, int argc, char *argv[])
{
    u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
    u8 buf[4];
    char *version;
    size_t len;
    int rlen, i;

    WPA_PUT_BE32(buf, WLANTEST_CTRL_VERSION);
    rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
    if (rlen < 0)
        return -1;

    version = (char *) attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_VERSION,
                                &len);
    if (version == NULL)
        return -1;

    for (i = 0; i < len; i++)
        putchar(version[i]);
    printf("\n");

    return 0;
}
Beispiel #25
0
static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
				size_t clen)
{
	u8 *passphrase;
	size_t len;
	struct wlantest_passphrase *p, *pa;
	u8 *bssid;

	passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
	if (passphrase == NULL) {
		u8 *wepkey;
		char *key;
		enum wlantest_ctrl_cmd res;

		wepkey = attr_get(cmd, clen, WLANTEST_ATTR_WEPKEY, &len);
		if (wepkey == NULL) {
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
			return;
		}
		key = os_zalloc(len + 1);
		if (key == NULL) {
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
		os_memcpy(key, wepkey, len);
		if (add_wep(wt, key) < 0)
			res = WLANTEST_CTRL_FAILURE;
		else
			res = WLANTEST_CTRL_SUCCESS;
		os_free(key);
		ctrl_send_simple(wt, sock, res);
		return;
	}

	if (len < 8 || len > 63) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	p = os_zalloc(sizeof(*p));
	if (p == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}
	os_memcpy(p->passphrase, passphrase, len);
	wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);

	bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
	if (bssid) {
		os_memcpy(p->bssid, bssid, ETH_ALEN);
		wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
			   MAC2STR(p->bssid));
	}

	dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
	{
		if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
		    os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
			wpa_printf(MSG_INFO, "Passphrase was already known");
			os_free(p);
			p = NULL;
			break;
		}
	}

	if (p) {
		struct wlantest_bss *bss;
		dl_list_add(&wt->passphrase, &p->list);
		dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
			if (bssid &&
			    os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
				continue;
			bss_add_pmk_from_passphrase(bss, p->passphrase);
		}
	}

	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}
Beispiel #26
0
void HRA_store_a(SV *self, SV *attr, char *t, SV *value, ...)
{
    SV *vstring = newSVuv((UV)SvRV(value)); //reverse lookup key
    SV *aobj    = NULL; //primary attribute entry, from attr_lookup
    SV *vref    = NULL; //value's entry in attribute hash
    SV *attrhash_ref = NULL; //reference for attribute hash, for adding actions
    
    SV **a_r_ent = NULL; //lval-type HE for looking/storing attr in vhash
    char *astring = NULL;
    
    hrattr_simple *aptr; //our private attribute structure
    
    int options = STORE_OPT_O_CREAT;
    int i;
    
    dXSARGS;
    if ((items-4) % 2) {
        die("Expected hash options or nothing (got %d)", items-3);
    }
    for(i=4;i<items;i+=2) {
        _chkopt(STRONG_ATTR, i, options);
        _chkopt(STRONG_VALUE, i, options);
    }
    
    aobj = attr_get(self, attr, t, options);
    if(!aobj) {
        die("attr_get() failed to return anything");
    }
    
    aptr = attr_from_sv(SvRV(aobj));
    assert(SvROK(aobj));
    astring = attr_strkey(aptr, attr_getsize(aptr));
    
    if(!insert_into_vhash(value, aobj, astring, REF2TABLE(self), NULL)) {
        goto GT_RET; /*No new insertions*/
    }
    
    if(!HvKEYS(aptr->attrhash)) {
        /*First entry and we've already inserted our reverse entry*/
        SvREFCNT_dec(SvRV(aobj));
    }
    
    vref = newSVsv(value);
    if(hv_store_ent(aptr->attrhash, vstring, vref, 0)) {
        if( (options & STORE_OPT_STRONG_VALUE) == 0) {
            sv_rvweaken(vref);
        }
    } else {
        SvREFCNT_dec(vref);
    }
    
    RV_Newtmp(attrhash_ref, (SV*)aptr->attrhash);
    
    HR_Action v_actions[] = {
        HR_DREF_FLDS_ptr_from_hv(SvRV(value), attrhash_ref),
        HR_ACTION_LIST_TERMINATOR
    };
    
    HR_add_actions_real(value, v_actions);
        
    GT_RET:
    SvREFCNT_dec(vstring);
    if(attrhash_ref) {
        RV_Freetmp(attrhash_ref);
    }
    XSRETURN(0);
}
Beispiel #27
0
static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
	DIR *dp;
	buffer *out;
	struct dirent *dent;
	struct stat st;
	char *path, *path_file;
	size_t i;
	int hide_dotfiles = p->conf.hide_dot_files;
	dirls_list_t dirs, files, *list;
	dirls_entry_t *tmp;
	char sizebuf[sizeof("999.9K")];
	char datebuf[sizeof("2005-Jan-01 22:23:24")];
	size_t k;
	const char *content_type;
	long name_max;
#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR)
	char attrval[128];
	int attrlen;
#endif
#ifdef HAVE_LOCALTIME_R
	struct tm tm;
#endif

	if (buffer_string_is_empty(dir)) return -1;

	i = buffer_string_length(dir);

#ifdef HAVE_PATHCONF
	if (0 >= (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
		/* some broken fs (fuse) return 0 instead of -1 */
#ifdef NAME_MAX
		name_max = NAME_MAX;
#else
		name_max = 255; /* stupid default */
#endif
	}
#elif defined __WIN32
	name_max = FILENAME_MAX;
#else
	name_max = NAME_MAX;
#endif

	path = malloc(i + name_max + 1);
	force_assert(NULL != path);
	memcpy(path, dir->ptr, i+1);
	path_file = path + i;

	if (NULL == (dp = opendir(path))) {
		log_error_write(srv, __FILE__, __LINE__, "sbs",
			"opendir failed:", dir, strerror(errno));

		free(path);
		return -1;
	}

	dirs.ent   = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	force_assert(dirs.ent);
	dirs.size  = DIRLIST_BLOB_SIZE;
	dirs.used  = 0;
	files.ent  = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	force_assert(files.ent);
	files.size = DIRLIST_BLOB_SIZE;
	files.used = 0;

	while ((dent = readdir(dp)) != NULL) {
		unsigned short exclude_match = 0;

		if (dent->d_name[0] == '.') {
			if (hide_dotfiles)
				continue;
			if (dent->d_name[1] == '\0')
				continue;
			if (dent->d_name[1] == '.' && dent->d_name[2] == '\0')
				continue;
		}

		if (p->conf.hide_readme_file && !buffer_string_is_empty(p->conf.show_readme)) {
			if (strcmp(dent->d_name, p->conf.show_readme->ptr) == 0)
				continue;
		}
		if (p->conf.hide_header_file && !buffer_string_is_empty(p->conf.show_header)) {
			if (strcmp(dent->d_name, p->conf.show_header->ptr) == 0)
				continue;
		}

		/* compare d_name against excludes array
		 * elements, skipping any that match.
		 */
#ifdef HAVE_PCRE_H
		for(i = 0; i < p->conf.excludes->used; i++) {
			int n;
#define N 10
			int ovec[N * 3];
			pcre *regex = p->conf.excludes->ptr[i]->regex;

			if ((n = pcre_exec(regex, NULL, dent->d_name,
				    strlen(dent->d_name), 0, 0, ovec, 3 * N)) < 0) {
				if (n != PCRE_ERROR_NOMATCH) {
					log_error_write(srv, __FILE__, __LINE__, "sd",
						"execution error while matching:", n);

					/* aborting would require a lot of manual cleanup here.
					 * skip instead (to not leak names that break pcre matching)
					 */
					exclude_match = 1;
					break;
				}
			}
			else {
				exclude_match = 1;
				break;
			}
		}

		if (exclude_match) {
			continue;
		}
#endif

		i = strlen(dent->d_name);

		/* NOTE: the manual says, d_name is never more than NAME_MAX
		 *       so this should actually not be a buffer-overflow-risk
		 */
		if (i > (size_t)name_max) continue;

		memcpy(path_file, dent->d_name, i + 1);
		if (stat(path, &st) != 0)
			continue;

		list = &files;
		if (S_ISDIR(st.st_mode))
			list = &dirs;

		if (list->used == list->size) {
			list->size += DIRLIST_BLOB_SIZE;
			list->ent   = (dirls_entry_t**) realloc(list->ent, sizeof(dirls_entry_t*) * list->size);
			force_assert(list->ent);
		}

		tmp = (dirls_entry_t*) malloc(sizeof(dirls_entry_t) + 1 + i);
		tmp->mtime = st.st_mtime;
		tmp->size  = st.st_size;
		tmp->namelen = i;
		memcpy(DIRLIST_ENT_NAME(tmp), dent->d_name, i + 1);

		list->ent[list->used++] = tmp;
	}
	closedir(dp);

	if (dirs.used) http_dirls_sort(dirs.ent, dirs.used);

	if (files.used) http_dirls_sort(files.ent, files.used);

	out = buffer_init();
	http_list_directory_header(srv, con, p, out);

	/* directories */
	for (i = 0; i < dirs.used; i++) {
		tmp = dirs.ent[i];

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif

		buffer_append_string_len(out, CONST_STR_LEN("<tr class=\"d\"><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("/\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a>/</td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n"));

		free(tmp);
	}

	/* files */
	for (i = 0; i < files.used; i++) {
		tmp = files.ent[i];

		content_type = NULL;
#if defined(HAVE_XATTR)
		if (con->conf.use_xattr) {
			memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
			attrlen = sizeof(attrval) - 1;
			if (attr_get(path, srv->srvconf.xattr_name->ptr, attrval, &attrlen, 0) == 0) {
				attrval[attrlen] = '\0';
				content_type = attrval;
			}
		}
#elif defined(HAVE_EXTATTR)
		if (con->conf.use_xattr) {
			memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
			if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, srv->srvconf.xattr_name->ptr, attrval, sizeof(attrval)-1))) {
				attrval[attrlen] = '\0';
				content_type = attrval;
			}
		}
#endif

		if (content_type == NULL) {
			content_type = "application/octet-stream";
			for (k = 0; k < con->conf.mimetypes->used; k++) {
				data_string *ds = (data_string *)con->conf.mimetypes->data[k];
				size_t ct_len;

				if (buffer_is_empty(ds->key))
					continue;

				ct_len = buffer_string_length(ds->key);
				if (tmp->namelen < ct_len)
					continue;

				if (0 == strncasecmp(DIRLIST_ENT_NAME(tmp) + tmp->namelen - ct_len, ds->key->ptr, ct_len)) {
					content_type = ds->value->ptr;
					break;
				}
			}
		}

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif
		http_list_directory_sizefmt(sizebuf, sizeof(sizebuf), tmp->size);

		buffer_append_string_len(out, CONST_STR_LEN("<tr><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a></td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">"));
		buffer_append_string(out, sizebuf);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"t\">"));
		buffer_append_string(out, content_type);
		buffer_append_string_len(out, CONST_STR_LEN("</td></tr>\n"));

		free(tmp);
	}

	free(files.ent);
	free(dirs.ent);
	free(path);

	http_list_directory_footer(srv, con, p, out);

	/* Insert possible charset to Content-Type */
	if (buffer_string_is_empty(p->conf.encoding)) {
		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
	} else {
		buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
		buffer_append_string_buffer(p->content_charset, p->conf.encoding);
		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
	}

	con->file_finished = 1;
	chunkqueue_append_buffer(con->write_queue, out);
	buffer_free(out);

	return 0;
}
Beispiel #28
0
static void ctrl_send_(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u8 *bssid, *sta_addr;
	int prot;
	u8 *frame;
	size_t frame_len;
	int ret = 0;
	struct ieee80211_hdr *hdr;
	u16 fc;

	frame = attr_get(cmd, clen, WLANTEST_ATTR_FRAME, &frame_len);
	prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
	if (frame == NULL || frame_len < 24 || prot < 0) {
		wpa_printf(MSG_INFO, "Invalid send command parameters");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	hdr = (struct ieee80211_hdr *) frame;
	fc = le_to_host16(hdr->frame_control);
	switch (WLAN_FC_GET_TYPE(fc)) {
	case WLAN_FC_TYPE_MGMT:
		bssid = hdr->addr3;
		if (os_memcmp(hdr->addr2, hdr->addr3, ETH_ALEN) == 0)
			sta_addr = hdr->addr1;
		else
			sta_addr = hdr->addr2;
		break;
	case WLAN_FC_TYPE_DATA:
		switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
		case 0:
			bssid = hdr->addr3;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_TODS:
			bssid = hdr->addr1;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_FROMDS:
			bssid = hdr->addr2;
			sta_addr = hdr->addr1;
			break;
		default:
			wpa_printf(MSG_INFO, "Unsupported inject frame");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
		break;
	default:
		wpa_printf(MSG_INFO, "Unsupported inject frame");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL) {
		wpa_printf(MSG_INFO, "Unknown BSSID");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	sta = sta_find(bss, sta_addr);
	if (sta == NULL) {
		wpa_printf(MSG_INFO, "Unknown STA address");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	ret = wlantest_inject(wt, bss, sta, frame, frame_len, prot);

	if (ret)
		wpa_printf(MSG_INFO, "Failed to inject frame");
	else
		wpa_printf(MSG_INFO, "Frame injected successfully");
	ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
			 WLANTEST_CTRL_FAILURE);
}
Beispiel #29
0
ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size)
{
#if defined(HAVE_GETXATTR)
#ifndef XATTR_ADDITIONAL_OPTIONS
	return getxattr(path, name, value, size);
#else

/* So that we do not recursivly call this function */
#undef getxattr
	int options = 0;
	return getxattr(path, name, value, size, 0, options);
#endif
#elif defined(HAVE_GETEA)
	return getea(path, name, value, size);
#elif defined(HAVE_EXTATTR_GET_FILE)
	char *s;
	ssize_t retval;
	int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
		EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
	const char *attrname = ((s=strchr(name, '.')) == NULL) ? name : s + 1;
	/*
	 * The BSD implementation has a nasty habit of silently truncating
	 * the returned value to the size of the buffer, so we have to check
	 * that the buffer is large enough to fit the returned value.
	 */
	if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
		if (size == 0) {
			return retval;
		} else if (retval > size) {
			errno = ERANGE;
			return -1;
		}
		if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
			return retval;
	}

	return -1;
#elif defined(HAVE_ATTR_GET)
	int retval, flags = 0;
	int valuelength = (int)size;
	char *attrname = strchr(name,'.') + 1;

	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;

	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
	if (size == 0 && retval == -1 && errno == E2BIG) {
		return valuelength;
	}

	return retval ? retval : valuelength;
#elif defined(HAVE_ATTROPEN)
	ssize_t ret = -1;
	int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
	if (attrfd >= 0) {
		ret = solaris_read_xattr(attrfd, value, size);
		close(attrfd);
	}
	return ret;
#else
	errno = ENOSYS;
	return -1;
#endif
}
Beispiel #30
0
static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
	DIR *dp;
	buffer *out;
	struct dirent *dent;
	struct stat st;
	size_t i;
	int hide_dotfiles = p->conf.hide_dot_files;
	dirls_list_t dirs, files, *list;
	dirls_entry_t *tmp;
	char sizebuf[sizeof("999.9K")];
	char datebuf[sizeof("2005-Jan-01 22:23:24")];
	size_t k;
	const char *content_type;
	long name_max;

#ifdef HAVE_XATTR
	char attrval[128];
	int attrlen;
#endif
#ifdef HAVE_LOCALTIME_R
	struct tm tm;
#endif

	/* empty pathname, never ... */
	if (buffer_is_empty(dir)) return -1;

	/* max-length for the opendir */
#ifdef HAVE_PATHCONF
	if (-1 == (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
#ifdef NAME_MAX
		name_max = NAME_MAX;
#else
		name_max = 256; /* stupid default */
#endif
	}
#elif defined _WIN32
	name_max = FILENAME_MAX;
#else
	name_max = NAME_MAX;
#endif

	buffer_copy_string_buffer(p->path, dir);
	PATHNAME_APPEND_SLASH(p->path);

#ifdef _WIN32
	/* append *.* to the path */
	buffer_append_string_len(p->path, CONST_STR_LEN("*.*"));
#endif

	if (NULL == (dp = opendir(p->path->ptr))) {
		log_error_write(srv, __FILE__, __LINE__, "sbs",
			"opendir failed:", dir, strerror(errno));

		return -1;
	}

	dirs.ent   = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	assert(dirs.ent);
	dirs.size  = DIRLIST_BLOB_SIZE;
	dirs.used  = 0;
	files.ent  = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	assert(files.ent);
	files.size = DIRLIST_BLOB_SIZE;
	files.used = 0;

	while ((dent = readdir(dp)) != NULL) {
		unsigned short exclude_match = 0;

		if (dent->d_name[0] == '.') {
			if (hide_dotfiles)
				continue;
			if (dent->d_name[1] == '\0')
				continue;
			if (dent->d_name[1] == '.' && dent->d_name[2] == '\0')
				continue;
		}

		if (p->conf.hide_readme_file) {
			if (strcmp(dent->d_name, "README.txt") == 0)
				continue;
		}
		if (p->conf.hide_header_file) {
			if (strcmp(dent->d_name, "HEADER.txt") == 0)
				continue;
		}

		/* compare d_name against excludes array
		 * elements, skipping any that match.
		 */
#ifdef HAVE_PCRE_H
		for(i = 0; i < p->conf.excludes->used; i++) {
			int n;
#define N 10
			int ovec[N * 3];
			pcre *regex = p->conf.excludes->ptr[i]->regex;

			if ((n = pcre_exec(regex, NULL, dent->d_name,
				    strlen(dent->d_name), 0, 0, ovec, 3 * N)) < 0) {
				if (n != PCRE_ERROR_NOMATCH) {
					log_error_write(srv, __FILE__, __LINE__, "sd",
						"execution error while matching:", n);

					return -1;
				}
			}
			else {
				exclude_match = 1;
				break;
			}
		}

		if (exclude_match) {
			continue;
		}
#endif

		i = strlen(dent->d_name);

		/* NOTE: the manual says, d_name is never more than NAME_MAX
		 *       so this should actually not be a buffer-overflow-risk
		 */
		if (i > (size_t)name_max) continue;

		/* build the dirname */
		buffer_copy_string_buffer(p->path, dir);
		PATHNAME_APPEND_SLASH(p->path);
		buffer_append_string(p->path, dent->d_name);

		if (stat(p->path->ptr, &st) != 0) {
			fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, p->path->ptr, strerror(errno));
			continue;
		}

		list = &files;
		if (S_ISDIR(st.st_mode))
			list = &dirs;

		if (list->used == list->size) {
			list->size += DIRLIST_BLOB_SIZE;
			list->ent   = (dirls_entry_t**) realloc(list->ent, sizeof(dirls_entry_t*) * list->size);
			assert(list->ent);
		}

		tmp = (dirls_entry_t*) malloc(sizeof(dirls_entry_t) + 1 + i);
		tmp->mtime = st.st_mtime;
		tmp->size  = st.st_size;
		tmp->namelen = i;
		memcpy(DIRLIST_ENT_NAME(tmp), dent->d_name, i + 1);

		list->ent[list->used++] = tmp;
	}
	closedir(dp);

	if (dirs.used) http_dirls_sort(dirs.ent, dirs.used);

	if (files.used) http_dirls_sort(files.ent, files.used);

	out = chunkqueue_get_append_buffer(con->send);
	buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
	if (buffer_is_empty(p->conf.encoding)) {
		buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
	} else {
		buffer_append_string_buffer(out, p->conf.encoding);
	}
	buffer_append_string_len(out, CONST_STR_LEN("\"?>\n"));
	http_list_directory_header(srv, con, p, out);

	/* directories */
	for (i = 0; i < dirs.used; i++) {
		tmp = dirs.ent[i];

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif

		buffer_append_string_len(out, CONST_STR_LEN("<tr><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("/\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a>/</td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n"));

		free(tmp);
	}

	/* files */
	for (i = 0; i < files.used; i++) {
		tmp = files.ent[i];

		content_type = NULL;

#ifdef HAVE_XATTR
		if (con->conf.use_xattr) {
			/* build the dirname */
			buffer_copy_string_buffer(p->path, dir);
			PATHNAME_APPEND_SLASH(p->path);
			buffer_append_string_len(p->path, DIRLIST_ENT_NAME(tmp), tmp->namelen);

			attrlen = sizeof(attrval) - 1;
			if (attr_get(p->path->ptr, "Content-Type", attrval, &attrlen, 0) == 0) {
				attrval[attrlen] = '\0';
				content_type = attrval;
			}
		}
#endif

		if (content_type == NULL) {
			content_type = "application/octet-stream";
			for (k = 0; k < con->conf.mimetypes->used; k++) {
				data_string *ds = (data_string *)con->conf.mimetypes->data[k];
				size_t ct_len;

				if (ds->key->used == 0)
					continue;

				ct_len = ds->key->used - 1;
				if (tmp->namelen < ct_len)
					continue;

				if (0 == strncasecmp(DIRLIST_ENT_NAME(tmp) + tmp->namelen - ct_len, ds->key->ptr, ct_len)) {
					content_type = ds->value->ptr;
					break;
				}
			}
		}

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif
		http_list_directory_sizefmt(sizebuf, tmp->size);

		buffer_append_string_len(out, CONST_STR_LEN("<tr><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a></td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">"));
		buffer_append_string(out, sizebuf);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"t\">"));
		buffer_append_string(out, content_type);
		buffer_append_string_len(out, CONST_STR_LEN("</td></tr>\n"));

		free(tmp);
	}

	free(files.ent);
	free(dirs.ent);

	http_list_directory_footer(srv, con, p, out);

	/* Insert possible charset to Content-Type */
	if (buffer_is_empty(p->conf.encoding)) {
		response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
	} else {
		buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
		buffer_append_string_buffer(p->content_charset, p->conf.encoding);
		response_header_insert(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
	}

	con->send->bytes_in += out->used - 1;

	con->send->is_closed = 1;

	return 0;
}