Changeset 988 for vendor/current/source3/lib/util.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/lib/util.c
r860 r988 29 29 #include "../lib/util/util_pw.h" 30 30 #include "messages.h" 31 #include "messages_dgm.h" 31 32 #include "libcli/security/security.h" 32 33 extern char *global_clobber_region_function; 34 extern unsigned int global_clobber_region_line; 33 #include "serverid.h" 34 #include "lib/util/sys_rw.h" 35 #include "lib/util/sys_rw_data.h" 36 #include "lib/util/util_process.h" 37 38 #ifdef HAVE_SYS_PRCTL_H 39 #include <sys/prctl.h> 40 #endif 35 41 36 42 /* Max allowable allococation - 256mb - 0x10000000 */ … … 77 83 static enum remote_arch_types ra_type = RA_UNKNOWN; 78 84 79 /***********************************************************************80 Definitions for all names.81 ***********************************************************************/82 83 static char *smb_scope;84 static int smb_num_netbios_names;85 static char **smb_my_netbios_names;86 87 /***********************************************************************88 Allocate and set scope. Ensure upper case.89 ***********************************************************************/90 91 bool set_global_scope(const char *scope)92 {93 SAFE_FREE(smb_scope);94 smb_scope = SMB_STRDUP(scope);95 if (!smb_scope)96 return False;97 strupper_m(smb_scope);98 return True;99 }100 101 /*********************************************************************102 Ensure scope is never null string.103 *********************************************************************/104 105 const char *global_scope(void)106 {107 if (!smb_scope)108 set_global_scope("");109 return smb_scope;110 }111 112 static void free_netbios_names_array(void)113 {114 int i;115 116 for (i = 0; i < smb_num_netbios_names; i++)117 SAFE_FREE(smb_my_netbios_names[i]);118 119 SAFE_FREE(smb_my_netbios_names);120 smb_num_netbios_names = 0;121 }122 123 static bool allocate_my_netbios_names_array(size_t number)124 {125 free_netbios_names_array();126 127 smb_num_netbios_names = number + 1;128 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );129 130 if (!smb_my_netbios_names)131 return False;132 133 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);134 return True;135 }136 137 static bool set_my_netbios_names(const char *name, int i)138 {139 SAFE_FREE(smb_my_netbios_names[i]);140 141 smb_my_netbios_names[i] = SMB_STRDUP(name);142 if (!smb_my_netbios_names[i])143 return False;144 strupper_m(smb_my_netbios_names[i]);145 return True;146 }147 148 /***********************************************************************149 Free memory allocated to global objects150 ***********************************************************************/151 152 void gfree_names(void)153 {154 gfree_netbios_names();155 SAFE_FREE( smb_scope );156 free_netbios_names_array();157 free_local_machine_name();158 }159 160 85 void gfree_all( void ) 161 86 { 162 87 gfree_names(); 163 88 gfree_loadparm(); 164 gfree_case_tables();165 89 gfree_charcnv(); 166 90 gfree_interfaces(); … … 168 92 } 169 93 170 const char *my_netbios_names(int i)171 {172 return smb_my_netbios_names[i];173 }174 175 bool set_netbios_aliases(const char **str_array)176 {177 size_t namecount;178 179 /* Work out the max number of netbios aliases that we have */180 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )181 ;182 183 if ( global_myname() && *global_myname())184 namecount++;185 186 /* Allocate space for the netbios aliases */187 if (!allocate_my_netbios_names_array(namecount))188 return False;189 190 /* Use the global_myname string first */191 namecount=0;192 if ( global_myname() && *global_myname()) {193 set_my_netbios_names( global_myname(), namecount );194 namecount++;195 }196 197 if (str_array) {198 size_t i;199 for ( i = 0; str_array[i] != NULL; i++) {200 size_t n;201 bool duplicate = False;202 203 /* Look for duplicates */204 for( n=0; n<namecount; n++ ) {205 if( strequal( str_array[i], my_netbios_names(n) ) ) {206 duplicate = True;207 break;208 }209 }210 if (!duplicate) {211 if (!set_my_netbios_names(str_array[i], namecount))212 return False;213 namecount++;214 }215 }216 }217 return True;218 }219 220 /****************************************************************************221 Common name initialization code.222 ****************************************************************************/223 224 bool init_names(void)225 {226 int n;227 228 if (global_myname() == NULL || *global_myname() == '\0') {229 if (!set_global_myname(myhostname())) {230 DEBUG( 0, ( "init_names: malloc fail.\n" ) );231 return False;232 }233 }234 235 if (!set_netbios_aliases(lp_netbios_aliases())) {236 DEBUG( 0, ( "init_names: malloc fail.\n" ) );237 return False;238 }239 240 set_local_machine_name(global_myname(),false);241 242 DEBUG( 5, ("Netbios name list:-\n") );243 for( n=0; my_netbios_names(n); n++ ) {244 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",245 n, my_netbios_names(n) ) );246 }247 248 return( True );249 }250 251 94 /******************************************************************* 252 95 Check if a file exists - call vfs_file_exist for samba files. … … 288 131 } 289 132 290 /******************************************************************* 291 Returns the size in bytes of the named file. 292 ********************************************************************/ 293 294 SMB_OFF_T get_file_size(char *file_name) 295 { 296 SMB_STRUCT_STAT buf; 297 buf.st_ex_size = 0; 298 if (sys_stat(file_name, &buf, false) != 0) 299 return (SMB_OFF_T)-1; 300 return get_file_size_stat(&buf); 301 } 302 303 /******************************************************************* 304 Return a string representing an attribute for a file. 305 ********************************************************************/ 306 307 char *attrib_string(uint16 mode) 308 { 309 fstring attrstr; 310 311 attrstr[0] = 0; 312 313 if (mode & FILE_ATTRIBUTE_VOLUME) fstrcat(attrstr,"V"); 314 if (mode & FILE_ATTRIBUTE_DIRECTORY) fstrcat(attrstr,"D"); 315 if (mode & FILE_ATTRIBUTE_ARCHIVE) fstrcat(attrstr,"A"); 316 if (mode & FILE_ATTRIBUTE_HIDDEN) fstrcat(attrstr,"H"); 317 if (mode & FILE_ATTRIBUTE_SYSTEM) fstrcat(attrstr,"S"); 318 if (mode & FILE_ATTRIBUTE_READONLY) fstrcat(attrstr,"R"); 319 320 return talloc_strdup(talloc_tos(), attrstr); 133 /**************************************************************************** 134 Check two stats have identical dev and ino fields. 135 ****************************************************************************/ 136 137 bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1, 138 const SMB_STRUCT_STAT *sbuf2) 139 { 140 if (sbuf1->st_ex_dev != sbuf2->st_ex_dev || 141 sbuf1->st_ex_ino != sbuf2->st_ex_ino) { 142 return false; 143 } 144 return true; 145 } 146 147 /**************************************************************************** 148 Check if a stat struct is identical for use. 149 ****************************************************************************/ 150 151 bool check_same_stat(const SMB_STRUCT_STAT *sbuf1, 152 const SMB_STRUCT_STAT *sbuf2) 153 { 154 if (sbuf1->st_ex_uid != sbuf2->st_ex_uid || 155 sbuf1->st_ex_gid != sbuf2->st_ex_gid || 156 !check_same_dev_ino(sbuf1, sbuf2)) { 157 return false; 158 } 159 return true; 321 160 } 322 161 … … 325 164 ********************************************************************/ 326 165 327 void show_msg(c har *buf)166 void show_msg(const char *buf) 328 167 { 329 168 int i; … … 362 201 bcc = MIN(bcc, 512); 363 202 364 dump_data(10, (uint8 *)smb_buf(buf), bcc); 365 } 366 367 /******************************************************************* 368 Set the length and marker of an encrypted smb packet. 369 ********************************************************************/ 370 371 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num) 372 { 373 _smb_setlen(buf,len); 374 375 SCVAL(buf,4,0xFF); 376 SCVAL(buf,5,'E'); 377 SSVAL(buf,6,enc_ctx_num); 378 } 379 380 /******************************************************************* 381 Set the length and marker of an smb packet. 382 ********************************************************************/ 383 384 void smb_setlen(char *buf,int len) 385 { 386 _smb_setlen_large(buf,len); 387 388 SCVAL(buf,4,0xFF); 389 SCVAL(buf,5,'S'); 390 SCVAL(buf,6,'M'); 391 SCVAL(buf,7,'B'); 203 dump_data(10, (const uint8_t *)smb_buf_const(buf), bcc); 392 204 } 393 205 … … 409 221 ********************************************************************/ 410 222 411 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)223 ssize_t message_push_blob(uint8_t **outbuf, DATA_BLOB blob) 412 224 { 413 225 size_t newlen = smb_len(*outbuf) + 4 + blob.length; 414 uint8 *tmp;415 416 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {226 uint8_t *tmp; 227 228 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8_t, newlen))) { 417 229 DEBUG(0, ("talloc failed\n")); 418 230 return -1; … … 542 354 ********************************************************************/ 543 355 544 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_Tpos)356 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, off_t pos) 545 357 { 546 358 size_t total=0; 547 359 ssize_t ret; 548 360 549 if (pos == ( SMB_OFF_T)-1) {361 if (pos == (off_t)-1) { 550 362 return write_data(fd, buffer, N); 551 363 } … … 569 381 #else 570 382 /* Use lseek and write_data. */ 571 if ( sys_lseek(fd, pos, SEEK_SET) == -1) {383 if (lseek(fd, pos, SEEK_SET) == -1) { 572 384 if (errno != ESPIPE) { 573 385 return -1; … … 578 390 } 579 391 392 static int reinit_after_fork_pipe[2] = { -1, -1 }; 393 394 NTSTATUS init_before_fork(void) 395 { 396 int ret; 397 398 ret = pipe(reinit_after_fork_pipe); 399 if (ret == -1) { 400 NTSTATUS status; 401 402 status = map_nt_error_from_unix_common(errno); 403 404 DEBUG(0, ("Error creating child_pipe: %s\n", 405 nt_errstr(status))); 406 407 return status; 408 } 409 410 return NT_STATUS_OK; 411 } 412 413 /** 414 * Detect died parent by detecting EOF on the pipe 415 */ 416 static void reinit_after_fork_pipe_handler(struct tevent_context *ev, 417 struct tevent_fd *fde, 418 uint16_t flags, 419 void *private_data) 420 { 421 char c; 422 423 if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) { 424 /* 425 * we have reached EOF on stdin, which means the 426 * parent has exited. Shutdown the server 427 */ 428 (void)kill(getpid(), SIGTERM); 429 } 430 } 431 580 432 581 433 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx, 582 struct event_context *ev_ctx,583 struct server_id id,584 bool parent_longlived)434 struct tevent_context *ev_ctx, 435 bool parent_longlived, 436 const char *comment) 585 437 { 586 438 NTSTATUS status = NT_STATUS_OK; 587 439 588 /* Reset the state of the random 589 * number generation system, so 590 * children do not get the same random 591 * numbers as each other */ 592 set_need_random_reseed(); 440 if (reinit_after_fork_pipe[1] != -1) { 441 close(reinit_after_fork_pipe[1]); 442 reinit_after_fork_pipe[1] = -1; 443 } 593 444 594 445 /* tdb needs special fork handling */ 595 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {446 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) { 596 447 DEBUG(0,("tdb_reopen_all failed.\n")); 597 448 status = NT_STATUS_OPEN_FAILED; … … 599 450 } 600 451 601 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) { 602 smb_panic(__location__ ": Failed to re-initialise event context"); 452 if (ev_ctx != NULL) { 453 tevent_set_trace_callback(ev_ctx, NULL, NULL); 454 if (tevent_re_initialise(ev_ctx) != 0) { 455 smb_panic(__location__ ": Failed to re-initialise event context"); 456 } 457 } 458 459 if (reinit_after_fork_pipe[0] != -1) { 460 struct tevent_fd *fde; 461 462 fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */, 463 reinit_after_fork_pipe[0], TEVENT_FD_READ, 464 reinit_after_fork_pipe_handler, NULL); 465 if (fde == NULL) { 466 smb_panic(__location__ ": Failed to add reinit_after_fork pipe event"); 467 } 603 468 } 604 469 … … 608 473 * fork 609 474 */ 610 status = messaging_reinit(msg_ctx , id);475 status = messaging_reinit(msg_ctx); 611 476 if (!NT_STATUS_IS_OK(status)) { 612 477 DEBUG(0,("messaging_reinit() failed: %s\n", … … 614 479 } 615 480 } 481 482 if (comment) { 483 prctl_set_comment(comment); 484 } 485 616 486 done: 617 487 return status; 618 }619 620 #if defined(PARANOID_MALLOC_CHECKER)621 622 /****************************************************************************623 Internal malloc wrapper. Externally visible.624 ****************************************************************************/625 626 void *malloc_(size_t size)627 {628 if (size == 0) {629 return NULL;630 }631 #undef malloc632 return malloc(size);633 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY634 }635 636 /****************************************************************************637 Internal calloc wrapper. Not externally visible.638 ****************************************************************************/639 640 static void *calloc_(size_t count, size_t size)641 {642 if (size == 0 || count == 0) {643 return NULL;644 }645 #undef calloc646 return calloc(count, size);647 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY648 }649 650 /****************************************************************************651 Internal realloc wrapper. Not externally visible.652 ****************************************************************************/653 654 static void *realloc_(void *ptr, size_t size)655 {656 #undef realloc657 return realloc(ptr, size);658 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY659 }660 661 #endif /* PARANOID_MALLOC_CHECKER */662 663 /****************************************************************************664 Type-safe memalign665 ****************************************************************************/666 667 void *memalign_array(size_t el_size, size_t align, unsigned int count)668 {669 if (count >= MAX_ALLOC_SIZE/el_size) {670 return NULL;671 }672 673 return sys_memalign(align, el_size*count);674 }675 676 /****************************************************************************677 Type-safe calloc.678 ****************************************************************************/679 680 void *calloc_array(size_t size, size_t nmemb)681 {682 if (nmemb >= MAX_ALLOC_SIZE/size) {683 return NULL;684 }685 if (size == 0 || nmemb == 0) {686 return NULL;687 }688 #if defined(PARANOID_MALLOC_CHECKER)689 return calloc_(nmemb, size);690 #else691 return calloc(nmemb, size);692 #endif693 }694 695 /****************************************************************************696 Expand a pointer to be a particular size.697 Note that this version of Realloc has an extra parameter that decides698 whether to free the passed in storage on allocation failure or if the699 new size is zero.700 701 This is designed for use in the typical idiom of :702 703 p = SMB_REALLOC(p, size)704 if (!p) {705 return error;706 }707 708 and not to have to keep track of the old 'p' contents to free later, nor709 to worry if the size parameter was zero. In the case where NULL is returned710 we guarentee that p has been freed.711 712 If free later semantics are desired, then pass 'free_old_on_error' as False which713 guarentees that the old contents are not freed on error, even if size == 0. To use714 this idiom use :715 716 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);717 if (!tmp) {718 SAFE_FREE(p);719 return error;720 } else {721 p = tmp;722 }723 724 Changes were instigated by Coverity error checking. JRA.725 ****************************************************************************/726 727 void *Realloc(void *p, size_t size, bool free_old_on_error)728 {729 void *ret=NULL;730 731 if (size == 0) {732 if (free_old_on_error) {733 SAFE_FREE(p);734 }735 DEBUG(2,("Realloc asked for 0 bytes\n"));736 return NULL;737 }738 739 #if defined(PARANOID_MALLOC_CHECKER)740 if (!p) {741 ret = (void *)malloc_(size);742 } else {743 ret = (void *)realloc_(p,size);744 }745 #else746 if (!p) {747 ret = (void *)malloc(size);748 } else {749 ret = (void *)realloc(p,size);750 }751 #endif752 753 if (!ret) {754 if (free_old_on_error && p) {755 SAFE_FREE(p);756 }757 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));758 }759 760 return(ret);761 488 } 762 489 … … 766 493 767 494 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, 768 void *element, void *_array, uint32 *num_elements,495 void *element, void *_array, uint32_t *num_elements, 769 496 ssize_t *array_size) 770 497 { … … 838 565 } 839 566 } 840 841 /****************************************************************************842 Interpret a protocol description string, with a default.843 ****************************************************************************/844 845 int interpret_protocol(const char *str,int def)846 {847 if (strequal(str,"NT1"))848 return(PROTOCOL_NT1);849 if (strequal(str,"LANMAN2"))850 return(PROTOCOL_LANMAN2);851 if (strequal(str,"LANMAN1"))852 return(PROTOCOL_LANMAN1);853 if (strequal(str,"CORE"))854 return(PROTOCOL_CORE);855 if (strequal(str,"COREPLUS"))856 return(PROTOCOL_COREPLUS);857 if (strequal(str,"CORE+"))858 return(PROTOCOL_COREPLUS);859 860 DEBUG(0,("Unrecognised protocol level %s\n",str));861 862 return(def);863 }864 865 567 866 568 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) … … 898 600 char *value = NULL; 899 601 900 char *nis_map = (char *)lp_ nis_home_map_name();602 char *nis_map = (char *)lp_homedir_map(); 901 603 902 604 char buffer[NIS_MAXATTRVAL + 1]; … … 950 652 int nis_result_len; /* and set this */ 951 653 char *nis_domain; /* yp_get_default_domain inits this */ 952 char *nis_map = (char *)lp_nis_home_map_name();654 char *nis_map = lp_homedir_map(talloc_tos()); 953 655 954 656 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) { … … 987 689 #endif 988 690 989 /****************************************************************************990 Check if a process exists. Does this work on all unixes?991 ****************************************************************************/992 993 691 bool process_exists(const struct server_id pid) 994 692 { 995 if (procid_is_me(&pid)) { 996 return True; 997 } 998 999 if (procid_is_local(&pid)) { 1000 return (kill(pid.pid,0) == 0 || errno != ESRCH); 1001 } 1002 1003 #ifdef CLUSTER_SUPPORT 1004 return ctdbd_process_exists(messaging_ctdbd_connection(), 1005 pid.vnn, pid.pid); 1006 #else 1007 return False; 1008 #endif 693 return serverid_exists(&pid); 1009 694 } 1010 695 … … 1088 773 return g; 1089 774 1090 grp = sys_getgrnam(name);775 grp = getgrnam(name); 1091 776 if (grp) 1092 777 return(grp->gr_gid); … … 1098 783 ********************************************************************/ 1099 784 1100 void smb_panic (const char *constwhy)785 void smb_panic_s3(const char *why) 1101 786 { 1102 787 char *cmd; 1103 788 int result; 1104 789 1105 #ifdef DEVELOPER 1106 {1107 1108 if (global_clobber_region_function) { 1109 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n", 1110 global_clobber_region_function,1111 global_clobber_region_line));1112 }1113 }790 DEBUG(0,("PANIC (pid %llu): %s\n", 791 (unsigned long long)getpid(), why)); 792 log_stack_trace(); 793 794 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER) 795 /* 796 * Make sure all children can attach a debugger. 797 */ 798 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0); 1114 799 #endif 1115 800 1116 DEBUG(0,("PANIC (pid %llu): %s\n", 1117 (unsigned long long)sys_getpid(), why)); 1118 log_stack_trace(); 1119 1120 cmd = lp_panic_action(); 801 cmd = lp_panic_action(talloc_tos()); 1121 802 if (cmd && *cmd) { 1122 803 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); … … 1277 958 ********************************************************************/ 1278 959 1279 const char *readdirname( SMB_STRUCT_DIR *p)1280 { 1281 SMB_STRUCT_DIRENT*ptr;960 const char *readdirname(DIR *p) 961 { 962 struct dirent *ptr; 1282 963 char *dname; 1283 964 … … 1285 966 return(NULL); 1286 967 1287 ptr = ( SMB_STRUCT_DIRENT *)sys_readdir(p);968 ptr = (struct dirent *)readdir(p); 1288 969 if (!ptr) 1289 970 return(NULL); … … 1336 1017 } else { 1337 1018 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))|| 1338 (!case_sensitive && ( StrCaseCmp(last_component, namelist->name) == 0))) {1019 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) { 1339 1020 DEBUG(8,("is_in_path: match succeeded\n")); 1340 1021 return True; … … 1352 1033 speed so we can pre-parse all the names in the list 1353 1034 and don't do it for each call to is_in_path(). 1354 namelist is modified here and is assumed to be1355 a copy owned by the caller.1356 1035 We also check if the entry contains a wildcard to 1357 1036 remove a potentially expensive call to mask_match … … 1359 1038 ********************************************************************/ 1360 1039 1361 void set_namearray(name_compare_entry **ppname_array, const char *namelist )1040 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in) 1362 1041 { 1363 1042 char *name_end; 1364 char *nameptr = (char *)namelist; 1043 char *namelist; 1044 char *namelist_end; 1045 char *nameptr; 1365 1046 int num_entries = 0; 1366 1047 int i; … … 1368 1049 (*ppname_array) = NULL; 1369 1050 1370 if((name ptr == NULL ) || ((nameptr != NULL) && (*nameptr== '\0')))1051 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0'))) 1371 1052 return; 1053 1054 namelist = talloc_strdup(talloc_tos(), namelist_in); 1055 if (namelist == NULL) { 1056 DEBUG(0,("set_namearray: talloc fail\n")); 1057 return; 1058 } 1059 nameptr = namelist; 1060 1061 namelist_end = &namelist[strlen(namelist)]; 1372 1062 1373 1063 /* We need to make two passes over the string. The … … 1376 1066 */ 1377 1067 1378 while( *nameptr) {1068 while(nameptr <= namelist_end) { 1379 1069 if ( *nameptr == '/' ) { 1380 1070 /* cope with multiple (useless) /s) */ … … 1388 1078 /* find the next '/' or consume remaining */ 1389 1079 name_end = strchr_m(nameptr, '/'); 1390 if (name_end == NULL) 1391 name_end = (char *)nameptr + strlen(nameptr); 1392 1393 /* next segment please */ 1394 nameptr = name_end + 1; 1080 if (name_end == NULL) { 1081 /* Point nameptr at the terminating '\0' */ 1082 nameptr += strlen(nameptr); 1083 } else { 1084 /* next segment please */ 1085 nameptr = name_end + 1; 1086 } 1395 1087 num_entries++; 1396 1088 } 1397 1089 1398 if(num_entries == 0) 1090 if(num_entries == 0) { 1091 talloc_free(namelist); 1399 1092 return; 1093 } 1400 1094 1401 1095 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) { 1402 1096 DEBUG(0,("set_namearray: malloc fail\n")); 1097 talloc_free(namelist); 1403 1098 return; 1404 1099 } 1405 1100 1406 1101 /* Now copy out the names */ 1407 nameptr = (char *)namelist;1102 nameptr = namelist; 1408 1103 i = 0; 1409 while( *nameptr) {1104 while(nameptr <= namelist_end) { 1410 1105 if ( *nameptr == '/' ) { 1411 1106 /* cope with multiple (useless) /s) */ … … 1419 1114 /* find the next '/' or consume remaining */ 1420 1115 name_end = strchr_m(nameptr, '/'); 1421 if (name_end )1116 if (name_end != NULL) { 1422 1117 *name_end = '\0'; 1423 else 1424 name_end = nameptr + strlen(nameptr); 1118 } 1425 1119 1426 1120 (*ppname_array)[i].is_wild = ms_has_wild(nameptr); 1427 1121 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) { 1428 1122 DEBUG(0,("set_namearray: malloc fail (1)\n")); 1123 talloc_free(namelist); 1429 1124 return; 1430 1125 } 1431 1126 1432 /* next segment please */ 1433 nameptr = name_end + 1; 1127 if (name_end == NULL) { 1128 /* Point nameptr at the terminating '\0' */ 1129 nameptr += strlen(nameptr); 1130 } else { 1131 /* next segment please */ 1132 nameptr = name_end + 1; 1133 } 1434 1134 i++; 1435 1135 } … … 1437 1137 (*ppname_array)[i].name = NULL; 1438 1138 1139 talloc_free(namelist); 1439 1140 return; 1440 }1441 1442 /****************************************************************************1443 Routine to free a namearray.1444 ****************************************************************************/1445 1446 void free_namearray(name_compare_entry *name_array)1447 {1448 int i;1449 1450 if(name_array == NULL)1451 return;1452 1453 for(i=0; name_array[i].name!=NULL; i++)1454 SAFE_FREE(name_array[i].name);1455 SAFE_FREE(name_array);1456 1141 } 1457 1142 … … 1466 1151 ****************************************************************************/ 1467 1152 1468 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T*pcount, int *ptype, pid_t *ppid)1469 { 1470 SMB_STRUCT_FLOCKlock;1153 bool fcntl_getlock(int fd, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid) 1154 { 1155 struct flock lock; 1471 1156 int ret; 1472 1157 … … 1480 1165 lock.l_pid = 0; 1481 1166 1482 ret = sys_fcntl_ptr(fd, SMB_F_GETLK,&lock);1167 ret = sys_fcntl_ptr(fd,F_GETLK,&lock); 1483 1168 1484 1169 if (ret == -1) { … … 1514 1199 1515 1200 for (n=0; my_netbios_names(n); n++) { 1516 if (strequal(my_netbios_names(n), s)) { 1201 const char *nbt_name = my_netbios_names(n); 1202 1203 if (strncasecmp_m(nbt_name, s, MAX_NETBIOSNAME_LEN-1) == 0) { 1517 1204 ret=True; 1518 1205 break; … … 1520 1207 } 1521 1208 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); 1522 return(ret);1523 }1524 1525 /*******************************************************************1526 Is the name specified our workgroup/domain.1527 Returns true if it is equal, false otherwise.1528 ********************************************************************/1529 1530 bool is_myworkgroup(const char *s)1531 {1532 bool ret = False;1533 1534 if (strequal(s, lp_workgroup())) {1535 ret=True;1536 }1537 1538 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));1539 1209 return(ret); 1540 1210 } … … 1653 1323 int str_checksum(const char *s) 1654 1324 { 1655 TDB_DATA key = string_tdb_data(s); 1325 TDB_DATA key; 1326 if (s == NULL) 1327 return 0; 1328 1329 key = (TDB_DATA) { .dptr = discard_const_p(uint8_t, s), 1330 .dsize = strlen(s) }; 1331 1656 1332 return tdb_jenkins_hash(&key); 1657 1333 } … … 1803 1479 } 1804 1480 1805 /** 1806 * @brief Returns an absolute path to a file concatenating the provided 1807 * @a rootpath and @a basename 1808 * 1809 * @param name Filename, relative to @a rootpath 1810 * 1811 * @retval Pointer to a string containing the full path. 1812 **/ 1813 1814 static char *xx_path(const char *name, const char *rootpath) 1815 { 1816 char *fname = NULL; 1817 1818 fname = talloc_strdup(talloc_tos(), rootpath); 1819 if (!fname) { 1820 return NULL; 1821 } 1822 trim_string(fname,"","/"); 1823 1824 if (!directory_exist(fname)) { 1825 if (!mkdir(fname,0755)) 1826 DEBUG(1, ("Unable to create directory %s for file %s. " 1827 "Error was %s\n", fname, name, strerror(errno))); 1828 } 1829 1830 return talloc_asprintf(talloc_tos(), 1831 "%s/%s", 1832 fname, 1833 name); 1834 } 1835 1836 /** 1837 * @brief Returns an absolute path to a file in the Samba lock directory. 1838 * 1839 * @param name File to find, relative to LOCKDIR. 1840 * 1841 * @retval Pointer to a talloc'ed string containing the full path. 1842 **/ 1843 1844 char *lock_path(const char *name) 1845 { 1846 return xx_path(name, lp_lockdir()); 1847 } 1848 1849 /** 1850 * @brief Returns an absolute path to a file in the Samba pid directory. 1851 * 1852 * @param name File to find, relative to PIDDIR. 1853 * 1854 * @retval Pointer to a talloc'ed string containing the full path. 1855 **/ 1856 1857 char *pid_path(const char *name) 1858 { 1859 return xx_path(name, lp_piddir()); 1860 } 1861 1862 /** 1863 * @brief Returns an absolute path to a file in the Samba lib directory. 1864 * 1865 * @param name File to find, relative to LIBDIR. 1866 * 1867 * @retval Pointer to a string containing the full path. 1868 **/ 1869 1870 char *lib_path(const char *name) 1871 { 1872 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name); 1873 } 1874 1875 /** 1876 * @brief Returns an absolute path to a file in the Samba modules directory. 1877 * 1878 * @param name File to find, relative to MODULESDIR. 1879 * 1880 * @retval Pointer to a string containing the full path. 1881 **/ 1882 1883 char *modules_path(const char *name) 1884 { 1885 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name); 1886 } 1887 1888 /** 1889 * @brief Returns an absolute path to a file in the Samba data directory. 1890 * 1891 * @param name File to find, relative to CODEPAGEDIR. 1892 * 1893 * @retval Pointer to a talloc'ed string containing the full path. 1894 **/ 1895 1896 char *data_path(const char *name) 1897 { 1898 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name); 1899 } 1900 1901 /** 1902 * @brief Returns an absolute path to a file in the Samba state directory. 1903 * 1904 * @param name File to find, relative to STATEDIR. 1905 * 1906 * @retval Pointer to a talloc'ed string containing the full path. 1907 **/ 1908 1909 char *state_path(const char *name) 1910 { 1911 return xx_path(name, lp_statedir()); 1912 } 1913 1914 /** 1915 * @brief Returns an absolute path to a file in the Samba cache directory. 1916 * 1917 * @param name File to find, relative to CACHEDIR. 1918 * 1919 * @retval Pointer to a talloc'ed string containing the full path. 1920 **/ 1921 1922 char *cache_path(const char *name) 1923 { 1924 return xx_path(name, lp_cachedir()); 1925 } 1926 1927 /** 1928 * @brief Returns the platform specific shared library extension. 1929 * 1930 * @retval Pointer to a const char * containing the extension. 1931 **/ 1932 1933 const char *shlib_ext(void) 1934 { 1935 return get_dyn_SHLIBEXT(); 1481 /***************************************************************** 1482 Get local hostname and cache result. 1483 *****************************************************************/ 1484 1485 char *myhostname_upper(void) 1486 { 1487 static char *ret; 1488 if (ret == NULL) { 1489 char *name = get_myname(NULL); 1490 if (name == NULL) { 1491 return NULL; 1492 } 1493 ret = strupper_talloc(NULL, name); 1494 talloc_free(name); 1495 } 1496 return ret; 1936 1497 } 1937 1498 … … 1960 1521 len = p-dir; 1961 1522 1962 if (!(*parent = (char *) TALLOC_MEMDUP(mem_ctx, dir, len+1))) {1523 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) { 1963 1524 return False; 1964 1525 } … … 1978 1539 { 1979 1540 char c; 1980 1981 if (lp_posix_pathnames()) {1982 /* With posix pathnames no characters are wild. */1983 return False;1984 }1985 1541 1986 1542 while ((c = *s++)) { … … 2179 1735 return false; 2180 1736 } 2181 strlower_m(p2); 2182 strlower_m(s2); 1737 if (!strlower_m(p2)) { 1738 TALLOC_FREE(ctx); 1739 return false; 1740 } 1741 if (!strlower_m(s2)) { 1742 TALLOC_FREE(ctx); 1743 return false; 1744 } 2183 1745 2184 1746 /* Remove any *? and ** from the pattern as they are meaningless */ … … 2200 1762 2201 1763 /********************************************************************** 2202 Converts a name to a fully qualified domain name. 2203 Returns true if lookup succeeded, false if not (then fqdn is set to name) 2204 Note we deliberately use gethostbyname here, not getaddrinfo as we want 2205 to examine the h_aliases and I don't know how to do that with getaddrinfo. 2206 ***********************************************************************/ 1764 Converts a name to a fully qualified domain name. 1765 Returns true if lookup succeeded, false if not (then fqdn is set to name) 1766 Uses getaddrinfo() with AI_CANONNAME flag to obtain the official 1767 canonical name of the host. getaddrinfo() may use a variety of sources 1768 including /etc/hosts to obtain the domainname. It expects aliases in 1769 /etc/hosts to NOT be the FQDN. The FQDN should come first. 1770 ************************************************************************/ 2207 1771 2208 1772 bool name_to_fqdn(fstring fqdn, const char *name) 2209 1773 { 2210 1774 char *full = NULL; 2211 struct hostent *hp = gethostbyname(name); 2212 2213 if (!hp || !hp->h_name || !*hp->h_name) { 1775 struct addrinfo hints; 1776 struct addrinfo *result; 1777 int s; 1778 1779 /* Configure hints to obtain canonical name */ 1780 1781 memset(&hints, 0, sizeof(struct addrinfo)); 1782 hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ 1783 hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ 1784 hints.ai_flags = AI_CANONNAME; /* Get host's FQDN */ 1785 hints.ai_protocol = 0; /* Any protocol */ 1786 1787 s = getaddrinfo(name, NULL, &hints, &result); 1788 if (s != 0) { 1789 DEBUG(1, ("getaddrinfo: %s\n", gai_strerror(s))); 2214 1790 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name)); 2215 1791 fstrcpy(fqdn, name); 2216 1792 return false; 2217 1793 } 2218 2219 /* Find out if the fqdn is returned as an alias 1794 full = result->ai_canonname; 1795 1796 /* Find out if the FQDN is returned as an alias 2220 1797 * to cope with /etc/hosts files where the first 2221 * name is not the fqdn but the short name */ 2222 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) { 2223 int i; 2224 for (i = 0; hp->h_aliases[i]; i++) { 2225 if (strchr_m(hp->h_aliases[i], '.')) { 2226 full = hp->h_aliases[i]; 2227 break; 2228 } 2229 } 2230 } 2231 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) { 1798 * name is not the FQDN but the short name. 1799 * getaddrinfo provides no easy way of handling aliases 1800 * in /etc/hosts. Users should make sure the FQDN 1801 * comes first in /etc/hosts. */ 1802 if (full && (! strchr_m(full, '.'))) { 2232 1803 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n")); 2233 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n")); 1804 DEBUGADD(1, (" Full qualified domain names (FQDNs) should not be specified\n")); 1805 DEBUGADD(1, (" as an alias in /etc/hosts. FQDN should be the first name\n")); 1806 DEBUGADD(1, (" prior to any aliases.\n")); 1807 } 1808 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) { 1809 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n")); 1810 DEBUGADD(1, (" Specifying the machine hostname for address 127.0.0.1 may lead\n")); 2234 1811 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n")); 2235 1812 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n")); 2236 full = hp->h_name;2237 }2238 if (!full) {2239 full = hp->h_name;2240 1813 } 2241 1814 2242 1815 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full)); 2243 1816 fstrcpy(fqdn, full); 1817 freeaddrinfo(result); /* No longer needed */ 2244 1818 return true; 2245 1819 } 2246 1820 2247 /********************************************************************** 2248 Append a DATA_BLOB to a talloc'ed object 2249 ***********************************************************************/ 2250 2251 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob) 2252 { 2253 size_t old_size = 0; 2254 char *result; 2255 2256 if (blob.length == 0) { 2257 return buf; 2258 } 2259 2260 if (buf != NULL) { 2261 old_size = talloc_get_size(buf); 2262 } 2263 2264 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length); 2265 if (result == NULL) { 2266 return NULL; 2267 } 2268 2269 memcpy(result + old_size, blob.data, blob.length); 2270 return result; 2271 } 2272 2273 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options) 1821 uint32_t map_share_mode_to_deny_mode(uint32_t share_access, uint32_t private_options) 2274 1822 { 2275 1823 switch (share_access & ~FILE_SHARE_DELETE) { … … 2289 1837 } 2290 1838 2291 return (uint32)-1; 2292 } 2293 2294 pid_t procid_to_pid(const struct server_id *proc) 2295 { 2296 return proc->pid; 2297 } 2298 2299 static uint32 my_vnn = NONCLUSTER_VNN; 2300 2301 void set_my_vnn(uint32 vnn) 2302 { 2303 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn)); 2304 my_vnn = vnn; 2305 } 2306 2307 uint32 get_my_vnn(void) 2308 { 2309 return my_vnn; 2310 } 2311 2312 static uint64_t my_unique_id = 0; 2313 2314 void set_my_unique_id(uint64_t unique_id) 2315 { 2316 my_unique_id = unique_id; 2317 } 2318 2319 struct server_id pid_to_procid(pid_t pid) 2320 { 2321 struct server_id result; 2322 result.pid = pid; 2323 result.unique_id = my_unique_id; 2324 result.vnn = my_vnn; 2325 return result; 2326 } 2327 2328 struct server_id procid_self(void) 2329 { 2330 return pid_to_procid(sys_getpid()); 2331 } 2332 2333 bool procid_equal(const struct server_id *p1, const struct server_id *p2) 2334 { 2335 if (p1->pid != p2->pid) 2336 return False; 2337 if (p1->vnn != p2->vnn) 2338 return False; 2339 return True; 2340 } 2341 2342 bool cluster_id_equal(const struct server_id *id1, 2343 const struct server_id *id2) 2344 { 2345 return procid_equal(id1, id2); 2346 } 2347 2348 bool procid_is_me(const struct server_id *pid) 2349 { 2350 if (pid->pid != sys_getpid()) 2351 return False; 2352 if (pid->vnn != my_vnn) 2353 return False; 2354 return True; 1839 return (uint32_t)-1; 2355 1840 } 2356 1841 2357 1842 struct server_id interpret_pid(const char *pid_string) 2358 1843 { 2359 struct server_id result; 2360 int pid; 2361 unsigned int vnn; 2362 if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) { 2363 result.vnn = vnn; 2364 result.pid = pid; 2365 } 2366 else if (sscanf(pid_string, "%d", &pid) == 1) { 2367 result.vnn = get_my_vnn(); 2368 result.pid = pid; 2369 } 2370 else { 2371 result.vnn = NONCLUSTER_VNN; 2372 result.pid = -1; 2373 } 2374 /* Assigning to result.pid may have overflowed 2375 Map negative pid to -1: i.e. error */ 2376 if (result.pid < 0) { 2377 result.pid = -1; 2378 } 2379 result.unique_id = 0; 2380 return result; 2381 } 2382 2383 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid) 2384 { 2385 if (pid->vnn == NONCLUSTER_VNN) { 2386 return talloc_asprintf(mem_ctx, 2387 "%d", 2388 (int)pid->pid); 2389 } 2390 else { 2391 return talloc_asprintf(mem_ctx, 2392 "%u:%d", 2393 (unsigned)pid->vnn, 2394 (int)pid->pid); 2395 } 2396 } 2397 2398 char *procid_str_static(const struct server_id *pid) 2399 { 2400 return procid_str(talloc_tos(), pid); 2401 } 2402 2403 bool procid_valid(const struct server_id *pid) 2404 { 2405 return (pid->pid != -1); 2406 } 2407 2408 bool procid_is_local(const struct server_id *pid) 2409 { 2410 return pid->vnn == my_vnn; 2411 } 2412 2413 /**************************************************************** 2414 Check if offset/length fit into bufsize. Should probably be 2415 merged with is_offset_safe, but this would require a rewrite 2416 of lanman.c. Later :-) 2417 ****************************************************************/ 2418 2419 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length) 2420 { 2421 if ((offset + length < offset) || (offset + length < length)) { 2422 /* wrap */ 2423 return true; 2424 } 2425 if ((offset > bufsize) || (offset + length > bufsize)) { 2426 /* overflow */ 2427 return true; 2428 } 2429 return false; 1844 return server_id_from_string(get_my_vnn(), pid_string); 2430 1845 } 2431 1846 … … 2537 1952 } 2538 1953 2539 #if 02540 2541 Disable these now we have checked all code paths and ensured2542 NULL returns on zero request. JRA.2543 2544 /****************************************************************2545 talloc wrapper functions that guarentee a null pointer return2546 if size == 0.2547 ****************************************************************/2548 2549 #ifndef MAX_TALLOC_SIZE2550 #define MAX_TALLOC_SIZE 0x100000002551 #endif2552 2553 /*2554 * talloc and zero memory.2555 * - returns NULL if size is zero.2556 */2557 2558 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)2559 {2560 void *p;2561 2562 if (size == 0) {2563 return NULL;2564 }2565 2566 p = talloc_named_const(ctx, size, name);2567 2568 if (p) {2569 memset(p, '\0', size);2570 }2571 2572 return p;2573 }2574 2575 /*2576 * memdup with a talloc.2577 * - returns NULL if size is zero.2578 */2579 2580 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)2581 {2582 void *newp;2583 2584 if (size == 0) {2585 return NULL;2586 }2587 2588 newp = talloc_named_const(t, size, name);2589 if (newp) {2590 memcpy(newp, p, size);2591 }2592 2593 return newp;2594 }2595 2596 /*2597 * alloc an array, checking for integer overflow in the array size.2598 * - returns NULL if count or el_size are zero.2599 */2600 2601 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)2602 {2603 if (count >= MAX_TALLOC_SIZE/el_size) {2604 return NULL;2605 }2606 2607 if (el_size == 0 || count == 0) {2608 return NULL;2609 }2610 2611 return talloc_named_const(ctx, el_size * count, name);2612 }2613 2614 /*2615 * alloc an zero array, checking for integer overflow in the array size2616 * - returns NULL if count or el_size are zero.2617 */2618 2619 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)2620 {2621 if (count >= MAX_TALLOC_SIZE/el_size) {2622 return NULL;2623 }2624 2625 if (el_size == 0 || count == 0) {2626 return NULL;2627 }2628 2629 return _talloc_zero(ctx, el_size * count, name);2630 }2631 2632 /*2633 * Talloc wrapper that returns NULL if size == 0.2634 */2635 void *talloc_zeronull(const void *context, size_t size, const char *name)2636 {2637 if (size == 0) {2638 return NULL;2639 }2640 return talloc_named_const(context, size, name);2641 }2642 #endif2643 2644 1954 /**************************************************************** 2645 1955 strip off leading '\\' from a hostname … … 2660 1970 2661 1971 return s; 2662 }2663 2664 bool tevent_req_poll_ntstatus(struct tevent_req *req,2665 struct tevent_context *ev,2666 NTSTATUS *status)2667 {2668 bool ret = tevent_req_poll(req, ev);2669 if (!ret) {2670 *status = map_nt_error_from_unix(errno);2671 }2672 return ret;2673 1972 } 2674 1973 … … 2748 2047 bool map_open_params_to_ntcreate(const char *smb_base_fname, 2749 2048 int deny_mode, int open_func, 2750 uint32 *paccess_mask,2751 uint32 *pshare_mode,2752 uint32 *pcreate_disposition,2753 uint32 *pcreate_options,2049 uint32_t *paccess_mask, 2050 uint32_t *pshare_mode, 2051 uint32_t *pcreate_disposition, 2052 uint32_t *pcreate_options, 2754 2053 uint32_t *pprivate_flags) 2755 2054 { 2756 uint32 access_mask;2757 uint32 share_mode;2758 uint32 create_disposition;2759 uint32 create_options = FILE_NON_DIRECTORY_FILE;2055 uint32_t access_mask; 2056 uint32_t share_mode; 2057 uint32_t create_disposition; 2058 uint32_t create_options = FILE_NON_DIRECTORY_FILE; 2760 2059 uint32_t private_flags = 0; 2761 2060 … … 2888 2187 2889 2188 } 2189 2190 /************************************************************************* 2191 Return a talloced copy of a struct security_unix_token. NULL on fail. 2192 *************************************************************************/ 2193 2194 struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok) 2195 { 2196 struct security_unix_token *cpy; 2197 2198 cpy = talloc(ctx, struct security_unix_token); 2199 if (!cpy) { 2200 return NULL; 2201 } 2202 2203 cpy->uid = tok->uid; 2204 cpy->gid = tok->gid; 2205 cpy->ngroups = tok->ngroups; 2206 if (tok->ngroups) { 2207 /* Make this a talloc child of cpy. */ 2208 cpy->groups = (gid_t *)talloc_memdup( 2209 cpy, tok->groups, tok->ngroups * sizeof(gid_t)); 2210 if (!cpy->groups) { 2211 TALLOC_FREE(cpy); 2212 return NULL; 2213 } 2214 } else { 2215 cpy->groups = NULL; 2216 } 2217 return cpy; 2218 } 2219 2220 /**************************************************************************** 2221 Check that a file matches a particular file type. 2222 ****************************************************************************/ 2223 2224 bool dir_check_ftype(uint32_t mode, uint32_t dirtype) 2225 { 2226 uint32_t mask; 2227 2228 /* Check the "may have" search bits. */ 2229 if (((mode & ~dirtype) & 2230 (FILE_ATTRIBUTE_HIDDEN | 2231 FILE_ATTRIBUTE_SYSTEM | 2232 FILE_ATTRIBUTE_DIRECTORY)) != 0) { 2233 return false; 2234 } 2235 2236 /* Check the "must have" bits, 2237 which are the may have bits shifted eight */ 2238 /* If must have bit is set, the file/dir can 2239 not be returned in search unless the matching 2240 file attribute is set */ 2241 mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY| 2242 FILE_ATTRIBUTE_ARCHIVE| 2243 FILE_ATTRIBUTE_READONLY| 2244 FILE_ATTRIBUTE_HIDDEN| 2245 FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */ 2246 if(mask) { 2247 if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY| 2248 FILE_ATTRIBUTE_ARCHIVE| 2249 FILE_ATTRIBUTE_READONLY| 2250 FILE_ATTRIBUTE_HIDDEN| 2251 FILE_ATTRIBUTE_SYSTEM))) == mask) { 2252 /* check if matching attribute present */ 2253 return true; 2254 } else { 2255 return false; 2256 } 2257 } 2258 2259 return true; 2260 }
Note:
See TracChangeset
for help on using the changeset viewer.