smb_file *smb_session_file_remove(smb_session *s, smb_fd fd) { smb_share *share; smb_file *iter, *keep; assert(s != NULL && fd); if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL) return (NULL); iter = share->files; if (iter == NULL) return (NULL); if (iter->fid == SMB_FD_FID(fd)) { share->files = iter->next; return (iter); } while(iter->next != NULL && iter->next->fid != SMB_FD_TID(fd)) iter = iter->next; if (iter->next != NULL) { keep = iter->next; iter->next = iter->next->next; return (keep); } else return (NULL); }
smb_file *smb_session_file_get(smb_session *s, smb_fd fd) { smb_share *share; smb_file *iter; assert(s != NULL && fd); if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL) return (NULL); iter = share->files; while(iter != NULL && iter->fid != SMB_FD_FID(fd)) iter = iter->next; return (iter); }
void smb_fclose(smb_session *s, smb_fd fd) { smb_file *file; smb_message *msg; smb_close_req req; assert(s != NULL); if (!fd) return; // XXX Memory leak, destroy the file after removing it if ((file = smb_session_file_remove(s, fd)) == NULL) return; msg = smb_message_new(SMB_CMD_CLOSE); if (!msg) { free(file->name); free(file); return; } msg->packet->header.tid = SMB_FD_TID(fd); SMB_MSG_INIT_PKT(req); req.wct = 3; req.fid = SMB_FD_FID(fd); req.last_write = ~0; req.bct = 0; SMB_MSG_PUT_PKT(msg, req); // We don't check for succes or failure, since we actually don't really // care about creating a potentiel leak server side. smb_session_send_msg(s, msg); smb_session_recv_msg(s, 0); smb_message_destroy(msg); free(file->name); free(file); }