+++ /dev/null
-^samba3.smb2.timestamps.time_t_4294967295\(ad_dc\)
-^samba3.smb2.timestamps.time_t_4294967295\(nt4_dc\)
-^samba3.smb2.timestamps.time_t_0\(nt4_dc\)
-^samba3.smb2.timestamps.time_t_0\(ad_dc\)
-^samba3.smb2.timestamps.time_t_-1\(nt4_dc\)
-^samba3.smb2.timestamps.time_t_-1\(ad_dc\)
-^samba3.smb2.timestamps.time_t_-2\(nt4_dc\)
-^samba3.smb2.timestamps.time_t_-2\(ad_dc\)
-^samba3.smb2.timestamps.time_t_1968\(nt4_dc\)
-^samba3.smb2.timestamps.time_t_1968\(ad_dc\)
Use SMB_VFS_UNLINKAT(.., AT_REMOVEDIR) instead. */
/* Version 42 - Remove SMB_VFS_CHOWN */
/* Version 42 - Remove struct write_cache *wcp from files_struct */
+/* Version 42 - SMB_VFS_NTIMES() receives null times based on UTIMES_OMIT */
#define SMB_VFS_INTERFACE_VERSION 42
uint32 num_share_modes;
uint32 num_delete_tokens;
[size_is(num_delete_tokens)] delete_token delete_tokens[];
- timespec old_write_time;
- timespec changed_write_time;
+ NTTIME old_write_time;
+ NTTIME changed_write_time;
[skip] boolean8 fresh;
[skip] boolean8 modified;
[ignore] file_id id; /* In memory key used to lookup cache. */
boolean8 update_write_time_triggered;
boolean8 update_write_time_on_close;
boolean8 write_time_forced;
- timespec close_write_time;
+ NTTIME close_write_time;
vfs_default_durable_stat stat_info;
} vfs_default_durable_cookie;
*/
#include "includes.h"
+#include "lib/util/time_basic.h"
#include "system/filesys.h"
#include "lib/util/server_id.h"
#include "locking/proto.h"
}
if (write_time) {
- ZERO_STRUCTP(write_time);
+ *write_time = make_omit_timespec();
}
if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
{
struct share_mode_lock *lck;
struct file_id_buf ftmp;
+ struct timeval_buf tbuf;
+ NTTIME nt = full_timespec_to_nt_time(&write_time);
DBG_INFO("%s id=%s\n",
- timestring(talloc_tos(),
- convert_timespec_to_time_t(write_time)),
+ timespec_string_buf(&write_time, true, &tbuf),
file_id_str_buf(fileid, &ftmp));
lck = get_existing_share_mode_lock(talloc_tos(), fileid);
return False;
}
- if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
+ if (lck->data->changed_write_time != nt) {
lck->data->modified = True;
- lck->data->changed_write_time = write_time;
+ lck->data->changed_write_time = nt;
}
TALLOC_FREE(lck);
{
struct share_mode_lock *lck;
struct file_id_buf idbuf;
+ struct timeval_buf tbuf;
+ NTTIME nt = full_timespec_to_nt_time(&write_time);
DBG_INFO("%s id=%s\n",
- timestring(talloc_tos(),
- convert_timespec_to_time_t(write_time)),
+ timespec_string_buf(&write_time, true, &tbuf),
file_id_str_buf(fileid, &idbuf));
lck = get_existing_share_mode_lock(talloc_tos(), fileid);
return False;
}
- if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
+ if (lck->data->old_write_time != nt) {
lck->data->modified = True;
- lck->data->old_write_time = write_time;
+ lck->data->old_write_time = nt;
}
TALLOC_FREE(lck);
{
struct share_mode_data *d = lck->data;
- if (!null_timespec(d->changed_write_time)) {
- return d->changed_write_time;
+ if (!null_nttime(d->changed_write_time)) {
+ return nt_time_to_full_timespec(d->changed_write_time);
}
- return d->old_write_time;
+ return nt_time_to_full_timespec(d->old_write_time);
}
struct file_has_open_streams_state {
if (d->servicepath == NULL) {
goto fail;
}
- d->old_write_time = *old_write_time;
+ d->old_write_time = full_timespec_to_nt_time(old_write_time);
d->modified = false;
d->fresh = true;
return d;
int result;
int mask = 0;
- if (!null_timespec(ft->atime)) {
+ if (!is_omit_timespec(&ft->atime)) {
stx.stx_atime = ft->atime;
mask |= CEPH_SETATTR_ATIME;
}
- if (!null_timespec(ft->mtime)) {
+ if (!is_omit_timespec(&ft->mtime)) {
stx.stx_mtime = ft->mtime;
mask |= CEPH_SETATTR_MTIME;
}
- if (!null_timespec(ft->create_time)) {
+ if (!is_omit_timespec(&ft->create_time)) {
stx.stx_btime = ft->create_time;
mask |= CEPH_SETATTR_BTIME;
}
struct utimbuf buf;
int result;
- if (null_timespec(ft->atime)) {
+ if (is_omit_timespec(&ft->atime)) {
buf.actime = smb_fname->st.st_ex_atime.tv_sec;
} else {
buf.actime = ft->atime.tv_sec;
}
- if (null_timespec(ft->mtime)) {
+ if (is_omit_timespec(&ft->mtime)) {
buf.modtime = smb_fname->st.st_ex_mtime.tv_sec;
} else {
buf.modtime = ft->mtime.tv_sec;
}
- if (!null_timespec(ft->create_time)) {
+ if (!is_omit_timespec(&ft->create_time)) {
set_create_timespec_ea(handle->conn, smb_fname,
ft->create_time);
}
}
if (ft != NULL) {
- if (null_timespec(ft->atime)) {
+ if (is_omit_timespec(&ft->atime)) {
ft->atime= smb_fname->st.st_ex_atime;
}
- if (null_timespec(ft->mtime)) {
+ if (is_omit_timespec(&ft->mtime)) {
ft->mtime = smb_fname->st.st_ex_mtime;
}
- if (!null_timespec(ft->create_time)) {
+ if (!is_omit_timespec(&ft->create_time)) {
set_create_timespec_ea(handle->conn,
smb_fname,
ft->create_time);
return -1);
if ((config->meta != FRUIT_META_NETATALK) ||
- null_timespec(ft->create_time))
+ is_omit_timespec(&ft->create_time))
{
return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
}
START_PROFILE(syscall_ntimes);
- if (null_timespec(ft->atime)) {
+ if (is_omit_timespec(&ft->atime)) {
times[0].tv_sec = smb_fname->st.st_ex_atime.tv_sec;
times[0].tv_nsec = smb_fname->st.st_ex_atime.tv_nsec;
} else {
times[0].tv_nsec = ft->atime.tv_nsec;
}
- if (null_timespec(ft->mtime)) {
+ if (is_omit_timespec(&ft->mtime)) {
times[1].tv_sec = smb_fname->st.st_ex_mtime.tv_sec;
times[1].tv_nsec = smb_fname->st.st_ex_mtime.tv_nsec;
} else {
static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt,
int idx, int *flags)
{
- if (!null_timespec(ts)) {
+ if (!is_omit_timespec(&ts)) {
*flags |= 1 << idx;
gt[idx].tv_sec = ts.tv_sec;
gt[idx].tv_nsec = ts.tv_nsec;
return -1;
}
- if(null_timespec(ft->create_time)){
+ if (is_omit_timespec(&ft->create_time)){
DEBUG(10,("vfs_gpfs_ntimes:Create Time is NULL\n"));
return 0;
}
struct smb_file_time ft;
int ret, err;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
if (smb_fname_tmp == NULL) {
}
if (fsp->write_time_forced) {
+ struct timespec ts;
+
DEBUG(10,("close_remove_share_mode: write time forced "
"for file %s\n",
fsp_str_dbg(fsp)));
- set_close_write_time(fsp, lck->data->changed_write_time);
+ ts = nt_time_to_full_timespec(lck->data->changed_write_time);
+ set_close_write_time(fsp, ts);
} else if (fsp->update_write_time_on_close) {
/* Someone had a pending write. */
- if (null_timespec(fsp->close_write_time)) {
+ if (is_omit_timespec(&fsp->close_write_time)) {
DEBUG(10,("close_remove_share_mode: update to current time "
"for file %s\n",
fsp_str_dbg(fsp)));
{
DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
- if (null_timespec(ts)) {
+ if (is_omit_timespec(&ts)) {
return;
}
fsp->write_time_forced = false;
NTSTATUS status;
struct share_mode_lock *lck = NULL;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (!fsp->update_write_time_on_close) {
return NT_STATUS_OK;
}
- if (null_timespec(fsp->close_write_time)) {
+ if (is_omit_timespec(&fsp->close_write_time)) {
fsp->close_write_time = timespec_current();
}
/* Close write times overwrite sticky write times
so we must replace any sticky write time here. */
- if (!null_timespec(lck->data->changed_write_time)) {
+ if (!null_nttime(lck->data->changed_write_time)) {
(void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
}
TALLOC_FREE(lck);
fileid = vfs_file_id_from_sbuf(conn,
&smb_fname.st);
get_file_infos(fileid, 0, NULL, &write_time_ts);
- if (!null_timespec(write_time_ts)) {
+ if (!is_omit_timespec(&write_time_ts)) {
update_stat_ex_mtime(&smb_fname.st,
write_time_ts);
}
if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
!null_nttime(dosattrib.info.info3.create_time)) {
struct timespec create_time =
- nt_time_to_unix_timespec(
+ nt_time_to_full_timespec(
dosattrib.info.info3.create_time);
update_stat_ex_create_time(&smb_fname->st,
{
struct timespec creat_time;
- creat_time = nt_time_to_unix_timespec(info->create_time);
+ creat_time = nt_time_to_full_timespec(info->create_time);
update_stat_ex_create_time(&smb_fname->st, creat_time);
DBG_DEBUG("file [%s] creation time [%s]\n",
dosattrib.info.info4.valid_flags = XATTR_DOSINFO_ATTRIB |
XATTR_DOSINFO_CREATE_TIME;
dosattrib.info.info4.attrib = dosmode;
- dosattrib.info.info4.create_time = unix_timespec_to_nt_time(
- smb_fname->st.st_ex_btime);
+ dosattrib.info.info4.create_time = full_timespec_to_nt_time(
+ &smb_fname->st.st_ex_btime);
if (!(smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) {
dosattrib.info.info4.valid_flags |= XATTR_DOSINFO_ITIME;
- dosattrib.info.info4.itime = unix_timespec_to_nt_time(
- smb_fname->st.st_ex_itime);
+ dosattrib.info.info4.itime = full_timespec_to_nt_time(
+ &smb_fname->st.st_ex_itime);
}
DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime)
{
- if (null_timespec(mtime)) {
+ if (is_omit_timespec(&mtime)) {
return true;
}
bool set_sticky_write_time_fsp(struct files_struct *fsp, struct timespec mtime)
{
- if (null_timespec(mtime)) {
+ if (is_omit_timespec(&mtime)) {
return true;
}
cookie.update_write_time_triggered = fsp->update_write_time_triggered;
cookie.update_write_time_on_close = fsp->update_write_time_on_close;
cookie.write_time_forced = fsp->write_time_forced;
- cookie.close_write_time = fsp->close_write_time;
+ cookie.close_write_time = full_timespec_to_nt_time(
+ &fsp->close_write_time);
cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
if (lck != NULL) {
struct smb_file_time ft;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (fsp->write_time_forced) {
- ft.mtime = lck->data->changed_write_time;
+ ft.mtime = nt_time_to_full_timespec(
+ lck->data->changed_write_time);
} else if (fsp->update_write_time_on_close) {
- if (null_timespec(fsp->close_write_time)) {
+ if (is_omit_timespec(&fsp->close_write_time)) {
ft.mtime = timespec_current();
} else {
ft.mtime = fsp->close_write_time;
}
}
- if (!null_timespec(ft.mtime)) {
+ if (!is_omit_timespec(&ft.mtime)) {
round_timespec(conn->ts_res, &ft.mtime);
file_ntimes(conn, fsp->fsp_name, &ft);
}
cookie.update_write_time_triggered = fsp->update_write_time_triggered;
cookie.update_write_time_on_close = fsp->update_write_time_on_close;
cookie.write_time_forced = fsp->write_time_forced;
- cookie.close_write_time = fsp->close_write_time;
+ cookie.close_write_time = full_timespec_to_nt_time(
+ &fsp->close_write_time);
cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
fsp->update_write_time_triggered = cookie.update_write_time_triggered;
fsp->update_write_time_on_close = cookie.update_write_time_on_close;
fsp->write_time_forced = cookie.write_time_forced;
- fsp->close_write_time = cookie.close_write_time;
+ fsp->close_write_time = nt_time_to_full_timespec(
+ cookie.close_write_time);
status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
{
struct smb_file_time ft;
+ init_smb_file_time(&ft);
+
if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
/* Don't use delayed writes on POSIX files. */
return;
fsp->update_write_time_triggered = true;
fsp->update_write_time_on_close = false;
- ft = (struct smb_file_time) { .mtime = timespec_current() };
+ ft.mtime = timespec_current();
/* Update the time in the open file db. */
(void)set_write_time(fsp->file_id, ft.mtime);
fsp->fnum = FNUM_FIELD_INVALID;
fsp->conn = conn;
+ fsp->close_write_time = make_omit_timespec();
DLIST_ADD(sconn->files, fsp);
sconn->num_files += 1;
*/
struct timespec write_time = get_share_mode_write_time(lck);
- if (!null_timespec(write_time)) {
+ if (!is_omit_timespec(&write_time)) {
update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
}
}
we only update timestamps on file writes.
See bug #9870.
*/
- ZERO_STRUCT(mtimespec);
+ mtimespec = make_omit_timespec();
#ifdef O_DIRECTORY
status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
*/
struct timespec write_time = get_share_mode_write_time(lck);
- if (!null_timespec(write_time)) {
+ if (!is_omit_timespec(&write_time)) {
update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
}
}
ZERO_STRUCT(write_time_ts);
fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, 0, NULL, &write_time_ts);
- if (!null_timespec(write_time_ts)) {
+ if (!is_omit_timespec(&write_time_ts)) {
update_stat_ex_mtime(&smb_fname->st, write_time_ts);
}
}
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsetatr);
+ init_smb_file_time(&ft);
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
}
}
- ft = (struct smb_file_time) {
- .mtime = convert_time_t_to_timespec(mtime)
- };
+ ft.mtime = time_t_to_full_timespec(mtime);
status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBcreate);
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
}
/* mtime. */
- ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
+ ft.mtime = time_t_to_full_timespec(srv_make_unix_date3(req->vwv+1));
srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
STR_TERMINATE, &status);
*/
t = srv_make_unix_date3(req->vwv+1);
- set_close_write_time(fsp, convert_time_t_to_timespec(t));
+ set_close_write_time(fsp, time_t_to_full_timespec(t));
}
if (fsp->num_aio_requests != 0) {
numtowrite = SVAL(req->vwv+1, 0);
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
- mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
+ mtime = time_t_to_full_timespec(srv_make_unix_date3(req->vwv+4));
data = (const char *)req->buf + 1;
/*
NTSTATUS status;
START_PROFILE(SMBsetattrE);
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (req->wct < 7) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
* Convert the DOS times into unix times.
*/
- ft.atime = convert_time_t_to_timespec(
+ ft.atime = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+3));
- ft.mtime = convert_time_t_to_timespec(
+ ft.mtime = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+5));
- ft.create_time = convert_time_t_to_timespec(
+ ft.create_time = time_t_to_full_timespec(
srv_make_unix_date2(req->vwv+1));
reply_outbuf(req, 0, 0);
if (state->mxac != NULL) {
NTTIME last_write_time;
- last_write_time = unix_timespec_to_nt_time(
- state->result->fsp_name->st.st_ex_mtime);
+ last_write_time = full_timespec_to_nt_time(
+ &state->result->fsp_name->st.st_ex_mtime);
if (last_write_time != state->max_access_time) {
uint8_t p[8];
uint32_t max_access_granted;
write_time = get_share_mode_write_time(lck);
TALLOC_FREE(lck);
- if (null_timespec(write_time)) {
+ if (is_omit_timespec(&write_time)) {
tevent_req_done(req);
return;
}
#include "includes.h"
#include "ntioctl.h"
#include "system/filesys.h"
+#include "lib/util/time_basic.h"
#include "version.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
dstart = pdata;
dend = dstart + data_size - 1;
- if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
+ if (!is_omit_timespec(&write_time_ts) &&
+ !INFO_LEVEL_IS_UNIX(info_level))
+ {
update_stat_ex_mtime(psbuf, write_time_ts);
}
bool setting_write_time)
{
struct smb_filename smb_fname_base;
+ struct timeval_buf tbuf[4];
uint32_t action =
FILE_NOTIFY_CHANGE_LAST_ACCESS
|FILE_NOTIFY_CHANGE_LAST_WRITE
}
/* get some defaults (no modifications) if any info is zero or -1. */
- if (null_timespec(ft->create_time)) {
+ if (is_omit_timespec(&ft->create_time)) {
action &= ~FILE_NOTIFY_CHANGE_CREATION;
}
- if (null_timespec(ft->atime)) {
+ if (is_omit_timespec(&ft->atime)) {
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
- if (null_timespec(ft->mtime)) {
+ if (is_omit_timespec(&ft->mtime)) {
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
round_timespec(conn->ts_res, &ft->atime);
round_timespec(conn->ts_res, &ft->mtime);
- DEBUG(5,("smb_set_filetime: actime: %s\n ",
- time_to_asc(convert_timespec_to_time_t(ft->atime))));
- DEBUG(5,("smb_set_filetime: modtime: %s\n ",
- time_to_asc(convert_timespec_to_time_t(ft->mtime))));
- DEBUG(5,("smb_set_filetime: ctime: %s\n ",
- time_to_asc(convert_timespec_to_time_t(ft->ctime))));
- DEBUG(5,("smb_set_file_time: createtime: %s\n ",
- time_to_asc(convert_timespec_to_time_t(ft->create_time))));
+ DBG_DEBUG("smb_set_filetime: actime: %s\n ",
+ timespec_string_buf(&ft->atime, true, &tbuf[0]));
+ DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
+ timespec_string_buf(&ft->mtime, true, &tbuf[1]));
+ DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
+ timespec_string_buf(&ft->ctime, true, &tbuf[2]));
+ DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
+ timespec_string_buf(&ft->create_time, true, &tbuf[3]));
if (setting_write_time) {
/*
* away and will set it on file close and after a write. JRA.
*/
- DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
- time_to_asc(convert_timespec_to_time_t(ft->mtime))));
+ DBG_DEBUG("setting pending modtime to %s\n",
+ timespec_string_buf(&ft->mtime, true, &tbuf[0]));
if (fsp != NULL) {
if (fsp->base_fsp) {
uint32_t dosmode = 0;
NTSTATUS status = NT_STATUS_OK;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (total_data < 36) {
return NT_STATUS_INVALID_PARAMETER;
NTSTATUS status;
struct smb_file_time ft;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (total_data < 12) {
return NT_STATUS_INVALID_PARAMETER;
}
/* create time */
- ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
+ ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
/* access time */
- ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
+ ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
/* write time */
- ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
+ ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
DEBUG(10,("smb_set_info_standard: file %s\n",
smb_fname_str_dbg(smb_fname)));
struct file_id id;
SMB_STRUCT_STAT sbuf;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
if (total_data < 100) {
return NT_STATUS_INVALID_PARAMETER;
}
/* Deal with any time changes. */
- if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
+ if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
/* No change, don't cancel anything. */
return status;
}
* we need. Just remember if we modified
* mtime and send the notify ourselves.
*/
- if (null_timespec(ft.mtime)) {
+ if (is_omit_timespec(&ft.mtime)) {
modify_mtime = false;
}
return NT_STATUS_OK;
}
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
- ft.atime = convert_time_t_to_timespec(atoi(argv[2]));
- ft.mtime = convert_time_t_to_timespec(atoi(argv[3]));
+ ft.atime = time_t_to_full_timespec(atoi(argv[2]));
+ ft.mtime = time_t_to_full_timespec(atoi(argv[3]));
smb_fname = synthetic_smb_fname_split(mem_ctx,
argv[1],