BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBgetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fd); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (cli_is_error(cli)) { return False; } if (size) { *size = IVAL(cli->inbuf, smb_vwv6); } if (attr) { *attr = SVAL(cli->inbuf,smb_vwv10); } if (c_time) { *c_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0); } if (a_time) { *a_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2); } if (m_time) { *m_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4); } return True; }
static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo, uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len) { file_info finfo2; int len; char *base = p; if (!finfo) { finfo = &finfo2; } if (p_resume_key) { *p_resume_key = 0; } memcpy(finfo,&def_finfo,sizeof(*finfo)); finfo->cli = cli; switch (level) { case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call (tridge) */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), len+2, STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; /* check for unisys! */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), len, STR_NOALIGN); return PTR_DIFF(p, base) + 1; case 260: /* NT uses this, but also accepts 2 */ { size_t namelen, slen; p += 4; /* next entry offset */ if (p_resume_key) { *p_resume_key = IVAL(p,0); } p += 4; /* fileindex */ /* Offset zero is "create time", not "change time". */ p += 8; finfo->atime_ts = interpret_long_date(p); p += 8; finfo->mtime_ts = interpret_long_date(p); p += 8; finfo->ctime_ts = interpret_long_date(p); p += 8; finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; { /* stupid NT bugs. grr */ int flags = 0; if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), slen, flags); } p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); /* To be robust in the face of unicode conversion failures we need to copy the raw bytes of the last name seen here. Namelen doesn't include the terminating unicode null, so copy it here. */ if (p_last_name_raw && p_last_name_raw_len) { if (namelen + 2 > p_last_name_raw->length) { memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); *p_last_name_raw_len = 0; } else { memcpy(p_last_name_raw->data, p, namelen); SSVAL(p_last_name_raw->data, namelen, 0); *p_last_name_raw_len = namelen + 2; } } return (size_t)IVAL(base, 0); } } DEBUG(1,("Unknown long filename format %d\n",level)); return (size_t)IVAL(base,0); }