예제 #1
0
static void icq_get_user_info(session_t *s, userlist_t *u, struct icq_tlv_list *tlvs, int newstatus) {
    int caps = 0, desc_chg = 0;
    char *descr = NULL;
    icq_tlv_t *t;

    if (!u)
        return;

    debug_function("icq_get_user_info() %s\n", u->uid);

    descr = u->descr ? xstrdup(u->descr) : NULL;

    user_private_item_set_int(u, "idle", 0);
    user_private_item_set_int(u, "status_f", 0);
    user_private_item_set_int(u, "xstatus", 0);

    for (t = tlvs; t; t = t->next) {

        /* Check t->len */
        switch (t->type) {
        case 0x01:
            if (tlv_length_check("icq_get_user_info()", t, 2))
                continue;
            break;
        case 0x03:
        case 0x04:
        case 0x05:
        case 0x06:
        case 0x0a:
        case 0x0f:
            if (tlv_length_check("icq_get_user_info()", t, 4))
                continue;
            break;
        }
        /* now we've got trusted length */
        switch (t->type) {
        case 0x01: /* User class */
            user_private_item_set_int(u, "class", t->nr);
            break;

        case 0x03: /* Time when client gone online (unix time_t) */
            user_private_item_set_int(u, "online", t->nr);
            break;

        case 0x04: /* idle timer */
        {
            uint16_t idle;
            if ( (idle = t->nr) )
                user_private_item_set_int(u, "idle", time(NULL) - 60*idle);
            break;
        }

        case 0x05: /* Time when this account was registered (unix time_t) */
            user_private_item_set_int(u, "member", t->nr);
            break;

        case 0x06:
        {
            /* User status
             *
             * ICQ service presence notifications use user status field which consist
             * of two parts. First is a various flags (birthday flag, webaware flag,
             * etc). Second is a user status (online, away, busy, etc) flags.
             */
            uint16_t status	= t->nr & 0xffff;
            uint16_t flags	= t->nr >> 16;

            user_private_item_set_int(u, "status_f", flags);
            debug_white(" %s status flags=0x%04x status=0x%04x\n", u->uid, flags, status);
            newstatus = icq2ekg_status(status);
            break;
        }

        case 0x0a: /* IP address */
        {
            uint32_t ip;
            if (icq_unpack_nc(t->buf, t->len, "i", &ip)) {
                if (ip)
                    user_private_item_set_int(u, "ip", ip);
            }
            break;
        }

        case 0x0c: /* DC info */
        {
            struct {
                uint32_t ip;
                uint32_t port;
                uint8_t tcp_flag;
                uint16_t version;
                uint32_t conn_cookie;
                uint32_t web_port;
                uint32_t client_features;
                /* faked time signatures, used to identify clients */
                uint32_t ts1;
                uint32_t ts2;
                uint32_t ts3;
                uint16_t junk;
            } tlv_c;

            if (!icq_unpack_nc(t->buf, t->len, "IICWIII",
                               &tlv_c.ip, &tlv_c.port,
                               &tlv_c.tcp_flag, &tlv_c.version,
                               &tlv_c.conn_cookie, &tlv_c.web_port,
                               &tlv_c.client_features))
            {
                debug_error(" %s TLV(C) corrupted?\n", u->uid);
                continue;
            } else {
                user_private_item_set_int(u, "dcc.ip", tlv_c.ip);
                user_private_item_set_int(u, "dcc.port", tlv_c.port);
                user_private_item_set_int(u, "dcc.flag", tlv_c.tcp_flag);
                user_private_item_set_int(u, "version", tlv_c.version);
                user_private_item_set_int(u, "dcc.cookie", tlv_c.conn_cookie);
                user_private_item_set_int(u, "dcc.web_port", tlv_c.web_port);	// ?wo? do we need it?
                if (t->len >= 12 && icq_unpack_nc(t->buf, t->len, "23 III", &tlv_c.ts1, &tlv_c.ts3, &tlv_c.ts3))
                    ;
            }
            break;
        }

        case 0x0d: /* Client capabilities list */
        {
            unsigned char *data = t->buf;
            int d_len = t->len;

            if (tlv_length_check("icq_get_user_info()", t, t->len & ~0xF))
                break;
            while (d_len > 0) {
                int cid = icq_cap_id(data);
                if (cid != CAP_UNKNOWN) {
                    caps |= 1 << cid;
                } else if ((cid = icq_xstatus_id(data))) {
                    user_private_item_set_int(u, "xstatus", cid);
                } else {
                    /* ?wo? client id???*/
                    debug_error("Unknown cap\n");
                    icq_hexdump(DEBUG_ERROR, data, 0x10);
                }
                data  += 0x10;		// capability length
                d_len -= 0x10;
            }
            break;
        }

        case 0x0e: /* AOL users. No values */
            break;

        case 0x0f:
        case 0x10: /* Online time in seconds */
            break;

        case 0x19: /* short caps */
        {
            unsigned char *data = t->buf;
            int d_len = t->len;

            while (d_len > 0) {
                int cid = icq_short_cap_id(data);
                if (cid != CAP_UNKNOWN) {
                    caps |= 1 << cid;
                } else {
                    /* WTF? */
                }
                data  += 2;		// short capability length
                d_len -= 2;
            }
            break;
        }

        case 0x1d: /* user icon id & hash */
        {
            static char empty_item[0x10] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
            unsigned char *t_data = t->buf;
            int t_len = t->len;

            while (t_len > 0) {

                uint16_t item_type;
                uint8_t item_flags;
                uint8_t item_len;

                if (!icq_unpack(t_data, &t_data, &t_len, "WCC", &item_type, &item_flags, &item_len)) {
                    debug_error(" %s TLV(1D) corrupted?\n", u->uid);
                    break;
                }

                /* just some validity check */
                if (item_len > t_len)
                    item_len = t_len;

                if ((item_type == 0x02) && (item_flags == 4)) {
                    /* iChat online message */
                    if (item_len>4) {
                        char *tmp;
                        uint16_t enc;
                        icq_unpack_nc(t_data, item_len, "Uw", &tmp, &enc);
                        descr = !enc ? ekg_utf8_to_locale_dup(tmp) : xstrdup(tmp);
                    }
                    desc_chg = 1;
                } else if ((item_type == 0x0e) && (item_len>7)) {
                    /* 000E: Custom Status (ICQ6) */
                    char *tmp = xstrndup((char *)t_data, item_len);
                    if ( !xstrncmp(tmp, "icqmood", 7) && xisdigit(*(tmp+7)) ) {
                        int xstatus = atoi(tmp+7) + 1;
                        if (xstatus<=XSTATUS_COUNT)
                            user_private_item_set_int(u, "xstatus", xstatus);
                    }
                    xfree(tmp);
                } else if (memcmp(t_data, empty_item, (item_len < 0x10) ? item_len : 0x10)) {
                    /* Item types
                     * 	0000: AIM mini avatar
                     * 	0001: AIM/ICQ avatar ID/hash (len 5 or 16 bytes)
                     * 	0002: iChat online message
                     *	0008: ICQ Flash avatar hash (16 bytes)
                     * 	0009: iTunes music store link
                     *	000C: ICQ contact photo (16 bytes)
                     *	000D: ?
                     */

                    debug_white(" %s has got avatar: type: %d flags: %d\n", u->uid, item_type, item_flags);
                    icq_hexdump(DEBUG_WHITE, t_data, item_len);
                    /* XXX, display message, get? do something? */
                }

                t_data += item_len;
                t_len -= item_len;
            }
            break;
        }
        default:
            if (t->len==4)
                debug_warn(" %s Unknown TLV(0x%x) len=4 v=%d (0x%x) (%s)\n", u->uid, t->type, t->nr, t->nr, t->nr?timestamp_time("%Y-%m-%d %H:%M:%S", t->nr):"");
            else
                debug_error(" %s Unknown TLV(0x%x) len=%d\n", u->uid, t->type, t->len);
        }
    }

    if (desc_chg || (newstatus != u->status)) {
        if (!descr && !desc_chg && u->descr)
            descr = xstrdup(u->descr);

        protocol_status_emit(s, u->uid, newstatus, descr, time(NULL));
    }

    if (!desc_chg) {
        if (u->status == EKG_STATUS_NA) {
            icq_send_snac(s, 0x02, 0x05, NULL, NULL,	/* Request user info */
                          "Ws",
                          (uint32_t) 1,			/* request type (1 - general info, 2 - short user info, 3 - away message, 4 - client capabilities) */
                          u->uid+4);
        } else {
            icq_get_description(s, u->uid+4, u->status);
        }
    }

    if (u->status == EKG_STATUS_NA) {
        user_private_item_set_int(u, "online", 0);
        user_private_item_set_int(u, "last_ip", user_private_item_get_int(u, "ip"));
        user_private_item_set_int(u, "ip", 0);
        if (user_private_item_get_int(u, "version") < 8) {
            caps &= ~(1<<CAP_SRV_RELAY);
            debug_warn("icq_snac_buddy_online() Forcing simple messages due to compatibility issues (%s).\n", u->uid);
        }
    }

    user_private_item_set_int(u, "caps", caps);
    user_private_item_set_int(u, "utf", (caps && (1<<CAP_UTF)) ? 1:0);

    xfree(descr);
}
예제 #2
0
void split_timestamp(ULL timestamp, int& out_year, int& out_month, int& out_day, int& out_hour, int& out_minute, int& out_second) {
  date_to_ymd(timestamp_date(timestamp), out_year, out_month, out_day);
  time_to_hms(timestamp_time(timestamp), out_hour, out_minute, out_second);
}
예제 #3
0
파일: backlog.c 프로젝트: hiciu/ekg2
/*
 * backlog_split()
 *
 * dzieli linie tekstu w buforze na linie ekranowe.
 *
 *  - w - okno do podzielenia
 *
 * XXX function uses n->x0, y0, width, height !!! call calc_window_dimension(). !!!
 */
