📄 util.c
字号:
}/******************************************************************* Reduce a file name, removing .. elements.********************************************************************/void dos_clean_name(char *s){ char *p=NULL; DEBUG(3,("dos_clean_name [%s]\n",s)); /* remove any double slashes */ all_string_sub(s, "\\\\", "\\", 0); while ((p = strstr_m(s,"\\..\\")) != NULL) { pstring s1; *p = 0; pstrcpy(s1,p+3); if ((p=strrchr_m(s,'\\')) != NULL) *p = 0; else *s = 0; pstrcat(s,s1); } trim_string(s,NULL,"\\.."); all_string_sub(s, "\\.\\", "\\", 0);}/******************************************************************* Reduce a file name, removing .. elements. ********************************************************************/void unix_clean_name(char *s){ char *p=NULL; DEBUG(3,("unix_clean_name [%s]\n",s)); /* remove any double slashes */ all_string_sub(s, "//","/", 0); /* Remove leading ./ characters */ if(strncmp(s, "./", 2) == 0) { trim_string(s, "./", NULL); if(*s == 0) pstrcpy(s,"./"); } while ((p = strstr_m(s,"/../")) != NULL) { pstring s1; *p = 0; pstrcpy(s1,p+3); if ((p=strrchr_m(s,'/')) != NULL) *p = 0; else *s = 0; pstrcat(s,s1); } trim_string(s,NULL,"/..");}/******************************************************************* Close the low 3 fd's and open dev/null in their place.********************************************************************/void close_low_fds(BOOL stderr_too){#ifndef VALGRIND int fd; int i; close(0); close(1); if (stderr_too) close(2); /* try and use up these file descriptors, so silly library routines writing to stdout etc won't cause havoc */ for (i=0;i<3;i++) { if (i == 2 && !stderr_too) continue; fd = sys_open("/dev/null",O_RDWR,0); if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0); if (fd < 0) { DEBUG(0,("Can't open /dev/null\n")); return; } if (fd != i) { DEBUG(0,("Didn't get file descriptor %d\n",i)); return; } }#endif}/******************************************************************* Write data into an fd at a given offset. Ignore seek errors.********************************************************************/ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos){ size_t total=0; ssize_t ret; if (pos == (SMB_OFF_T)-1) { return write_data(fd, buffer, N); }#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) while (total < N) { ret = sys_pwrite(fd,buffer + total,N - total, pos); if (ret == -1 && errno == ESPIPE) { return write_data(fd, buffer + total,N - total); } if (ret == -1) { DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) )); return -1; } if (ret == 0) { return total; } total += ret; pos += ret; } return (ssize_t)total;#else /* Use lseek and write_data. */ if (sys_lseek(fd, pos, SEEK_SET) == -1) { if (errno != ESPIPE) { return -1; } } return write_data(fd, buffer, N);#endif}/**************************************************************************** Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, else if SYSV use O_NDELAY if BSD use FNDELAY****************************************************************************/int set_blocking(int fd, BOOL set){ int val;#ifdef O_NONBLOCK#define FLAG_TO_SET O_NONBLOCK#else#ifdef SYSV#define FLAG_TO_SET O_NDELAY#else /* BSD */#define FLAG_TO_SET FNDELAY#endif#endif if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1) return -1; if(set) /* Turn blocking on - ie. clear nonblock flag */ val &= ~FLAG_TO_SET; else val |= FLAG_TO_SET; return sys_fcntl_long( fd, F_SETFL, val);#undef FLAG_TO_SET}/**************************************************************************** Transfer some data between two fd's.****************************************************************************/#ifndef TRANSFER_BUF_SIZE#define TRANSFER_BUF_SIZE 65536#endifssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t), ssize_t (*write_fn)(int, const void *, size_t)){ char *buf; size_t total = 0; ssize_t read_ret; ssize_t write_ret; size_t num_to_read_thistime; size_t num_written = 0; if ((buf = SMB_MALLOC(TRANSFER_BUF_SIZE)) == NULL) return -1; while (total < n) { num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); read_ret = (*read_fn)(infd, buf, num_to_read_thistime); if (read_ret == -1) { DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) )); SAFE_FREE(buf); return -1; } if (read_ret == 0) break; num_written = 0; while (num_written < read_ret) { write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written); if (write_ret == -1) { DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) )); SAFE_FREE(buf); return -1; } if (write_ret == 0) return (ssize_t)total; num_written += (size_t)write_ret; } total += (size_t)read_ret; } SAFE_FREE(buf); return (ssize_t)total; }SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n){ return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);}/******************************************************************* Sleep for a specified number of milliseconds.********************************************************************/void smb_msleep(unsigned int t){#if defined(HAVE_NANOSLEEP) struct timespec tval; int ret; tval.tv_sec = t/1000; tval.tv_nsec = 1000000*(t%1000); do { errno = 0; ret = nanosleep(&tval, &tval); } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));#else unsigned int tdiff=0; struct timeval tval,t1,t2; fd_set fds; GetTimeOfDay(&t1); t2 = t1; while (tdiff < t) { tval.tv_sec = (t-tdiff)/1000; tval.tv_usec = 1000*((t-tdiff)%1000); /* Never wait for more than 1 sec. */ if (tval.tv_sec > 1) { tval.tv_sec = 1; tval.tv_usec = 0; } FD_ZERO(&fds); errno = 0; sys_select_intr(0,&fds,NULL,NULL,&tval); GetTimeOfDay(&t2); if (t2.tv_sec < t1.tv_sec) { /* Someone adjusted time... */ t1 = t2; } tdiff = TvalDiff(&t1,&t2); }#endif}/**************************************************************************** Become a daemon, discarding the controlling terminal.****************************************************************************/void become_daemon(BOOL Fork){ if (Fork) { if (sys_fork()) { _exit(0); } } /* detach from the terminal */#ifdef HAVE_SETSID setsid();#elif defined(TIOCNOTTY) { int i = sys_open("/dev/tty", O_RDWR, 0); if (i != -1) { ioctl(i, (int) TIOCNOTTY, (char *)0); close(i); } }#endif /* HAVE_SETSID */ /* Close fd's 0,1,2. Needed if started by rsh */ close_low_fds(False); /* Don't close stderr, let the debug system attach it to the logfile */}/**************************************************************************** Put up a yes/no prompt.****************************************************************************/BOOL yesno(char *p){ pstring ans; printf("%s",p); if (!fgets(ans,sizeof(ans)-1,stdin)) return(False); if (*ans == 'y' || *ans == 'Y') return(True); return(False);}#if defined(PARANOID_MALLOC_CHECKER)/**************************************************************************** Internal malloc wrapper. Externally visible.****************************************************************************/void *malloc_(size_t size){#undef malloc return malloc(size);#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY}/**************************************************************************** Internal calloc wrapper. Not externally visible.****************************************************************************/static void *calloc_(size_t count, size_t size){#undef calloc return calloc(count, size);#define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY}/**************************************************************************** Internal realloc wrapper. Not externally visible.****************************************************************************/static void *realloc_(void *ptr, size_t size){#undef realloc return realloc(ptr, size);#define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY}#endif /* PARANOID_MALLOC_CHECKER *//**************************************************************************** Type-safe malloc.****************************************************************************/void *malloc_array(size_t el_size, unsigned int count){ if (count >= MAX_ALLOC_SIZE/el_size) { return NULL; }#if defined(PARANOID_MALLOC_CHECKER) return malloc_(el_size*count);#else return malloc(el_size*count);#endif}/**************************************************************************** Type-safe calloc.****************************************************************************/void *calloc_array(size_t size, size_t nmemb){ if (nmemb >= MAX_ALLOC_SIZE/size) { return NULL; }#if defined(PARANOID_MALLOC_CHECKER) return calloc_(nmemb, size);#else return calloc(nmemb, size);#endif}/**************************************************************************** Expand a pointer to be a particular size.****************************************************************************/void *Realloc(void *p,size_t size){ void *ret=NULL; if (size == 0) { SAFE_FREE(p); DEBUG(5,("Realloc asked for 0 bytes\n")); return NULL; }#if defined(PARANOID_MALLOC_CHECKER) if (!p) ret = (void *)malloc_(size); else ret = (void *)realloc_(p,size);#else if (!p) ret = (void *)malloc(size); else ret = (void *)realloc(p,size);#endif if (!ret) DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size)); return(ret);}/**************************************************************************** Type-safe realloc.****************************************************************************/void *realloc_array(void *p,size_t el_size, unsigned int count){ if (count >= MAX_ALLOC_SIZE/el_size) { return NULL; } return Realloc(p,el_size*count);}/**************************************************************************** (Hopefully) efficient array append****************************************************************************/void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, void *element, void **array, uint32 *num_elements, ssize_t *array_size){ if (*array_size < 0) return; if (*array == NULL) { if (*array_size == 0) { *array_size = 128; } if (*array_size >= MAX_ALLOC_SIZE/element_size) { goto error; } if (mem_ctx != NULL) *array = TALLOC(mem_ctx, element_size * (*array_size)); else *array = SMB_MALLOC(element_size * (*array_size)); if (*array == NULL) goto error; } if (*num_elements == *array_size) { *array_size *= 2; if (*array_size >= MAX_ALLOC_SIZE/element_size) { goto error; } if (mem_ctx != NULL) *array = TALLOC_REALLOC(mem_ctx, *array, element_size * (*array_size)); else *array = SMB_REALLOC(*array, element_size * (*array_size)); if (*array == NULL) goto error; } memcpy((char *)(*array) + element_size*(*num_elements), element, element_size); *num_elements += 1; return; error: *num_elements = 0; *array_size = -1;}/**************************************************************************** Free memory, checks for NULL. Use directly SAFE_FREE() Exists only because we need to pass a function pointer somewhere --SSS****************************************************************************/void safe_free(void *p){ SAFE_FREE(p);}/**************************************************************************** Get my own name and IP.****************************************************************************/BOOL get_myname(char *my_name){ pstring hostname; *hostname = 0; /* get my host name */ if (gethostname(hostname, sizeof(hostname)) == -1) { DEBUG(0,("gethostname failed\n")); return False; } /* Ensure null termination. */ hostname[sizeof(hostname)-1] = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -