BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf, uint32 *attributes ) { unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; char param[sizeof(pstring)+6]; char *rparam=NULL, *rdata=NULL; char *p; pstring path; int len; pstrcpy( path, name ); /* cleanup */ len = strlen( path ); if ( path[len-1] == '\\' || path[len-1] == '/') path[len-1] = '\0'; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); p += 6; p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ NULL, 0, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } if (data_len < 36) { SAFE_FREE(rdata); SAFE_FREE(rparam); return False; } set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */ set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */ set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */ *attributes = IVAL( rdata, 32 ); SAFE_FREE(rparam); SAFE_FREE(rdata); return True; }
int SMBC_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { struct timespec change_time_ts; struct timespec access_time_ts; struct timespec write_time_ts; SMB_OFF_T size; uint16 mode; char *server = NULL; char *share = NULL; char *user = NULL; char *password = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } if (!file->file) { TALLOC_FREE(frame); return smbc_getFunctionFstatdir(context)(context, file, st); } /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, file->fname, NULL, &server, &share, &path, &user, &password, NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); errno = ENOENT; TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { time_t change_time, access_time, write_time; if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &change_time, &access_time, &write_time)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } change_time_ts = convert_time_t_to_timespec(change_time); access_time_ts = convert_time_t_to_timespec(access_time); write_time_ts = convert_time_t_to_timespec(write_time); } st->st_ino = ino; setup_stat(context, st, file->fname, size, mode); set_atimespec(st, access_time_ts); set_ctimespec(st, change_time_ts); set_mtimespec(st, write_time_ts); st->st_dev = file->srv->dev; TALLOC_FREE(frame); return 0; }
int SMBC_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) { SMBCSRV *srv = NULL; char *server = NULL; char *share = NULL; char *user = NULL; char *password = NULL; char *workgroup = NULL; char *path = NULL; struct timespec write_time_ts; struct timespec access_time_ts; struct timespec change_time_ts; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } DEBUG(4, ("smbc_stat(%s)\n", fname)); if (SMBC_parse_path(frame, context, fname, &workgroup, &server, &share, &path, &user, &password, NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); return -1; } } srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } if (!SMBC_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } st->st_ino = ino; setup_stat(context, st, (char *) fname, size, mode); set_atimespec(st, access_time_ts); set_ctimespec(st, change_time_ts); set_mtimespec(st, write_time_ts); st->st_dev = srv->dev; TALLOC_FREE(frame); return 0; }