static int backlog_split(window_t *w, backlog_line_t *b, gboolean show, int y) {
	ncurses_window_t *n = w->priv_data;
	int rows_count = 0;
	/* timestamp */
	int ts_width		= 0;
	gchar *ts_str		= NULL;
	fstr_attr_t *ts_attr	= NULL;
	/* prompt */
	int prompt_width	= b->line->prompt_empty ? 0 : xmbswidth(b->line->str, b->line->prompt_len);
	/* text */
	char *str		= b->line->str  + b->line->prompt_len;
	fstr_attr_t *attr	= b->line->attr + b->line->prompt_len;

	/* set timestamp */
	if (b->line->ts && formated_config_timestamp && config_timestamp_show &&
	    (!w->floating || w->id == WINDOW_LASTLOG_ID))
	{
		fstring_t *s = fstring_new(timestamp_time(formated_config_timestamp, b->line->ts));
		ts_str	 = s->str;
		ts_attr	 = s->attr;
		xfree(s);
		ts_width = xmbswidth(ts_str, xstrlen(ts_str));
	}

	while (*str || rows_count==0) {
		int len, last_space = 0;
		int width = n->width - prompt_width;

		if ((rows_count==0) || !(config_display_indent==1 && prompt_width==0))
			width -= ts_width;

		len = wrap_line(w, width, str, attr, &last_space);

		if (show && (0 <= y && y < n->height)) {
			wmove(n->window, n->y0 + y, n->x0);

			if (ts_width && ((config_display_indent==0) || (rows_count==0))) {
				ncurses_fstring_print_fast(n->window, ts_str, ts_attr, -1);
			} else if (config_display_indent==2 || prompt_width)
				wmove(n->window, n->y0 + y, n->x0 + ts_width);

			if (prompt_width)	/* print prompt */
				ncurses_fstring_print_fast(n->window, b->line->str, b->line->attr, b->line->prompt_len);

			if (width > 0)		/* print text */
				ncurses_fstring_print_fast(n->window, str, attr, len);
		}

		rows_count++;

		if (w->nowrap)
			break;

		str	+= len + last_space;
		attr	+= len + last_space;
		y++;
	}

	if (show && (n->marker == b) && (0 <= y && y < n->height))
		draw_thin_red_line(w, n->y0 + y);

	xfree(ts_str);
	xfree(ts_attr);

	return rows_count;
}
예제 #4
0
/*
 * Normalization of hours, minutes, and seconds is different than normalization of years, months, and day.
 * A specific time is a number of hours, minutes, and seconds that has already elapsed (e.g. 3:00 PM means
 * that 15 hours of the day have elapsed). A specific date is not a number of years, months, and days that
 * have elapsed, they indicate the current year, month, and day -- they indicate which year, month, and day
 * that we are in (e.g. 12/3/2009 at 8:00 AM means that 2008 years, 11 months, 2 days, 8 hours have elapsed).
 */
