diff --git a/documentation/history.doc b/documentation/history.doc index 012ec66..da59e9b 100644 --- a/documentation/history.doc +++ b/documentation/history.doc @@ -2836,3 +2836,30 @@ smbfs 2.11 (31.12.2018) - The non-debug builds of smbfs now complain again if any of the debug parameters are being used. + + +smbfs 2.12 (5.1.2019) + +- Found a couple more cases in which debug output did not use the + correct parameter information. This happened, for example, in the + SMB write operation (which did not correctly report the 64 bit + seek offset) and the ACTION_SET_COMMENT implementation which + did not print the comment string correctly. + +- Added a proper string length limit check for the text buffers + used by the DateToStr() function. + +- Enabled profiling support for SAS/C to learn more about the + most frequently-used functions and their respective running + times. Added inline qualifiers to these functions, or copied + the respective function to where it was called, allowing it + to be inlined. + +- The main file system processing loop no longer calls WaitSelect() + every time it needs to wait for a new packet to arrive, or for + a NetBIOS "keep alive" message to come along. It now defaults to + calling Wait(), which has a much lower overhead than WaitSelect(). + However, periodic calls to WaitSelect() and the associated NetBIOS + "keep alive" handling are scheduled regularly every 10 seconds. + That way the "keep alive" messages are dealt with without spending + too much time with WaitSelect(). diff --git a/source_code/assert.h b/source_code/assert.h index 3bb3789..9b194ea 100644 --- a/source_code/assert.h +++ b/source_code/assert.h @@ -110,8 +110,8 @@ void _LEAVE(const char *file,int line,const char *function); void _RETURN(const char *file,int line,const char *function,unsigned long result); void _DPRINTF_HEADER(const char *file,int line); - void VARARGS68K _DPRINTF(const char *format,...); - void VARARGS68K _DLOG(const char *format,...); + void VARARGS68K _DPRINTF(const char *format,...) __attribute__ ((format (printf, 1, 2))); + void VARARGS68K _DLOG(const char *format,...) __attribute__ ((format (printf, 1, 2))); void _SETDEBUGFILE(BPTR file); int _SETDEBUGLEVEL(int level); void _PUSHDEBUGLEVEL(int level); diff --git a/source_code/include/smb/smb_fs.h b/source_code/include/smb/smb_fs.h index 181f705..934c134 100644 --- a/source_code/include/smb/smb_fs.h +++ b/source_code/include/smb/smb_fs.h @@ -52,8 +52,6 @@ struct smb_lkrng /*****************************************************************************/ /* proc.c */ -byte *smb_encode_smb_length(byte *p, int len); -int smb_len(const byte *packet); void smb_translate_error_class_and_code(int errcls,int error,char ** class_ptr,char ** code_ptr); int smb_errno(int errcls, int error); int smb_payload_size(const struct smb_server *server, int wct, int bcc); diff --git a/source_code/main.c b/source_code/main.c index 1c4f72d..d339e4a 100644 --- a/source_code/main.c +++ b/source_code/main.c @@ -298,7 +298,9 @@ struct IconIFace * IIcon; /****************************************************************************/ -struct timerequest TimerRequest; +struct timerequest * TimerRequest; +struct MsgPort * TimerPort; +BOOL TimerTicking; /****************************************************************************/ @@ -311,6 +313,10 @@ int h_errno; /****************************************************************************/ +int profile_nest_count; + +/****************************************************************************/ + static struct DosList * DeviceNode; static BOOL DeviceNodeAdded; static struct DosList * VolumeNode; @@ -504,6 +510,14 @@ _start(STRPTR args, LONG args_length, struct ExecBase * exec_base) */ #else { + #if defined(__SASC) && defined(_PROFILE) && _PROFILE + { + extern int __stdargs _STI_150_Sprof(void); + + _STI_150_Sprof(); + } + #endif + /* Not enough stack size available? */ if(get_stack_size() < minimum_stack_size) { @@ -543,6 +557,14 @@ _start(STRPTR args, LONG args_length, struct ExecBase * exec_base) { result = main(); } + + #if defined(__SASC) && defined(_PROFILE) && _PROFILE + { + extern void __stdargs _STD_150_Sprof(void); + + _STD_150_Sprof(); + } + #endif } #endif /* __amigaos4__ */ @@ -1300,7 +1322,7 @@ main(void) { if(GetVar("smbfs_password",env_password,sizeof(env_password),0) > 0) { - D(("using PASSWORD=... stored in 'smbfs_password' environment variable.")); + SHOWMSG("using PASSWORD=... stored in 'smbfs_password' environment variable."); args.Password = env_password; } @@ -1532,9 +1554,9 @@ main(void) D(("change user name case = %s", get_switch_status(args.ChangeUserNameCase, TRUE) ? "yes" : "no")); if(args.Password != NULL) - D(("password = ...")); + SHOWMSG("password = ..."); else - D(("password = empty")); + SHOWMSG("password = empty"); D(("change password case = %s", get_switch_status(args.ChangePasswordCase, FALSE) ? "yes" : "no")); D(("unicode = '%s'", args.Unicode)); @@ -1810,8 +1832,12 @@ posix_strerror(int error) tags[0].ti_Data = error; tags[1].ti_Tag = TAG_END; + PROFILE_OFF(); + SocketBaseTagList(tags); + PROFILE_ON(); + result = (STRPTR)tags[0].ti_Data; } @@ -1831,8 +1857,12 @@ host_strerror(int error) tags[0].ti_Data = error; tags[1].ti_Tag = TAG_END; + PROFILE_OFF(); + SocketBaseTagList(tags); + PROFILE_ON(); + result = (STRPTR)tags[0].ti_Data; return(result); @@ -2143,7 +2173,7 @@ allocate_memory(LONG size) { ULONG * mem; - size = (sizeof(*mem) + size + 7) & ~7UL; + size = sizeof(*mem) + ((size + 7) & ~7UL); mem = AllocPooled(MemoryPool,size); if(mem != NULL) @@ -2543,6 +2573,8 @@ BroadcastNameQuery(const char *name, const char *scope, UBYTE *address) ENTER(); + PROFILE_OFF(); + sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sock_fd < 0) { @@ -2676,6 +2708,8 @@ BroadcastNameQuery(const char *name, const char *scope, UBYTE *address) if(sock_fd >= 0) CloseSocket(sock_fd); + PROFILE_ON(); + RETURN(result); return(result); } @@ -2733,6 +2767,8 @@ SendNetBIOSStatusQuery( ENTER(); + PROFILE_OFF(); + if(server_name != NULL && server_name_size > 0) { server_name_size--; @@ -2965,6 +3001,8 @@ SendNetBIOSStatusQuery( if(sock_fd >= 0) CloseSocket(sock_fd); + PROFILE_ON(); + RETURN(result); return(result); } @@ -2984,6 +3022,8 @@ send_disk_change_notification(ULONG class) ENTER(); + PROFILE_OFF(); + input_port = CreateMsgPort(); if(input_port == NULL) goto out; @@ -3020,6 +3060,8 @@ send_disk_change_notification(ULONG class) DeleteMsgPort(input_port); + PROFILE_ON(); + LEAVE(); } @@ -3054,7 +3096,7 @@ find_file_node_by_name(const TEXT * name,const struct FileNode * skip) if(result != NULL) D(("found it (= 0x%08lx)", result)); else - D(("didn't find it")); + SHOWMSG("didn't find it"); } #else { @@ -3077,26 +3119,26 @@ find_file_node_by_name(const TEXT * name,const struct FileNode * skip) { result = fn; - D(("found it (= 0x%08lx)", result)); + D(("found it (= 0x%08lx)", (ULONG)result)); } /* Use the next entry in the list, if possible. */ else if (sn->sn_next != NULL) { result = (struct FileNode *)sn->sn_next->sn_userdata; - D(("found it, but can't use it, so using the next best entry (= 0x%08lx)", result)); + D(("found it, but can't use it, so using the next best entry (= 0x%08lx)", (ULONG)result)); if(result == NULL) - D(("...but didn't actually find it")); + SHOWMSG("...but didn't actually find it"); } else { - D(("didn't find it")); + SHOWMSG("didn't find it"); } } else { - D(("didn't find it")); + SHOWMSG("didn't find it"); } } #endif /* USE_SPLAY_TREE */ @@ -3131,7 +3173,7 @@ find_lock_node_by_name(const TEXT * name,const struct LockNode * skip) if(result != NULL) D(("found it (= 0x%08lx)", result)); else - D(("didn't find it")); + SHOWMSG("didn't find it"); } #else { @@ -3150,25 +3192,25 @@ find_lock_node_by_name(const TEXT * name,const struct LockNode * skip) { result = ln; - D(("found it (= 0x%08lx)", result)); + D(("found it (= 0x%08lx)", (ULONG)result)); } else if (sn->sn_next != NULL) { result = (struct LockNode *)sn->sn_next->sn_userdata; - D(("found it, but can't use it, so using the next best entry (= 0x%08lx)", result)); + D(("found it, but can't use it, so using the next best entry (= 0x%08lx)", (ULONG)result)); if(result == NULL) - D(("...but didn't actually find it")); + SHOWMSG("...but didn't actually find it"); } else { - D(("didn't find it")); + SHOWMSG("didn't find it"); } } else { - D(("didn't find it")); + SHOWMSG("didn't find it"); } } #endif /* USE_SPLAY_TREE */ @@ -3285,7 +3327,7 @@ path_name_is_invalid(const TEXT * name, int name_len) for(i = 0 ; i < name_len ; i++) { c = name[i]; - + if(c < ' ' || strchr("<>\"\\|?*", c) != NULL) goto out; } @@ -3613,7 +3655,11 @@ really_remove_dosentry(struct DosList * entry) reject_all_pending_packets(port); + PROFILE_OFF(); + Delay(TICKS_PER_SECOND / 10); + + PROFILE_ON(); } if(NO success) @@ -3633,6 +3679,8 @@ cleanup(void) ENTER(); + PROFILE_OFF(); + /* If any errors have cropped up, display them now before * we call it quits. */ @@ -3743,12 +3791,27 @@ cleanup(void) } #endif /* __amigaos4__ */ - if(TimerBase != NULL) + if(TimerRequest != NULL) { - CloseDevice((struct IORequest *)&TimerRequest); - TimerBase = NULL; + if(TimerTicking) + { + if(CheckIO((struct IORequest *)TimerRequest) == NULL) + AbortIO((struct IORequest *)TimerRequest); + + WaitIO((struct IORequest *)TimerRequest); + TimerTicking = FALSE; + } + + if(TimerRequest->tr_node.io_Device != NULL) + CloseDevice((struct IORequest *)TimerRequest); + + DeleteIORequest((struct IORequest *)TimerRequest); + TimerRequest = NULL; } + if(TimerPort != NULL) + DeleteMsgPort(TimerPort); + #if defined(__amigaos4__) { if(ISocket != NULL) @@ -3809,6 +3872,8 @@ cleanup(void) MemoryPool = NULL; } + PROFILE_ON(); + LEAVE(); } @@ -3884,6 +3949,8 @@ setup( ENTER(); + PROFILE_OFF(); + NewList((struct List *)&FileList); NewList((struct List *)&LockList); @@ -3950,26 +4017,27 @@ setup( SHOWVALUE(DSTOffset); } - memset(&TimerRequest,0,sizeof(TimerRequest)); + TimerPort = CreateMsgPort(); + if(TimerPort != NULL) + TimerRequest = (struct timerequest *)CreateIORequest(TimerPort, sizeof(*TimerRequest)); - if(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)&TimerRequest,0) != OK) + if(TimerRequest == NULL || OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerRequest,0) != OK) { report_error("Could not open 'timer.device'."); goto out; } - TimerBase = (struct Library *)TimerRequest.tr_node.io_Device; + TimerBase = (struct Library *)TimerRequest->tr_node.io_Device; #if defined(__amigaos4__) { - if(TimerBase != NULL) + ASSERT(TimerBase != NULL); + + ITimer = (struct TimerIFace *)GetInterface(TimerBase, "main", 1, 0); + if(ITimer == NULL) { - ITimer = (struct TimerIFace *)GetInterface(TimerBase, "main", 1, 0); - if(ITimer == NULL) - { - report_error("Could not open 'timer.device'."); - goto out; - } + report_error("Could not open 'timer.device'."); + goto out; } } #endif /* __amigaos4__ */ @@ -4002,6 +4070,7 @@ setup( SBTM_SETVAL(SBTC_LOGTAGPTR), program_name, SBTM_SETVAL(SBTC_BREAKMASK), SIGBREAKF_CTRL_C, TAG_END); + if(error != OK) { report_error("Could not initialize 'bsdsocket.library' (%ld, %s).",error,posix_strerror(error)); @@ -4281,6 +4350,8 @@ setup( out: + PROFILE_ON(); + RETURN(result); return(result); } @@ -4771,12 +4842,12 @@ build_full_path_name( ENTER(); if(parent_name == NULL) - D(("parent name = NULL")); + SHOWMSG("parent name = NULL"); else D(("parent name = '%s'",escape_name(parent_name))); if(name == NULL) - D(("name = NULL")); + SHOWMSG("name = NULL"); else D(("name = '%s'",escape_name(name))); @@ -4873,11 +4944,14 @@ build_full_path_name( if(name_changed) { TEXT printable_name[MAX_FILENAME_LEN+1]; + int l; - ASSERT( name_len < (int)sizeof(printable_name) ); + l = name_len; + if(l >= (int)sizeof(printable_name)) + l = sizeof(printable_name)-1; - memmove(printable_name, name, name_len); - printable_name[name_len] = '\0'; + memmove(printable_name, name, l); + printable_name[l] = '\0'; D(("name changed to '%s'",escape_name(printable_name))); } @@ -4979,7 +5053,7 @@ build_full_path_name( /* Can't go any further. */ else { - D(("can't go any further up in the path")); + SHOWMSG("can't go any further up in the path"); error = ERROR_OBJECT_NOT_FOUND; goto out; @@ -5560,7 +5634,7 @@ get_parent_name( ASSERT( error_ptr != NULL ); - SHOWVALUE(parent); + SHOWPOINTER(parent); if(parent != NULL) { @@ -5579,7 +5653,7 @@ get_parent_name( } else { - D(("parent lock on ':' (ZERO lock)")); + SHOWMSG("parent lock on ':' (ZERO lock)"); name = NULL; } @@ -5610,7 +5684,7 @@ Action_Parent( ENTER(); - SHOWVALUE(parent); + SHOWPOINTER(parent); if(file_system_disabled) { @@ -5650,7 +5724,7 @@ Action_Parent( if(error != ERROR_OBJECT_NOT_FOUND) goto out; - D(("returning ZERO lock")); + SHOWMSG("returning ZERO lock"); } else { @@ -5672,7 +5746,7 @@ Action_Parent( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); full_name = NULL; ln = NULL; @@ -5680,7 +5754,7 @@ Action_Parent( } else { - D(("parent lock on ':' (ZERO lock)")); + SHOWMSG("parent lock on ':' (ZERO lock)"); SHOWMSG("returning ZERO lock"); } @@ -5745,7 +5819,7 @@ Action_DeleteObject( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_OBJECT_NOT_FOUND; goto out; } @@ -5764,7 +5838,7 @@ Action_DeleteObject( /* Trying to delete the root directory, are you kidding? */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot delete the root directory")); + SHOWMSG("cannot delete the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -5928,7 +6002,7 @@ Action_CreateDir( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_INVALID_COMPONENT_NAME; goto out; } @@ -5947,7 +6021,7 @@ Action_CreateDir( /* Trying to overwrite the root directory, are you kidding? */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot overwrite the root directory")); + SHOWMSG("cannot overwrite the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -5999,7 +6073,7 @@ Action_CreateDir( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); full_name = NULL; ln = NULL; @@ -6056,7 +6130,7 @@ Action_LocateObject( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_OBJECT_NOT_FOUND; goto out; } @@ -6092,7 +6166,7 @@ Action_LocateObject( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); SHOWPOINTER(ln->ln_FullName); @@ -6129,7 +6203,7 @@ Action_CopyDir( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); if(file_system_disabled) { @@ -6149,7 +6223,7 @@ Action_CopyDir( } else { - D(("lock on ':' (ZERO lock)")); + SHOWMSG("lock on ':' (ZERO lock)"); } /* If a specific lock is to be duplicated, then that @@ -6207,7 +6281,7 @@ Action_CopyDir( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); full_name = NULL; ln = NULL; @@ -6236,7 +6310,7 @@ Action_FreeLock( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); /* Passing ZERO is harmless. But we have to have * a valid lock if we are to proceed with releasing @@ -6279,18 +6353,18 @@ Action_FreeLock( } #else { - D(("looking up the lock address (what happened to trust?)")); + SHOWMSG("looking up the lock address (what happened to trust?)"); sn = splay_tree_find(&LockAddressTree, (splay_key_t)key); if(sn != NULL) { - D(("found it")); + SHOWMSG("found it"); found = (struct LockNode *)sn->sn_userdata; } else { - D(("didn't find it (this should never happen)")); + SHOWMSG("didn't find it (this should never happen)"); } } #endif /* USE_SPLAY_TREE */ @@ -6311,7 +6385,7 @@ Action_FreeLock( } else { - D(("lock on ':' (ZERO lock)")); + SHOWMSG("lock on ':' (ZERO lock)"); } result = DOSTRUE; @@ -6341,8 +6415,8 @@ Action_SameLock( ENTER(); - SHOWVALUE(lock1); - SHOWVALUE(lock2); + SHOWPOINTER(lock1); + SHOWPOINTER(lock2); if(file_system_disabled) { @@ -6447,7 +6521,7 @@ Action_SetProtect( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_OBJECT_NOT_FOUND; goto out; } @@ -6468,7 +6542,7 @@ Action_SetProtect( */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot change protection bits of the root directory")); + SHOWMSG("cannot change protection bits of the root directory"); error = ERROR_OBJECT_WRONG_TYPE; goto out; @@ -6592,8 +6666,8 @@ Action_RenameObject( D(("source name = '%b'",MKBADDR(source_bcpl_name))); D(("destination name = '%b'",MKBADDR(destination_bcpl_name))); - SHOWVALUE(source_lock); - SHOWVALUE(destination_lock); + SHOWPOINTER(source_lock); + SHOWPOINTER(destination_lock); if(file_system_disabled) { @@ -6612,7 +6686,7 @@ Action_RenameObject( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_OBJECT_NOT_FOUND; goto out; } @@ -6636,7 +6710,7 @@ Action_RenameObject( /* Trying to rename the root directory, are you kidding? */ if(strcmp(full_source_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot rename the root directory")); + SHOWMSG("cannot rename the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -6647,7 +6721,7 @@ Action_RenameObject( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_INVALID_COMPONENT_NAME; goto out; } @@ -6671,7 +6745,7 @@ Action_RenameObject( /* Trying to replace the root directory, are you kidding? */ if(strcmp(full_destination_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot replace the root directory")); + SHOWMSG("cannot replace the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -6833,7 +6907,7 @@ Action_Info( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); if(file_system_disabled) { @@ -6874,7 +6948,7 @@ Action_ExamineObject( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); memset(fib,0,sizeof(*fib)); @@ -6947,7 +7021,7 @@ Action_ExamineObject( error = translate_smb_name_to_amiga_name(translated_name,name_len,sizeof(translated_name)); if(error != OK) { - D(("name is not acceptable")); + SHOWMSG("name is not acceptable"); goto out; } @@ -6959,7 +7033,7 @@ Action_ExamineObject( error = validate_amigados_file_name(name, name_len); if(error != OK) { - D(("name contains unacceptable characters")); + SHOWMSG("name contains unacceptable characters"); goto out; } @@ -7026,7 +7100,7 @@ Action_ExamineObject( } else { - D(("lock on ':' (ZERO lock)")); + SHOWMSG("lock on ':' (ZERO lock)"); } /* So this is actually the root directory? */ @@ -7099,8 +7173,8 @@ Action_ExamineObject( D(("could not convert days=%ld/minutes=%ld/ticks=%ld", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick)); } - ASSERT( strlen(date) < sizeof(date) ); - ASSERT( strlen(time) < sizeof(time) ); + ASSERT( strlen(date) < LEN_DATSTRING ); + ASSERT( strlen(time) < LEN_DATSTRING ); } #endif /* DEBUG */ @@ -7304,8 +7378,8 @@ dir_scan_callback_func_exnext( D((" could not convert days=%ld/minutes=%ld/ticks=%ld", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick)); } - ASSERT( strlen(date) < sizeof(date) ); - ASSERT( strlen(time) < sizeof(time) ); + ASSERT( strlen(date) < LEN_DATSTRING ); + ASSERT( strlen(time) < LEN_DATSTRING ); } #endif /* DEBUG */ @@ -7334,7 +7408,7 @@ Action_ExamineNext( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); if(file_system_disabled) { @@ -7714,8 +7788,8 @@ dir_scan_callback_func_exall( D((" could not convert days=%ld/minutes=%ld/ticks=%ld", ed->ed_Days, ed->ed_Mins, ed->ed_Ticks)); } - ASSERT( strlen(date) < sizeof(date) ); - ASSERT( strlen(time) < sizeof(time) ); + ASSERT( strlen(date) < LEN_DATSTRING ); + ASSERT( strlen(time) < LEN_DATSTRING ); } #endif /* DEBUG */ } @@ -7740,6 +7814,8 @@ dir_scan_callback_func_exall( if(ec->ec_Control->eac_MatchFunc != NULL) { + LONG match; + SHOWMSG(" checking if match function accepts the entry"); /* Note: The order of the parameters passed to the match hook @@ -7758,7 +7834,13 @@ dir_scan_callback_func_exall( * function is given below: 1. match function (hook), * 2. pointer to type, 3. pointer to ExAllData. */ - if(NOT CallHookPkt(ec->ec_Control->eac_MatchFunc,&type,ed)) + PROFILE_OFF(); + + match = CallHookPkt(ec->ec_Control->eac_MatchFunc,&type,ed); + + PROFILE_ON(); + + if(NO match) { SHOWMSG(" match function rejected the entry"); goto out; @@ -7821,7 +7903,7 @@ Action_ExamineAll( ENTER(); - SHOWVALUE(lock); + SHOWPOINTER(lock); SHOWPOINTER(buffer); SHOWVALUE(buffer_size); SHOWVALUE(type); @@ -8214,7 +8296,7 @@ Action_Find( /* Trying to open the root directory? */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot open the root directory")); + SHOWMSG("cannot open the root directory"); error = ERROR_OBJECT_WRONG_TYPE; goto out; @@ -8518,18 +8600,18 @@ Action_End( } #else { - D(("looking up the file address (what happened to trust?)")); + SHOWMSG("looking up the file address (what happened to trust?)"); sn = splay_tree_find(&FileAddressTree, (splay_key_t)which_fn); if(sn != NULL) { - D(("found it")); + SHOWMSG("found it"); found = (struct FileNode *)sn->sn_userdata; } else { - D(("didn't find it (this should never happen)")); + SHOWMSG("didn't find it (this should never happen)"); } } #endif /* USE_SPLAY_TREE */ @@ -8670,7 +8752,7 @@ Action_Seek( /* We cannot seek back beyond the beginning of the file. */ if(compare_64_to_64(&reference_position_quad,&position_quad) < 0) { - D(("cannot seek back beyond the beginning of the file.")); + SHOWMSG("cannot seek back beyond the beginning of the file."); error = ERROR_SEEK_ERROR; goto out; @@ -8683,7 +8765,7 @@ Action_Seek( /* Careful, we need to check for overflow, too. */ if(add_64_plus_32_to_64(&reference_position_quad,position,&new_position_quad) > 0) { - D(("position is too large")); + SHOWMSG("position is too large"); error = ERROR_SEEK_ERROR; goto out; @@ -8871,7 +8953,7 @@ Action_SetDate( if(path_name_is_invalid(name, name_len)) { D(("'%s' is not a valid path name", name)); - + error = ERROR_OBJECT_NOT_FOUND; goto out; } @@ -8890,7 +8972,7 @@ Action_SetDate( /* Trying to change the date of the root directory? */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot change the date of the root directory")); + SHOWMSG("cannot change the date of the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -8934,8 +9016,8 @@ Action_SetDate( D(("could not convert days=%ld/minutes=%ld/ticks=%ld", ds->ds_Days, ds->ds_Minute, ds->ds_Tick)); } - ASSERT( strlen(date) < sizeof(date) ); - ASSERT( strlen(time) < sizeof(time) ); + ASSERT( strlen(date) < LEN_DATSTRING ); + ASSERT( strlen(time) < LEN_DATSTRING ); } #endif /* DEBUG */ @@ -9038,7 +9120,7 @@ Action_ExamineFH( error = translate_smb_name_to_amiga_name(translated_name,name_len,sizeof(translated_name)); if(error != OK) { - D(("name is not acceptable")); + SHOWMSG("name is not acceptable"); goto out; } @@ -9050,7 +9132,7 @@ Action_ExamineFH( error = validate_amigados_file_name(name, name_len); if(error != OK) { - D(("name contains unacceptable characters")); + SHOWMSG("name contains unacceptable characters"); goto out; } @@ -9129,8 +9211,8 @@ Action_ExamineFH( D(("could not convert days=%ld/minutes=%ld/ticks=%ld", fib->fib_Date.ds_Days, fib->fib_Date.ds_Minute, fib->fib_Date.ds_Tick)); } - ASSERT( strlen(date) < sizeof(date) ); - ASSERT( strlen(time) < sizeof(time) ); + ASSERT( strlen(date) < LEN_DATSTRING ); + ASSERT( strlen(time) < LEN_DATSTRING ); } #endif /* DEBUG */ @@ -9193,7 +9275,7 @@ Action_ParentFH( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); parent_dir_name = NULL; ln = NULL; @@ -9267,7 +9349,7 @@ Action_CopyDirFH( add_lock_node(ln); result = MKBADDR(&ln->ln_FileLock); - SHOWVALUE(&ln->ln_FileLock); + SHOWPOINTER(&ln->ln_FileLock); full_name = NULL; ln = NULL; @@ -9299,7 +9381,7 @@ Action_FHFromLock( ENTER(); - SHOWVALUE(fl); + SHOWPOINTER(fl); if(file_system_disabled) { @@ -9732,7 +9814,7 @@ Action_SetComment( ENTER(); - D(("name = '%b', comment = '%s'",MKBADDR(bcpl_name),MKBADDR(bcpl_comment))); + D(("name = '%b', comment = '%b'",MKBADDR(bcpl_name),MKBADDR(bcpl_comment))); if(file_system_disabled) { @@ -9773,7 +9855,7 @@ Action_SetComment( /* Trying to change the comment of the root directory? */ if(strcmp(full_name, SMB_ROOT_DIR_NAME) == SAME) { - D(("cannot change the comment of the root directory")); + SHOWMSG("cannot change the comment of the root directory"); error = ERROR_OBJECT_IN_USE; goto out; @@ -9991,7 +10073,7 @@ Action_FilesystemAttr( if(length > 0) { strlcpy((char *)data,VERS " (" DATE ")",length); - D(("FSA_VersionStringR = \"%s\"", data)); + D(("FSA_VersionStringR = \"%s\"", (char *)data)); } break; @@ -10037,6 +10119,7 @@ file_system_handler( const TEXT * service_name) { struct Process * this_process = (struct Process *)FindTask(NULL); + BOOL check_for_netbios_keepalive = FALSE; BOOL sign_off = FALSE; int old_priority = 0; fd_set read_fds; @@ -10127,19 +10210,27 @@ file_system_handler( Permit(); } - signal_mask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F | (1UL << FileSystemPort->mp_SigBit); + /* Check periodically for NetBIOS keep alive messages. */ + TimerRequest->tr_node.io_Command = TR_ADDREQUEST; + TimerRequest->tr_time.tv_secs = 10; + TimerRequest->tr_time.tv_micro = 0; + + SendIO((struct IORequest *)TimerRequest); + TimerTicking = TRUE; + + signal_mask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F | (1UL << FileSystemPort->mp_SigBit) | (1UL << TimerPort->mp_SigBit); FD_ZERO(&read_fds); do { - server_fd = ServerData->server.mount_data.fd; - /* If the server is currently connected, check if it has sent * a NetBIOS "keep alive" message and deal with it. */ - if(server_fd >= 0) + if(check_for_netbios_keepalive && (server_fd = ServerData->server.mount_data.fd) >= 0) { + int n; + /* We want to know if this socket has readable data for us. */ FD_SET(server_fd, &read_fds); @@ -10148,7 +10239,13 @@ file_system_handler( /* Wait for the server to send something, a signal to be received * or the next file system packet to arrive. */ - if(WaitSelect(server_fd+1,&read_fds,NULL,NULL,NULL,&signals) > 0) + PROFILE_OFF(); + + n = WaitSelect(server_fd+1,&read_fds,NULL,NULL,NULL,&signals); + + PROFILE_ON(); + + if(n > 0) { int num_bytes; UBYTE data[4]; @@ -10168,6 +10265,8 @@ file_system_handler( SHOWMSG("checking for more data..."); + PROFILE_OFF(); + non_blocking_io = TRUE; IoctlSocket(server_fd, FIONBIO, &non_blocking_io); @@ -10181,6 +10280,8 @@ file_system_handler( non_blocking_io = FALSE; IoctlSocket(server_fd, FIONBIO, &non_blocking_io); + PROFILE_ON(); + if(num_bytes > 0) { D(("there's probably something waiting to be read... (%ld bytes)", num_bytes)); @@ -10215,13 +10316,37 @@ file_system_handler( * ServerData->server.mount_data.fd. */ FD_CLR(server_fd, &read_fds); + + check_for_netbios_keepalive = FALSE; + + TimerRequest->tr_node.io_Command = TR_ADDREQUEST; + TimerRequest->tr_time.tv_secs = 10; + TimerRequest->tr_time.tv_micro = 0; + + SendIO((struct IORequest *)TimerRequest); + TimerTicking = TRUE; } /* The server connection isn't ready yet, so we wait for * stop/debug signals and more file system packets. */ else { + PROFILE_OFF(); + signals = Wait(signal_mask); + + PROFILE_ON(); + } + + /* Schedule an NetBIOS keep alive check? */ + if(signals & (1UL << TimerPort->mp_SigBit)) + { + SHOWMSG("scheduling a check for NetBIOS keep alive messages"); + + WaitIO((struct IORequest *)TimerRequest); + TimerTicking = FALSE; + + check_for_netbios_keepalive = TRUE; } /* Stop the file system? */ @@ -10294,9 +10419,9 @@ file_system_handler( if (num_packets_waiting > 1) D(("%lu packets are waiting to be processed", num_packets_waiting)); else if (num_packets_waiting == 1) - D(("1 packet is waiting to be processed")); + SHOWMSG("1 packet is waiting to be processed"); else - D(("no packet is waiting to be processed")); + SHOWMSG("no packet is waiting to be processed"); } #endif /* DEBUG */ @@ -10318,7 +10443,7 @@ file_system_handler( /* Is this even a valid address? */ if(sender == NULL || TypeOfMem((APTR)sender) == 0) { - D(("got packet; sender 0x%08lx", sender)); + D(("got packet; sender 0x%08lx", (ULONG)sender)); } /* Is the sender a Task? */ else if (sender->pr_Task.tc_Node.ln_Type == NT_TASK) @@ -10374,12 +10499,12 @@ file_system_handler( if(cli_number > 0) D(("got packet; sender '%s' (CLI #%ld)", command_name, cli_number)); else - D(("got packet; sender '%s' (CLI 0x%08lx)", command_name, cli)); + D(("got packet; sender '%s' (CLI 0x%08lx)", command_name, (ULONG)cli)); } /* No, it's just a shell. */ else { - D(("got packet; sender '%s' (CLI 0x%08lx)",((struct Node *)dp->dp_Port->mp_SigTask)->ln_Name, cli)); + D(("got packet; sender '%s' (CLI 0x%08lx)",((struct Node *)dp->dp_Port->mp_SigTask)->ln_Name, (ULONG)cli)); } } /* Doesn't look like a valid CLI pointer. */ @@ -10401,7 +10526,7 @@ file_system_handler( } else { - D(("got packet (MsgPort=0x%08lx)", dp->dp_Port)); + D(("got packet (MsgPort=0x%08lx)", (ULONG)dp->dp_Port)); } } #endif /* DEBUG */ @@ -10789,7 +10914,7 @@ file_system_handler( struct FileNode * fn; struct LockNode * ln; - D(("list of open files:")); + SHOWMSG("list of open files:"); for(fn = (struct FileNode *)FileList.mlh_Head ; fn->fn_MinNode.mln_Succ != NULL ; @@ -10800,7 +10925,7 @@ file_system_handler( D(("")); } - D(("list of allocated locks:")); + SHOWMSG("list of allocated locks:"); for(ln = (struct LockNode *)LockList.mlh_Head ; ln->ln_MinNode.mln_Succ != NULL ; @@ -10855,7 +10980,7 @@ file_system_handler( * to the first digit of the string. */ const char * -convert_quad_to_string(const QUAD * const number) +convert_quad_to_string(const QUAD * number) { static char string[22]; /* 21 bytes should be sufficient. */ diff --git a/source_code/proc.c b/source_code/proc.c index 7957e25..99e18aa 100644 --- a/source_code/proc.c +++ b/source_code/proc.c @@ -477,7 +477,7 @@ smb_decode_dword (const byte * p, dword * data) return (byte *)&p[4]; } -byte * +static INLINE byte * smb_encode_smb_length (byte * p, int len) { /* 0x00 = NetBIOS session message */ @@ -689,7 +689,7 @@ date_unix2dos (int utc_seconds, unsigned short *time_value, unsigned short *date * Support section. * ****************************************************************************/ -int +static INLINE int smb_len (const byte * packet) { /* This returns the payload length stored in the NetBIOS session header. */ @@ -956,13 +956,14 @@ smb_dump_packet (const byte * packet) errcls = (int) packet[9]; error = (int) (int) (packet[11] | ((int)packet[12]) << 8); - LOG (("smb_len = %ld valid = %ld\n", len = smb_len (packet), smb_valid_packet (packet))); + LOG (("smb_len = %ld valid = %ld\n", smb_len (packet), smb_valid_packet (packet))); LOG (("smb_cmd = %ld smb_wct = %ld smb_bcc = %ld\n", packet[8], SMB_WCT (packet), SMB_BCC (packet))); LOG (("smb_rcls = %ld smb_err = %ld\n", errcls, error)); if (errcls) smb_printerr (errcls, error); + len = smb_len (packet); if (len > 100) len = 100; @@ -2461,7 +2462,14 @@ smb_decode_dirent (const char *p, struct smb_dirent *entry) struct tm tm; seconds_to_tm(entry->mtime,&tm); - LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec)); + + LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n", + tm.tm_year + 1900, + tm.tm_mon+1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec)); } #endif /* DEBUG */ @@ -2606,6 +2614,8 @@ smb_proc_readdir_short ( goto out; } + ASSERT (bcc == count * SMB_DIRINFO_SIZE + 3); + if (bcc != count * SMB_DIRINFO_SIZE + 3) { LOG (("byte count (%ld) does not match expected size (%ld)\n", bcc, count * SMB_DIRINFO_SIZE + 3)); @@ -2812,7 +2822,7 @@ smb_decode_long_dirent ( /* Skip directory entries whose names we cannot store. */ if(name_len >= (int)finfo->complete_path_size) { - LOG(("name length >= %ld (skipping it)\n", finfo->complete_path_size)); + LOG(("name length >= %lu (skipping it)\n", (unsigned long)finfo->complete_path_size)); success = FALSE; break; @@ -2946,7 +2956,7 @@ smb_decode_long_dirent ( /* Skip directory entries whose names we cannot store. */ if(name_len >= (int)finfo->complete_path_size) { - LOG(("name length >= %ld (skipping it)\n", finfo->complete_path_size)); + LOG(("name length >= %lu (skipping it)\n", (unsigned long)finfo->complete_path_size)); success = FALSE; break; @@ -3194,8 +3204,12 @@ smb_proc_readdir_long ( { SHOWMSG("ouch; delaying and retrying"); + PROFILE_OFF(); + Delay(TICKS_PER_SECOND / 5); + PROFILE_ON(); + continue; } diff --git a/source_code/quad_math.c b/source_code/quad_math.c index 86b2c20..d6d4650 100644 --- a/source_code/quad_math.c +++ b/source_code/quad_math.c @@ -20,14 +20,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef _QUAD_MATH_H -#include "quad_math.h" -#endif /* _QUAD_MATH_H */ +#ifndef _SMBFS_H +#include "smbfs.h" +#endif /* _SMBFS_H */ /****************************************************************************/ /* This function comes from Harry S. Warren, Jr.'s book "Hacker's delight". */ -static int +static INLINE int carry(ULONG x, ULONG y) { int result; diff --git a/source_code/smakefile b/source_code/smakefile index e43cf26..af1472c 100644 --- a/source_code/smakefile +++ b/source_code/smakefile @@ -69,17 +69,24 @@ VERSION = 2 # #DEBUG_OPTIONS = define=DEBUG define=DUMP_SMB code=far data=faronly +########################################################################### + +# Enable profiling support; note that this requires linking +# against "lib:scnb.lib" instead of "lib:sc.lib", just like +# it is necessary for the debug build. +#PROFILE_OPTIONS = profile code=far data=faronly + ############################################################################### -# Note: if DEBUG_OPTIONS are enabled you will need to link smbfs against -# "lib:scnb.lib" rather than "lib:sc.lib". +# Note: if DEBUG_OPTIONS or PROFILE_OPTIONS are enabled you will need to link +# smbfs against "lib:scnb.lib" rather than "lib:sc.lib". LIBS = lib:sc.lib lib:amiga.lib lib:debug.lib ############################################################################### CFLAGS = \ idlen=64 comnest streq strmerge nostkchk \ - $(OPTIMIZE) cpu=$(CPU) debug=$(DEBUG) $(DEBUG_OPTIONS) \ + $(OPTIMIZE) cpu=$(CPU) debug=$(DEBUG) $(DEBUG_OPTIONS) $(PROFILE_OPTIONS) \ params=register idir=netinclude idir=include \ ignore=306 gst=system_headers.gst diff --git a/source_code/smb_abstraction.c b/source_code/smb_abstraction.c index 0c16bd7..af47bc1 100644 --- a/source_code/smb_abstraction.c +++ b/source_code/smb_abstraction.c @@ -796,7 +796,7 @@ smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int if (result < 0) goto out; - LOG(("read %ld bytes from offset %ld\n",len,offset)); + LOG(("read %ld bytes from offset %s\n",len,convert_quad_to_string(offset))); /* SMB_COM_READ_ANDX supported? */ if (f->server->server.protocol >= PROTOCOL_LANMAN1 && !f->server->server.prefer_core_protocol) @@ -1043,7 +1043,7 @@ smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offs ASSERT( n > 0 ); - LOG(("writing %ld bytes; offset=%lu, len=%ld\n", n, offset, len)); + LOG(("writing %ld bytes; offset=%s, len=%ld\n", n, convert_quad_to_string(&position_quad), len)); result = smb_proc_writex(&f->server->server, &f->dirent, &position_quad, n, data, error_ptr); if(result < 0) @@ -2136,6 +2136,7 @@ smba_start( h_errno = 0; h = gethostbyname (server); + lookup_error = h_errno; if (h != NULL) diff --git a/source_code/smbfs.h b/source_code/smbfs.h index 273451d..0666769 100644 --- a/source_code/smbfs.h +++ b/source_code/smbfs.h @@ -154,7 +154,7 @@ extern void VARARGS68K report_error(const TEXT * fmt,...); extern void string_toupper(STRPTR s); extern void VARARGS68K LocalSNPrintf(STRPTR buffer, int limit, const TEXT * formatString,...); extern TEXT * escape_name(const TEXT * name); -extern const char * convert_quad_to_string(const QUAD * const number); +extern const char * convert_quad_to_string(const QUAD * number); /****************************************************************************/ diff --git a/source_code/smbfs_rev.h b/source_code/smbfs_rev.h index 9dff14b..d0c584d 100644 --- a/source_code/smbfs_rev.h +++ b/source_code/smbfs_rev.h @@ -1,6 +1,6 @@ #define VERSION 2 -#define REVISION 11 -#define DATE "31.12.2018" -#define VERS "smbfs 2.11" -#define VSTRING "smbfs 2.11 (31.12.2018)\r\n" -#define VERSTAG "\0$VER: smbfs 2.11 (31.12.2018)" +#define REVISION 12 +#define DATE "5.1.2019" +#define VERS "smbfs 2.12" +#define VSTRING "smbfs 2.12 (5.1.2019)\r\n" +#define VERSTAG "\0$VER: smbfs 2.12 (5.1.2019)" diff --git a/source_code/smbfs_rev.rev b/source_code/smbfs_rev.rev index b4de394..48082f7 100644 --- a/source_code/smbfs_rev.rev +++ b/source_code/smbfs_rev.rev @@ -1 +1 @@ -11 +12 diff --git a/source_code/sock.c b/source_code/sock.c index e3cd3e0..aadf635 100644 --- a/source_code/sock.c +++ b/source_code/sock.c @@ -56,38 +56,74 @@ /*****************************************************************************/ +static INLINE int +smb_len (const byte * packet) +{ + /* This returns the payload length stored in the NetBIOS session header. */ + return (((int)(packet[1] & 0x1)) << 16) | (((int)packet[2]) << 8) | (packet[3]); +} + +static INLINE byte * +smb_encode_smb_length (byte * p, int len) +{ + /* 0x00 = NetBIOS session message */ + p[0] = 0; + + /* Length is a 17 bit integer, the most significant + * bit of which goes into bit #0. The other 7 bits + * are reserved. + */ + p[1] = (len >> 16) & 1; + + /* Payload length in network byte order + * (least significant 16 bits). + */ + p[2] = (len & 0xFF00) >> 8; + p[3] = (len & 0xFF); + + return &p[4]; +} + +/*****************************************************************************/ + /* Attempt to receive all the incoming data, even if recv() returns only * parts of the total number of bytes requested. Returns the number of bytes * read or, in case of error a negative number. A negative result is the * value of -errno. */ -static int -receive_all(int fd, void * _data, int len, int * error_ptr) +static INLINE int +receive_all(int fd, void * _data, int len) { - int num_bytes_received; char * data = _data; - int result; + int result = 0; + int n; ASSERT( data != NULL || len == 0 ); - ASSERT( error_ptr != NULL ); - for(num_bytes_received = 0 ; num_bytes_received < len ; num_bytes_received += result) + for(;;) { - result = recv(fd, &data[num_bytes_received], len - num_bytes_received, 0); - if(result == 0) + PROFILE_OFF(); + + n = recv(fd, data, len, 0); + + PROFILE_ON(); + + if(n < 0) + { + result = -1; + break; + } + + result += n; + + len -= n; + + if(len == 0 || n == 0) break; - if(result < 0) - { - (*error_ptr) = errno; - goto out; - } + data += n; } - result = num_bytes_received; - - out: - return(result); } @@ -110,9 +146,11 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p ASSERT( error_ptr != NULL ); /* Read the NetBIOS session header (rfc-1002, section 4.3.1) */ - result = receive_all (sock_fd, netbios_session_buf, NETBIOS_HEADER_SIZE, error_ptr); + result = receive_all (sock_fd, netbios_session_buf, NETBIOS_HEADER_SIZE); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); goto out; } @@ -176,9 +214,11 @@ smb_discard_netbios_frames(struct smb_server *server, int sock_fd, int * error_p goto out; } - result = receive_all (sock_fd, server->transmit_buffer, netbios_session_payload_size, error_ptr); + result = receive_all (sock_fd, server->transmit_buffer, netbios_session_payload_size); if (result < 0) { + (*error_ptr) = errno; + LOG(("recv error = %ld\n", (*error_ptr))); goto out; } @@ -212,6 +252,8 @@ smb_receive_raw ( ASSERT( server != NULL ); ASSERT( error_ptr != NULL ); + PROFILE_PUSH("SMB receive raw header"); + /* We need to read the NetBIOS session header before we can move * on and read the SMB data. Because the NetBIOS session header * may be a keepalive message or something else we can safely @@ -223,11 +265,21 @@ smb_receive_raw ( server->rcls = 0; server->err = 0; + PROFILE_PUSH("SMB receive raw header: receive_all()"); + /* Read the NetBIOS session header (rfc-1002, section 4.3.1) */ - result = receive_all (sock_fd, netbios_session_buf, NETBIOS_HEADER_SIZE, error_ptr); + result = receive_all (sock_fd, netbios_session_buf, NETBIOS_HEADER_SIZE); + + PROFILE_POP("SMB receive raw header: receive_all()"); + if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMB receive raw header"); + goto out; } @@ -238,6 +290,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMB receive raw header"); + goto out; } @@ -260,10 +315,15 @@ smb_receive_raw ( if(netbios_session_payload_size > (int)sizeof(netbios_session_payload)) netbios_session_payload_size = sizeof(netbios_session_payload); - result = receive_all (sock_fd, netbios_session_payload, netbios_session_payload_size, error_ptr); + result = receive_all (sock_fd, netbios_session_payload, netbios_session_payload_size); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMB receive raw header"); + goto out; } @@ -274,6 +334,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMB receive raw header"); + goto out; } @@ -330,6 +393,9 @@ smb_receive_raw ( (*error_ptr) = error_invalid_netbios_session; result = -1; + + PROFILE_POP("SMB receive raw header"); + goto out; } @@ -340,6 +406,8 @@ smb_receive_raw ( break; } + PROFILE_POP("SMB receive raw header"); + /* The length in the NetBIOS header is the raw data length (17 bits) */ len = netbios_session_payload_size; if (len > max_raw_length) @@ -383,13 +451,15 @@ smb_receive_raw ( LOG(("receiving SMB message and payload separately\n")); - LOG(("input_payload=0x%08lx, payload_size=%ld\n", input_payload, input_payload_size)); + LOG(("input_payload=0x%08lx, payload_size=%ld\n", (unsigned long)input_payload, input_payload_size)); if(command == SMBreadX) { int data_length; int data_offset; + PROFILE_PUSH("SMBreadX"); + /* We need to read the following data: * * 0: 32 bytes of SMB message header @@ -412,10 +482,15 @@ smb_receive_raw ( ASSERT( target != NULL ); - result = receive_all (sock_fd, target, 59, error_ptr); + result = receive_all (sock_fd, target, 59); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBreadX"); + goto out; } @@ -432,6 +507,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBreadX"); + goto out; } @@ -444,10 +522,15 @@ smb_receive_raw ( { LOG (("skipping %ld padding bytes\n", data_offset - 59)); - result = receive_all (sock_fd, target + 59, data_offset - 59, error_ptr); + result = receive_all (sock_fd, target + 59, data_offset - 59); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBreadX"); + goto out; } @@ -460,6 +543,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBreadX"); + goto out; } @@ -472,10 +558,15 @@ smb_receive_raw ( ASSERT( data_length <= input_payload_size ); - result = receive_all (sock_fd, input_payload, data_length, error_ptr); + result = receive_all (sock_fd, input_payload, data_length); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBreadX"); + goto out; } @@ -487,6 +578,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBreadX"); + goto out; } @@ -499,10 +593,15 @@ smb_receive_raw ( { LOG(("reading the remaining %ld bytes; this should never happen\n", len - num_bytes_received )); - result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received, error_ptr); + result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBreadX"); + goto out; } @@ -514,9 +613,14 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBreadX"); + goto out; } } + + PROFILE_POP("SMBreadX"); } else { @@ -524,6 +628,8 @@ smb_receive_raw ( int count_of_bytes_to_read; int buffer_format; + PROFILE_PUSH("SMBread"); + ASSERT( command == SMBread ); /* We need to read the following data: @@ -543,10 +649,15 @@ smb_receive_raw ( ASSERT( target != NULL ); - result = receive_all (sock_fd, target, 48, error_ptr); + result = receive_all (sock_fd, target, 48); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBread"); + goto out; } @@ -563,6 +674,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBread"); + goto out; } @@ -583,6 +697,9 @@ smb_receive_raw ( (*error_ptr) = error_invalid_buffer_format; result = -1; + + PROFILE_POP("SMBread"); + goto out; } @@ -603,13 +720,21 @@ smb_receive_raw ( (*error_ptr) = error_message_exceeds_buffer_size; result = -1; + + PROFILE_POP("SMBread"); + goto out; } - result = receive_all (sock_fd, input_payload, count_of_bytes_to_read, error_ptr); + result = receive_all (sock_fd, input_payload, count_of_bytes_to_read); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBread"); + goto out; } @@ -621,6 +746,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBread"); + goto out; } @@ -642,10 +770,15 @@ smb_receive_raw ( { LOG(("reading the remaining %ld bytes; this should never happen\n", len - num_bytes_received )); - result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received, error_ptr); + result = receive_all (sock_fd, &target[num_bytes_received], len - num_bytes_received); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMBread"); + goto out; } @@ -657,6 +790,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMBread"); + goto out; } } @@ -673,6 +809,8 @@ smb_receive_raw ( dump_smb(__FILE__,__LINE__,!want_header,&target[num_bytes_received],result,smb_packet_to_consumer,server->max_recv); } #endif /* defined(DUMP_SMB) */ + + PROFILE_POP("SMBread"); } result = num_bytes_received; @@ -685,14 +823,21 @@ smb_receive_raw ( */ else { + PROFILE_PUSH("SMB read full"); + LOG(("receiving SMB message and payload in one chunk\n")); ASSERT( target != NULL ); - result = receive_all (sock_fd, target, len, error_ptr); + result = receive_all (sock_fd, target, len); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMB read full"); + goto out; } @@ -704,6 +849,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMB read full"); + goto out; } @@ -751,6 +899,9 @@ smb_receive_raw ( (*error_ptr) = error_invalid_buffer_format; result = -1; + + PROFILE_POP("SMB read full"); + goto out; } @@ -771,6 +922,9 @@ smb_receive_raw ( (*error_ptr) = error_message_exceeds_buffer_size; result = -1; + + PROFILE_POP("SMB read full"); + goto out; } @@ -785,16 +939,25 @@ smb_receive_raw ( memset(&input_payload[count_of_bytes_to_read],0,count_of_bytes_returned - count_of_bytes_to_read); } } + + PROFILE_POP("SMB read full"); } } else { + PROFILE_PUSH("SMB read single buffer"); + ASSERT( target != NULL ); - result = receive_all (sock_fd, target, len, error_ptr); + result = receive_all (sock_fd, target, len); if (result < 0) { + (*error_ptr) = errno; + LOG (("recv error = %ld\n", (*error_ptr))); + + PROFILE_POP("SMB read single buffer"); + goto out; } @@ -806,6 +969,9 @@ smb_receive_raw ( (*error_ptr) = error_end_of_file; result = -1; + + PROFILE_POP("SMB read single buffer"); + goto out; } @@ -815,6 +981,8 @@ smb_receive_raw ( dump_smb(__FILE__,__LINE__,!want_header,target,result,smb_packet_to_consumer,server->max_recv); } #endif /* defined(DUMP_SMB) */ + + PROFILE_POP("SMB read single buffer"); } out: @@ -1089,7 +1257,12 @@ smb_release (struct smb_server *server) { if (server->mount_data.fd >= 0) { + PROFILE_OFF(); + CloseSocket (server->mount_data.fd); + + PROFILE_ON(); + server->mount_data.fd = -1; } @@ -1102,6 +1275,8 @@ smb_connect (struct smb_server *server, int * error_ptr) int enabled = TRUE; int result; + PROFILE_OFF(); + ASSERT( server != NULL ); ASSERT( error_ptr != NULL ); @@ -1292,6 +1467,8 @@ smb_connect (struct smb_server *server, int * error_ptr) out: + PROFILE_ON(); + return(result); } @@ -1426,8 +1603,8 @@ smb_request ( LOG (("len = %ld, cmd = 0x%lx, input_payload=0x%08lx, output_payload=0x%08lx, payload_size=%ld\n", len, buffer[8], - input_payload, - output_payload, + (unsigned long)input_payload, + (unsigned long)output_payload, payload_size)); #if defined(DUMP_SMB) @@ -1442,7 +1619,12 @@ smb_request ( { LOG(("using two send() calls\n")); + PROFILE_OFF(); + result = send (sock_fd, (void *) buffer, len, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno)); @@ -1452,7 +1634,12 @@ smb_request ( goto out; } + PROFILE_OFF(); + result = send (sock_fd, (void *)output_payload, payload_size, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("payload send() for %ld bytes failed (errno=%ld)\n", payload_size, errno)); @@ -1483,7 +1670,12 @@ smb_request ( iov[1].iov_base = (void *)output_payload; iov[1].iov_len = payload_size; + PROFILE_OFF(); + result = sendmsg (sock_fd, &msg, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("sendmsg() for %ld+%ld bytes failed (errno=%ld)\n", len, payload_size, errno)); @@ -1496,7 +1688,12 @@ smb_request ( } else { + PROFILE_OFF(); + result = send (sock_fd, (void *) buffer, len, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno)); @@ -1560,7 +1757,12 @@ smb_trans2_request ( dump_smb(__FILE__,__LINE__,0,buffer+NETBIOS_HEADER_SIZE,len-NETBIOS_HEADER_SIZE,smb_packet_from_consumer,server->max_recv); #endif /* defined(DUMP_SMB) */ + PROFILE_OFF(); + result = send (sock_fd, (void *) buffer, len, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno)); @@ -1619,7 +1821,12 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_ #endif /* defined(DUMP_SMB) */ /* Request that data should be read in raw mode. */ + PROFILE_OFF(); + result = send (sock_fd, (void *) buffer, len, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno)); @@ -1680,7 +1887,12 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i LOG(("using two send() calls\n")); /* Send the NetBIOS header. */ + PROFILE_OFF(); + result = send (sock_fd, nb_header, NETBIOS_HEADER_SIZE, 0); + + PROFILE_ON(); + if(result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", NETBIOS_HEADER_SIZE, errno)); @@ -1691,7 +1903,12 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i } /* Now send the data to be written. */ + PROFILE_OFF(); + result = send (sock_fd, (void *)source, length, 0); + + PROFILE_ON(); + if(result < 0) { LOG(("send() for %ld bytes failed (errno=%ld)\n", length, errno)); @@ -1722,7 +1939,12 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i iov[1].iov_base = (void *)source; iov[1].iov_len = length; + PROFILE_OFF(); + result = sendmsg (sock_fd, &msg, 0); + + PROFILE_ON(); + if (result < 0) { LOG(("sendmsg() for %ld+%ld bytes failed (errno=%ld)\n", NETBIOS_HEADER_SIZE, length, errno)); diff --git a/source_code/system_headers.h b/source_code/system_headers.h index 97f7603..512443c 100644 --- a/source_code/system_headers.h +++ b/source_code/system_headers.h @@ -106,6 +106,17 @@ #include #include +/* +#include +#include +#include +#include +#include +#include +#include +#include +*/ + /*****************************************************************************/ /* This is for backwards compatibility only. */ @@ -145,4 +156,42 @@ /*****************************************************************************/ +/* This is for use with the profiling support of the SAS/C compiler and + * its runtime library. The macros defined in the header file are replaced + * by no-ops for other compilers. + */ +#if defined(__SASC) && defined(_PROFILE) + +#include + +#if _PROFILE + +/* The profiling disable/enable calls need to nest, which is + * why we use our own local counter and some corresponding + * macros instead of the SAS/C-supplied versions. See the + * header file how they are supposed to work. + */ +extern int profile_nest_count; + +#undef PROFILE_ON +#undef PROFILE_OFF + +extern void kprintf(const char *fmt, ...); + +#define PROFILE_OFF() { if(profile_nest_count++ == 0) _PROLOG(0L); } +#define PROFILE_ON() { if(--profile_nest_count == 0) _EPILOG(0L); } +#endif /* _PROFILE */ + +#else + +#define PROFILE_OFF() {} +#define PROFILE_ON() {} + +#define PROFILE_PUSH(x) {} +#define PROFILE_POP(x) {} + +#endif /* __SASC */ + +/*****************************************************************************/ + #endif /* _SYSTEM_HEADERS_H */