Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions netmount-server/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ uint32_t time_to_fat(time_t t) {
return res;
}

time_t fat_to_time(uint32_t date_time) {
struct tm ltime;
ltime.tm_isdst = -1;
ltime.tm_sec = (date_time & 0x1f) * 2;
date_time >>= 5;
ltime.tm_min = date_time & 0x3f;
date_time >>= 6;
ltime.tm_hour = date_time & 0x1f;
date_time >>= 5;
ltime.tm_mday = date_time & 0x1f;
date_time >>= 5;
ltime.tm_mon = (date_time & 0x0f) - 1;
date_time >>= 4;
ltime.tm_year = date_time + 80;
return mktime(&ltime);
}

} // namespace


Expand Down Expand Up @@ -362,6 +379,14 @@ int32_t Drive::get_file_size(uint16_t handle) {
}


void Drive::set_file_date_time(uint16_t handle, uint32_t date_time) {
auto & item = get_item(handle);
auto file_time = std::chrono::file_clock::from_sys(std::chrono::system_clock::from_time_t(fat_to_time(date_time)));
std::filesystem::last_write_time(item.path, file_time);
item.update_last_used_timestamp();
}


bool Drive::find_file(
uint16_t handle, const fcb_file_name & tmpl, unsigned char attr, DosFileProperties & properties, uint16_t & nth) {

Expand Down
3 changes: 3 additions & 0 deletions netmount-server/fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ class Drive {
/// Returns the size of file defined by handle (or -1 on error)
int32_t get_file_size(uint16_t handle);

/// Throws exception on error
void set_file_date_time(uint16_t handle, uint32_t date_time);

/// Searches for files matching template `tmpl` in directory defined by `handle`
/// with at most attributes `attr`.
/// Fills in `properties` with the next match after `nth` and updates `nth`
Expand Down
15 changes: 11 additions & 4 deletions netmount-server/netmount-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,22 @@ int process_request(ReplyCache::ReplyInfo & reply_info, const uint8_t * request_
}

case INT2F_CLOSE_FILE: {
if (request_data_len != sizeof(drive_proto_closef)) {
auto * const request = reinterpret_cast<const drive_proto_closef *>(request_data);
uint32_t date_time = 0;
if (request_data_len == sizeof(drive_proto_closef)) {
date_time = from_little32(request->date_time);
} else if (request_data_len != sizeof(drive_proto_closef) - sizeof(uint32_t)) {
return -1;
}
// Only checking the existence of the handle because I don't keep files open.
auto * const request = reinterpret_cast<const drive_proto_closef *>(request_data);
const uint16_t handle = from_little16(request->start_cluster);
log(LogLevel::DEBUG, "CLOSE_FILE handle {}\n", handle);
log(LogLevel::DEBUG, "CLOSE_FILE handle {} {:08X}\n", handle, date_time);
try {
drive.get_handle_path(handle);
if (date_time != 0) {
drive.set_file_date_time(handle, date_time);
} else {
drive.get_handle_path(handle);
}
} catch (const std::runtime_error & ex) {
log(LogLevel::WARNING, "CLOSE_FILE handle {}: {}\n", handle, ex.what());
// TODO: Send error to client?
Expand Down
8 changes: 6 additions & 2 deletions netmount/netmount.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,11 @@ static void handle_request_for_our_drive(void) {

struct drive_proto_closef * const args = (struct drive_proto_closef * const)buff;
args->start_cluster = sftptr->start_cluster;
if (sftptr->start_file_time != sftptr->file_time) {
args->date_time = sftptr->file_time;
} else {
args->date_time = 0;
}
if (send_request(subfunction, reqdrv, sizeof(*args), &reply, &ax) == 0) {
if (ax != 0) {
set_error(r, ax);
Expand Down Expand Up @@ -1359,8 +1364,7 @@ static void handle_request_for_our_drive(void) {
sft_ptr->file_pos = 0;
sft_ptr->open_mode &= 0xFF00U;
sft_ptr->open_mode |= args->mode;
sft_ptr->rel_sector = 0xFFFFU;
sft_ptr->abs_sector = 0xFFFFU;
sft_ptr->start_file_time = args->date_time;
sft_ptr->dir_sector = 0;
sft_ptr->dir_entry_no = 0xFF; // why such value? no idea, EtherDFS says PHANTON.C uses that
sft_ptr->file_name = args->name;
Expand Down
9 changes: 7 additions & 2 deletions shared/dos.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,13 @@ struct dos_sft {
uint32_t file_time; // file date and time
uint32_t file_size; // file length
uint32_t file_pos; // current file position
uint16_t rel_sector;
uint16_t abs_sector;
union {
struct {
uint16_t rel_sector;
uint16_t abs_sector;
};
uint32_t start_file_time;
};
uint16_t dir_sector;
uint8_t dir_entry_no; // if local, number of directory entry within sector
struct fcb_file_name file_name;
Expand Down
1 change: 1 addition & 0 deletions shared/drvproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct drive_proto_hdr {

struct drive_proto_closef {
uint16_t start_cluster;
uint32_t date_time;
};


Expand Down