ULL operator+(const ULL& ts, const Interval& i) {
//  ULL t = 0;
//  int year,month,day,hours,minutes,seconds;
//  year = month = day = hours = minutes = seconds = 0;

  ULL t = 0;
  int year,month,day,hours,minutes,seconds;
  long inc = 0;
  long multiple;
  year = month = day = hours = minutes = seconds = 0;

  date_to_ymd(timestamp_date(ts), year, month, day);
  time_to_hms(timestamp_time(ts), hours, minutes, seconds);

  // add the interval's seconds, minutes, hours, and years to the values extracted from the timestamp (ts);
  //   we'll add the months and days later
  seconds += i.seconds;
  minutes += i.minutes;
  hours += i.hours;
  year += i.years;

  // Since adding a number of months might affect the day, we want to normalize the months before
  //   we go into normalizing the days.
  // For example: 1/29/2009 + 1 month = 1/28/2009
  //         but: 1/29/2008 + 1 month = 1/29/2009
  //        Also: 1/30/2009 + 1 month = 1/28/2009
  //         and: 1/31/2009 + 2 months = 3/31/2009
  // ** I am assuming the the day we fall on depends on how many days the target month has in it -- If  **
  // ** the target month has fewer days in it than the origin month, and the origin day is a day that   **
  // ** the target month doesn't have, then the target day will be the last day of the target month.    **

  // normalize month count
  //int origin_month_length = days_in_month(year, month);
  month += i.months;
  // figure out how many years worth of months we can increment our year count by,
  //   and determine which month we will be in after we remove that number of years worth of months from the month count.
  /*
  if(month > 12) {                                     
    year += (month - 1) / 12;
    month = ((month - 1) % 12) + 1;
  }
  */
  
  // see http://tinyurl.com/nu97yg for a demonstration of why this math works
  multiple = 12;
  inc = floor((double)(month - 1) / multiple);
  year += inc;
  month = ((month - 1) - multiple*inc) + 1;

  int target_month_length = days_in_month(year, month);
  if(/* target_month_length < origin_month_length && */ day > target_month_length) {     // adjust the day of the month if we need to
    day = target_month_length;                        // set the day to the last day in the (shorter) target month
  }

  /*
  // normalize seconds, minutes, and hours.
  minutes += seconds / 60;
  seconds %= 60;

  hours += minutes / 60;
  minutes %= 60;

  // we've already normalized the month count so adding to the day count is ok here (we'll normalize the day count afterward).
  day += hours / 24;
  hours %= 24;
  */

  // normalize seconds, minutes, and hours.
  multiple = 60;
  inc = floor((double)seconds / multiple);
  minutes += inc;
  seconds = seconds - multiple*inc;

  inc = floor((double)minutes / multiple);
  hours += inc;
  minutes = minutes - multiple*inc;

  // we've already normalized the month count so adding to the day count is ok here (we'll normalize the day count afterward).
  multiple = 24;
  inc = floor((double)hours / multiple);
  day += inc;
  hours = hours - multiple*inc;

  // normalize day count
  multiple = 12;
  day += i.days;
  int dpm = days_in_month(year, month);
  //cout << day << " " << dpm << endl;
  while(day > dpm) {
    day -= dpm;
    month++;

    // re-normalize month if needed
    inc = floor((double)(month - 1) / multiple);
    year += inc;
    month = ((month - 1) - multiple*inc) + 1;

    dpm = days_in_month(year, month);
  }
  while(day < 1) {
    month--;
    dpm = days_in_month(year, month);
    day += dpm;

    // re-normalize month if needed
    inc = floor((double)(month - 1) / multiple);
    year += inc;
    month = ((month - 1) - multiple*inc) + 1;

    //dpm = days_in_month(year, month);
  }

  t = join_timestamp(year, month, day, hours, minutes, seconds);

  return t;
}