2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
25 #ifdef WITH_NISPLUS_HOME
26 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
34 #undef Realloc /* SSLeay defines this and samba has a function of this name */
41 extern int DEBUGLEVEL;
45 int Protocol = PROTOCOL_COREPLUS;
47 /* a default finfo structure to ensure all fields are sensible */
48 file_info def_finfo = {-1,0,0,0,0,0,0,""};
50 /* the client file descriptor */
53 /* the last IP received from */
54 struct in_addr lastip;
56 /* the last port received from */
59 /* this is used by the chaining code */
65 case handling on filenames
67 int case_default = CASE_LOWER;
69 /* the following control case operations - they are put here so the
70 client can link easily */
73 BOOL use_mangled_map = False;
74 BOOL short_case_preserve;
77 fstring remote_machine="";
78 fstring local_machine="";
79 fstring remote_arch="UNKNOWN";
80 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 fstring remote_proto="UNKNOWN";
82 pstring myhostname="";
83 pstring user_socket_options="";
85 pstring sesssetup_user="";
86 pstring samlogon_user="";
88 BOOL sam_logon_in_ssb = False;
90 pstring global_myname = "";
91 fstring global_myworkgroup = "";
92 char **my_netbios_names;
94 int smb_read_error = 0;
96 static char *filename_dos(char *path,char *buf);
100 /****************************************************************************
101 find a suitable temporary directory. The result should be copied immediately
102 as it may be overwritten by a subsequent call
103 ****************************************************************************/
107 if ((p = getenv("TMPDIR"))) {
115 /****************************************************************************
116 determine if a file descriptor is in fact a socket
117 ****************************************************************************/
118 BOOL is_a_socket(int fd)
122 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
126 static char *last_ptr=NULL;
128 /****************************************************************************
129 Get the next token from a string, return False if none found
130 handles double-quotes.
131 Based on a routine by GJC@VILLAGE.COM.
132 Extensively modified by Andrew.Tridgell@anu.edu.au
133 ****************************************************************************/
134 BOOL next_token(char **ptr,char *buff,char *sep)
139 if (!ptr) ptr = &last_ptr;
140 if (!ptr) return(False);
144 /* default to simple separators */
145 if (!sep) sep = " \t\n\r";
147 /* find the first non sep char */
148 while(*s && strchr(sep,*s)) s++;
151 if (! *s) return(False);
153 /* copy over the token */
154 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
162 *ptr = (*s) ? s+1 : s;
169 /****************************************************************************
170 Convert list of tokens to array; dependent on above routine.
171 Uses last_ptr from above - bit of a hack.
172 ****************************************************************************/
173 char **toktocliplist(int *ctok, char *sep)
179 if (!sep) sep = " \t\n\r";
181 while(*s && strchr(sep,*s)) s++;
184 if (!*s) return(NULL);
188 while(*s && (!strchr(sep,*s))) s++;
189 while(*s && strchr(sep,*s)) *s++=0;
195 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
207 /* ************************************************************************* **
208 * Duplicate a block of memory.
209 * ************************************************************************* **
211 void *mem_dup( void *from, int size )
215 tmp = malloc( size );
217 (void)memcpy( tmp, from, size );
221 /****************************************************************************
222 prompte a dptr (to make it recently used)
223 ****************************************************************************/
224 void array_promote(char *array,int elsize,int element)
230 p = (char *)malloc(elsize);
234 DEBUG(5,("Ahh! Can't malloc\n"));
237 memcpy(p,array + element * elsize, elsize);
238 memmove(array + elsize,array,elsize*element);
239 memcpy(array,p,elsize);
243 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
252 } socket_options[] = {
253 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
254 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
255 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
257 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
259 #ifdef IPTOS_LOWDELAY
260 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
262 #ifdef IPTOS_THROUGHPUT
263 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
266 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
269 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
272 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
275 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
278 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
281 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
287 /****************************************************************************
288 set user socket options
289 ****************************************************************************/
290 void set_socket_options(int fd, char *options)
294 while (next_token(&options,tok," \t,"))
299 BOOL got_value = False;
301 if ((p = strchr(tok,'=')))
308 for (i=0;socket_options[i].name;i++)
309 if (strequal(socket_options[i].name,tok))
312 if (!socket_options[i].name)
314 DEBUG(0,("Unknown socket option %s\n",tok));
318 switch (socket_options[i].opttype)
322 ret = setsockopt(fd,socket_options[i].level,
323 socket_options[i].option,(char *)&value,sizeof(int));
328 DEBUG(0,("syntax error - %s does not take a value\n",tok));
331 int on = socket_options[i].value;
332 ret = setsockopt(fd,socket_options[i].level,
333 socket_options[i].option,(char *)&on,sizeof(int));
339 DEBUG(0,("Failed to set socket option %s\n",tok));
345 /****************************************************************************
346 close the socket communication
347 ****************************************************************************/
348 void close_sockets(void )
351 sslutil_disconnect(Client);
352 #endif /* WITH_SSL */
358 /****************************************************************************
359 determine whether we are in the specified group
360 ****************************************************************************/
361 BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
365 if (group == current_gid) return(True);
367 for (i=0;i<ngroups;i++)
368 if (group == groups[i])
374 /****************************************************************************
375 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
376 ****************************************************************************/
377 char *StrCpy(char *dest,char *src)
382 /* I don't want to get lazy with these ... */
384 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
389 if (!dest) return(NULL);
394 while ((*d++ = *src++)) ;
398 /****************************************************************************
399 line strncpy but always null terminates. Make sure there is room!
400 ****************************************************************************/
401 char *StrnCpy(char *dest,char *src,int n)
404 if (!dest) return(NULL);
409 while (n-- && (*d++ = *src++)) ;
415 /*******************************************************************
416 copy an IP address from one buffer to another
417 ********************************************************************/
418 void putip(void *dest,void *src)
424 /****************************************************************************
425 interpret the weird netbios "name". Return the name type
426 ****************************************************************************/
427 static int name_interpret(char *in,char *out)
430 int len = (*in++) / 2;
434 if (len > 30 || len<1) return(0);
438 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
442 *out = ((in[0]-'A')<<4) + (in[1]-'A');
450 /* Handle any scope names */
453 *out++ = '.'; /* Scope names are separated by periods */
454 len = *(unsigned char *)in++;
455 StrnCpy(out, in, len);
464 /****************************************************************************
465 mangle a name into netbios format
467 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
468 ****************************************************************************/
469 int name_mangle( char *In, char *Out, char name_type )
477 /* Safely copy the input string, In, into buf[]. */
478 (void)memset( buf, 0, 20 );
482 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
484 /* Place the length of the first field into the output buffer. */
488 /* Now convert the name to the rfc1001/1002 format. */
489 for( i = 0; i < 16; i++ )
491 c = toupper( buf[i] );
492 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
493 p[(i*2)+1] = (c & 0x000F) + 'A';
498 /* Add the scope string. */
499 for( i = 0, len = 0; NULL != scope; i++, len++ )
507 return( name_len(Out) );
519 return( name_len(Out) );
522 /*******************************************************************
523 check if a file exists
524 ********************************************************************/
525 BOOL file_exist(char *fname,struct stat *sbuf)
528 if (!sbuf) sbuf = &st;
530 if (sys_stat(fname,sbuf) != 0)
533 return(S_ISREG(sbuf->st_mode));
536 /*******************************************************************
537 check a files mod time
538 ********************************************************************/
539 time_t file_modtime(char *fname)
543 if (sys_stat(fname,&st) != 0)
549 /*******************************************************************
550 check if a directory exists
551 ********************************************************************/
552 BOOL directory_exist(char *dname,struct stat *st)
559 if (sys_stat(dname,st) != 0)
562 ret = S_ISDIR(st->st_mode);
568 /*******************************************************************
569 returns the size in bytes of the named file
570 ********************************************************************/
571 uint32 file_size(char *file_name)
575 sys_stat(file_name,&buf);
579 /*******************************************************************
580 return a string representing an attribute for a file
581 ********************************************************************/
582 char *attrib_string(int mode)
584 static fstring attrstr;
588 if (mode & aVOLID) fstrcat(attrstr,"V");
589 if (mode & aDIR) fstrcat(attrstr,"D");
590 if (mode & aARCH) fstrcat(attrstr,"A");
591 if (mode & aHIDDEN) fstrcat(attrstr,"H");
592 if (mode & aSYSTEM) fstrcat(attrstr,"S");
593 if (mode & aRONLY) fstrcat(attrstr,"R");
599 /*******************************************************************
600 case insensitive string compararison
601 ********************************************************************/
602 int StrCaseCmp(char *s, char *t)
604 /* compare until we run out of string, either t or s, or find a difference */
605 /* We *must* use toupper rather than tolower here due to the
606 asynchronous upper to lower mapping.
608 #if !defined(KANJI_WIN95_COMPATIBILITY)
610 * For completeness we should put in equivalent code for code pages
611 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
612 * doubt anyone wants Samba to behave differently from Win95 and WinNT
613 * here. They both treat full width ascii characters as case senstive
614 * filenames (ie. they don't do the work we do here).
618 if(lp_client_code_page() == KANJI_CODEPAGE)
620 /* Win95 treats full width ascii characters as case sensitive. */
625 return toupper (*s) - toupper (*t);
626 else if (is_sj_alph (*s) && is_sj_alph (*t))
628 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
634 else if (is_shift_jis (*s) && is_shift_jis (*t))
636 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
639 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
645 else if (is_shift_jis (*s))
647 else if (is_shift_jis (*t))
651 diff = toupper (*s) - toupper (*t);
660 #endif /* KANJI_WIN95_COMPATIBILITY */
662 while (*s && *t && toupper(*s) == toupper(*t))
668 return(toupper(*s) - toupper(*t));
672 /*******************************************************************
673 case insensitive string compararison, length limited
674 ********************************************************************/
675 int StrnCaseCmp(char *s, char *t, int n)
677 /* compare until we run out of string, either t or s, or chars */
678 /* We *must* use toupper rather than tolower here due to the
679 asynchronous upper to lower mapping.
681 #if !defined(KANJI_WIN95_COMPATIBILITY)
683 * For completeness we should put in equivalent code for code pages
684 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
685 * doubt anyone wants Samba to behave differently from Win95 and WinNT
686 * here. They both treat full width ascii characters as case senstive
687 * filenames (ie. they don't do the work we do here).
691 if(lp_client_code_page() == KANJI_CODEPAGE)
693 /* Win95 treats full width ascii characters as case sensitive. */
698 return toupper (*s) - toupper (*t);
699 else if (is_sj_alph (*s) && is_sj_alph (*t))
701 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
708 else if (is_shift_jis (*s) && is_shift_jis (*t))
710 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
713 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
720 else if (is_shift_jis (*s))
722 else if (is_shift_jis (*t))
726 diff = toupper (*s) - toupper (*t);
737 #endif /* KANJI_WIN95_COMPATIBILITY */
739 while (n && *s && *t && toupper(*s) == toupper(*t))
746 /* not run out of chars - strings are different lengths */
748 return(toupper(*s) - toupper(*t));
750 /* identical up to where we run out of chars,
751 and strings are same length */
756 /*******************************************************************
758 ********************************************************************/
759 BOOL strequal(char *s1, char *s2)
761 if (s1 == s2) return(True);
762 if (!s1 || !s2) return(False);
764 return(StrCaseCmp(s1,s2)==0);
767 /*******************************************************************
768 compare 2 strings up to and including the nth char.
769 ******************************************************************/
770 BOOL strnequal(char *s1,char *s2,int n)
772 if (s1 == s2) return(True);
773 if (!s1 || !s2 || !n) return(False);
775 return(StrnCaseCmp(s1,s2,n)==0);
778 /*******************************************************************
779 compare 2 strings (case sensitive)
780 ********************************************************************/
781 BOOL strcsequal(char *s1,char *s2)
783 if (s1 == s2) return(True);
784 if (!s1 || !s2) return(False);
786 return(strcmp(s1,s2)==0);
790 /*******************************************************************
791 convert a string to lower case
792 ********************************************************************/
793 void strlower(char *s)
797 #if !defined(KANJI_WIN95_COMPATIBILITY)
799 * For completeness we should put in equivalent code for code pages
800 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
801 * doubt anyone wants Samba to behave differently from Win95 and WinNT
802 * here. They both treat full width ascii characters as case senstive
803 * filenames (ie. they don't do the work we do here).
807 if(lp_client_code_page() == KANJI_CODEPAGE)
809 /* Win95 treats full width ascii characters as case sensitive. */
810 if (is_shift_jis (*s))
812 if (is_sj_upper (s[0], s[1]))
813 s[1] = sj_tolower2 (s[1]);
816 else if (is_kana (*s))
828 #endif /* KANJI_WIN95_COMPATIBILITY */
830 int skip = skip_multibyte_char( *s );
843 /*******************************************************************
844 convert a string to upper case
845 ********************************************************************/
846 void strupper(char *s)
850 #if !defined(KANJI_WIN95_COMPATIBILITY)
852 * For completeness we should put in equivalent code for code pages
853 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
854 * doubt anyone wants Samba to behave differently from Win95 and WinNT
855 * here. They both treat full width ascii characters as case senstive
856 * filenames (ie. they don't do the work we do here).
860 if(lp_client_code_page() == KANJI_CODEPAGE)
862 /* Win95 treats full width ascii characters as case sensitive. */
863 if (is_shift_jis (*s))
865 if (is_sj_lower (s[0], s[1]))
866 s[1] = sj_toupper2 (s[1]);
869 else if (is_kana (*s))
881 #endif /* KANJI_WIN95_COMPATIBILITY */
883 int skip = skip_multibyte_char( *s );
896 /*******************************************************************
897 convert a string to "normal" form
898 ********************************************************************/
899 void strnorm(char *s)
901 if (case_default == CASE_UPPER)
907 /*******************************************************************
908 check if a string is in "normal" case
909 ********************************************************************/
910 BOOL strisnormal(char *s)
912 if (case_default == CASE_UPPER)
913 return(!strhaslower(s));
915 return(!strhasupper(s));
919 /****************************************************************************
921 ****************************************************************************/
922 void string_replace(char *s,char oldc,char newc)
927 skip = skip_multibyte_char( *s );
939 /****************************************************************************
940 make a file into unix format
941 ****************************************************************************/
942 void unix_format(char *fname)
945 string_replace(fname,'\\','/');
949 pstrcpy(namecopy,fname);
951 pstrcat(fname,namecopy);
955 /****************************************************************************
956 make a file into dos format
957 ****************************************************************************/
958 void dos_format(char *fname)
960 string_replace(fname,'/','\\');
963 /*******************************************************************
964 show a smb message structure
965 ********************************************************************/
966 void show_msg(char *buf)
971 if (DEBUGLEVEL < 5) return;
973 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
975 (int)CVAL(buf,smb_com),
976 (int)CVAL(buf,smb_rcls),
977 (int)CVAL(buf,smb_reh),
978 (int)SVAL(buf,smb_err),
979 (int)CVAL(buf,smb_flg),
980 (int)SVAL(buf,smb_flg2)));
981 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
982 (int)SVAL(buf,smb_tid),
983 (int)SVAL(buf,smb_pid),
984 (int)SVAL(buf,smb_uid),
985 (int)SVAL(buf,smb_mid),
986 (int)CVAL(buf,smb_wct)));
988 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
990 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
991 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
994 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
996 DEBUG(5,("smb_bcc=%d\n",bcc));
998 if (DEBUGLEVEL < 10) return;
1000 if (DEBUGLEVEL < 50)
1002 bcc = MIN(bcc, 512);
1005 dump_data(10, smb_buf(buf), bcc);
1007 /*******************************************************************
1008 return the length of an smb packet
1009 ********************************************************************/
1010 int smb_len(char *buf)
1012 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1015 /*******************************************************************
1016 set the length of an smb packet
1017 ********************************************************************/
1018 void _smb_setlen(char *buf,int len)
1021 buf[1] = (len&0x10000)>>16;
1022 buf[2] = (len&0xFF00)>>8;
1026 /*******************************************************************
1027 set the length and marker of an smb packet
1028 ********************************************************************/
1029 void smb_setlen(char *buf,int len)
1031 _smb_setlen(buf,len);
1039 /*******************************************************************
1040 setup the word count and byte count for a smb message
1041 ********************************************************************/
1042 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1045 bzero(buf + smb_size,num_words*2 + num_bytes);
1046 CVAL(buf,smb_wct) = num_words;
1047 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1048 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1049 return (smb_size + num_words*2 + num_bytes);
1052 /*******************************************************************
1053 return the number of smb words
1054 ********************************************************************/
1055 int smb_numwords(char *buf)
1057 return (CVAL(buf,smb_wct));
1060 /*******************************************************************
1061 return the size of the smb_buf region of a message
1062 ********************************************************************/
1063 int smb_buflen(char *buf)
1065 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1068 /*******************************************************************
1069 return a pointer to the smb_buf data area
1070 ********************************************************************/
1071 int smb_buf_ofs(char *buf)
1073 return (smb_size + CVAL(buf,smb_wct)*2);
1076 /*******************************************************************
1077 return a pointer to the smb_buf data area
1078 ********************************************************************/
1079 char *smb_buf(char *buf)
1081 return (buf + smb_buf_ofs(buf));
1084 /*******************************************************************
1085 return the SMB offset into an SMB buffer
1086 ********************************************************************/
1087 int smb_offset(char *p,char *buf)
1089 return(PTR_DIFF(p,buf+4) + chain_size);
1093 /*******************************************************************
1094 skip past some strings in a buffer
1095 ********************************************************************/
1096 char *skip_string(char *buf,int n)
1099 buf += strlen(buf) + 1;
1103 /*******************************************************************
1104 trim the specified elements off the front and back of a string
1105 ********************************************************************/
1106 BOOL trim_string(char *s,char *front,char *back)
1109 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1115 if (!(*p = p[strlen(front)]))
1120 while (back && *back && strlen(s) >= strlen(back) &&
1121 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1124 s[strlen(s)-strlen(back)] = 0;
1130 /*******************************************************************
1131 reduce a file name, removing .. elements.
1132 ********************************************************************/
1133 void dos_clean_name(char *s)
1137 DEBUG(3,("dos_clean_name [%s]\n",s));
1139 /* remove any double slashes */
1140 string_sub(s, "\\\\", "\\");
1142 while ((p = strstr(s,"\\..\\")) != NULL)
1149 if ((p=strrchr(s,'\\')) != NULL)
1156 trim_string(s,NULL,"\\..");
1158 string_sub(s, "\\.\\", "\\");
1161 /*******************************************************************
1162 reduce a file name, removing .. elements.
1163 ********************************************************************/
1164 void unix_clean_name(char *s)
1168 DEBUG(3,("unix_clean_name [%s]\n",s));
1170 /* remove any double slashes */
1171 string_sub(s, "//","/");
1173 /* Remove leading ./ characters */
1174 if(strncmp(s, "./", 2) == 0) {
1175 trim_string(s, "./", NULL);
1180 while ((p = strstr(s,"/../")) != NULL)
1187 if ((p=strrchr(s,'/')) != NULL)
1194 trim_string(s,NULL,"/..");
1198 /*******************************************************************
1199 a wrapper for the normal chdir() function
1200 ********************************************************************/
1201 int ChDir(char *path)
1204 static pstring LastDir="";
1206 if (strcsequal(path,".")) return(0);
1208 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1209 DEBUG(3,("chdir to %s\n",path));
1210 res = sys_chdir(path);
1212 pstrcpy(LastDir,path);
1216 /* number of list structures for a caching GetWd function. */
1217 #define MAX_GETWDCACHE (50)
1225 } ino_list[MAX_GETWDCACHE];
1227 BOOL use_getwd_cache=True;
1229 /*******************************************************************
1230 return the absolute current directory path
1231 ********************************************************************/
1232 char *GetWd(char *str)
1235 static BOOL getwd_cache_init = False;
1236 struct stat st, st2;
1241 if (!use_getwd_cache)
1242 return(sys_getwd(str));
1244 /* init the cache */
1245 if (!getwd_cache_init)
1247 getwd_cache_init = True;
1248 for (i=0;i<MAX_GETWDCACHE;i++)
1250 string_init(&ino_list[i].text,"");
1251 ino_list[i].valid = False;
1255 /* Get the inode of the current directory, if this doesn't work we're
1258 if (stat(".",&st) == -1)
1260 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1261 return(sys_getwd(str));
1265 for (i=0; i<MAX_GETWDCACHE; i++)
1266 if (ino_list[i].valid)
1269 /* If we have found an entry with a matching inode and dev number
1270 then find the inode number for the directory in the cached string.
1271 If this agrees with that returned by the stat for the current
1272 directory then all is o.k. (but make sure it is a directory all
1275 if (st.st_ino == ino_list[i].inode &&
1276 st.st_dev == ino_list[i].dev)
1278 if (stat(ino_list[i].text,&st2) == 0)
1280 if (st.st_ino == st2.st_ino &&
1281 st.st_dev == st2.st_dev &&
1282 (st2.st_mode & S_IFMT) == S_IFDIR)
1284 pstrcpy (str, ino_list[i].text);
1286 /* promote it for future use */
1287 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1292 /* If the inode is different then something's changed,
1293 scrub the entry and start from scratch. */
1294 ino_list[i].valid = False;
1301 /* We don't have the information to hand so rely on traditional methods.
1302 The very slow getcwd, which spawns a process on some systems, or the
1303 not quite so bad getwd. */
1307 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1313 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1315 /* add it to the cache */
1316 i = MAX_GETWDCACHE - 1;
1317 string_set(&ino_list[i].text,s);
1318 ino_list[i].dev = st.st_dev;
1319 ino_list[i].inode = st.st_ino;
1320 ino_list[i].valid = True;
1322 /* put it at the top of the list */
1323 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1330 /*******************************************************************
1331 reduce a file name, removing .. elements and checking that
1332 it is below dir in the heirachy. This uses GetWd() and so must be run
1333 on the system that has the referenced file system.
1335 widelinks are allowed if widelinks is true
1336 ********************************************************************/
1337 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1339 #ifndef REDUCE_PATHS
1347 BOOL relative = (*s != '/');
1349 *dir2 = *wd = *base_name = *newname = 0;
1354 /* can't have a leading .. */
1355 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1357 DEBUG(3,("Illegal file name? (%s)\n",s));
1367 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1369 /* remove any double slashes */
1370 string_sub(s,"//","/");
1372 pstrcpy(base_name,s);
1373 p = strrchr(base_name,'/');
1380 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1384 if (ChDir(dir) != 0)
1386 DEBUG(0,("couldn't chdir to %s\n",dir));
1392 DEBUG(0,("couldn't getwd for %s\n",dir));
1398 if (p && (p != base_name))
1401 if (strcmp(p+1,".")==0)
1403 if (strcmp(p+1,"..")==0)
1407 if (ChDir(base_name) != 0)
1410 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1414 if (!GetWd(newname))
1417 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1421 if (p && (p != base_name))
1423 pstrcat(newname,"/");
1424 pstrcat(newname,p+1);
1428 int l = strlen(dir2);
1429 if (dir2[l-1] == '/')
1432 if (strncmp(newname,dir2,l) != 0)
1435 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1441 if (newname[l] == '/')
1442 pstrcpy(s,newname + l + 1);
1444 pstrcpy(s,newname+l);
1455 DEBUG(3,("reduced to %s\n",s));
1460 /****************************************************************************
1462 ****************************************************************************/
1463 static void expand_one(char *Mask,int len)
1466 while ((p1 = strchr(Mask,'*')) != NULL)
1468 int lfill = (len+1) - strlen(Mask);
1469 int l1= (p1 - Mask);
1472 memset(tmp+l1,'?',lfill);
1473 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1478 /****************************************************************************
1479 expand a wildcard expression, replacing *s with ?s
1480 ****************************************************************************/
1481 void expand_mask(char *Mask,BOOL doext)
1486 BOOL hasdot = False;
1488 BOOL absolute = (*Mask == '\\');
1490 *mbeg = *mext = *dirpart = *filepart = 0;
1492 /* parse the directory and filename */
1493 if (strchr(Mask,'\\'))
1494 dirname_dos(Mask,dirpart);
1496 filename_dos(Mask,filepart);
1498 pstrcpy(mbeg,filepart);
1499 if ((p1 = strchr(mbeg,'.')) != NULL)
1509 if (strlen(mbeg) > 8)
1511 pstrcpy(mext,mbeg + 8);
1517 pstrcpy(mbeg,"????????");
1518 if ((*mext == 0) && doext && !hasdot)
1519 pstrcpy(mext,"???");
1521 if (strequal(mbeg,"*") && *mext==0)
1529 pstrcpy(Mask,dirpart);
1530 if (*dirpart || absolute) pstrcat(Mask,"\\");
1535 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1539 /****************************************************************************
1540 does a string have any uppercase chars in it?
1541 ****************************************************************************/
1542 BOOL strhasupper(char *s)
1546 #if !defined(KANJI_WIN95_COMPATIBILITY)
1548 * For completeness we should put in equivalent code for code pages
1549 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1550 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1551 * here. They both treat full width ascii characters as case senstive
1552 * filenames (ie. they don't do the work we do here).
1556 if(lp_client_code_page() == KANJI_CODEPAGE)
1558 /* Win95 treats full width ascii characters as case sensitive. */
1559 if (is_shift_jis (*s))
1561 else if (is_kana (*s))
1571 #endif /* KANJI_WIN95_COMPATIBILITY */
1573 int skip = skip_multibyte_char( *s );
1586 /****************************************************************************
1587 does a string have any lowercase chars in it?
1588 ****************************************************************************/
1589 BOOL strhaslower(char *s)
1593 #if !defined(KANJI_WIN95_COMPATIBILITY)
1595 * For completeness we should put in equivalent code for code pages
1596 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1597 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1598 * here. They both treat full width ascii characters as case senstive
1599 * filenames (ie. they don't do the work we do here).
1603 if(lp_client_code_page() == KANJI_CODEPAGE)
1605 /* Win95 treats full width ascii characters as case sensitive. */
1606 if (is_shift_jis (*s))
1608 if (is_sj_upper (s[0], s[1]))
1610 if (is_sj_lower (s[0], s[1]))
1614 else if (is_kana (*s))
1626 #endif /* KANJI_WIN95_COMPATIBILITY */
1628 int skip = skip_multibyte_char( *s );
1641 /****************************************************************************
1642 find the number of chars in a string
1643 ****************************************************************************/
1644 int count_chars(char *s,char c)
1648 #if !defined(KANJI_WIN95_COMPATIBILITY)
1650 * For completeness we should put in equivalent code for code pages
1651 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1652 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1653 * here. They both treat full width ascii characters as case senstive
1654 * filenames (ie. they don't do the work we do here).
1658 if(lp_client_code_page() == KANJI_CODEPAGE)
1660 /* Win95 treats full width ascii characters as case sensitive. */
1663 if (is_shift_jis (*s))
1674 #endif /* KANJI_WIN95_COMPATIBILITY */
1678 int skip = skip_multibyte_char( *s );
1692 /****************************************************************************
1694 ****************************************************************************/
1695 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1700 pstrcpy(mask2,mask);
1702 if ((mode & aDIR) != 0)
1705 memset(buf+1,' ',11);
1706 if ((p = strchr(mask2,'.')) != NULL)
1709 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1710 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1714 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1716 bzero(buf+21,DIR_STRUCT_SIZE-21);
1717 CVAL(buf,21) = mode;
1718 put_dos_date(buf,22,date);
1719 SSVAL(buf,26,size & 0xFFFF);
1720 SSVAL(buf,28,size >> 16);
1721 StrnCpy(buf+30,fname,12);
1722 if (!case_sensitive)
1724 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1728 /*******************************************************************
1729 close the low 3 fd's and open dev/null in their place
1730 ********************************************************************/
1731 void close_low_fds(void)
1735 close(0); close(1); close(2);
1736 /* try and use up these file descriptors, so silly
1737 library routines writing to stdout etc won't cause havoc */
1739 fd = open("/dev/null",O_RDWR,0);
1740 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1742 DEBUG(0,("Can't open /dev/null\n"));
1746 DEBUG(0,("Didn't get file descriptor %d\n",i));
1752 /****************************************************************************
1753 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1755 if SYSV use O_NDELAY
1757 ****************************************************************************/
1758 int set_blocking(int fd, BOOL set)
1762 #define FLAG_TO_SET O_NONBLOCK
1765 #define FLAG_TO_SET O_NDELAY
1767 #define FLAG_TO_SET FNDELAY
1771 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1773 if(set) /* Turn blocking on - ie. clear nonblock flag */
1774 val &= ~FLAG_TO_SET;
1777 return fcntl( fd, F_SETFL, val);
1782 /****************************************************************************
1784 ****************************************************************************/
1785 int write_socket(int fd,char *buf,int len)
1791 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1792 ret = write_data(fd,buf,len);
1794 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1796 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
1797 len, fd, strerror(errno) ));
1802 /****************************************************************************
1804 ****************************************************************************/
1805 int read_udp_socket(int fd,char *buf,int len)
1808 struct sockaddr_in sock;
1811 socklen = sizeof(sock);
1812 bzero((char *)&sock,socklen);
1813 bzero((char *)&lastip,sizeof(lastip));
1814 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1816 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1820 lastip = sock.sin_addr;
1821 lastport = ntohs(sock.sin_port);
1823 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1824 inet_ntoa(lastip), lastport, ret));
1829 /****************************************************************************
1830 read data from a device with a timout in msec.
1831 mincount = if timeout, minimum to read before returning
1832 maxcount = number to be read.
1833 ****************************************************************************/
1834 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1840 struct timeval timeout;
1842 /* just checking .... */
1843 if (maxcnt <= 0) return(0);
1848 if (time_out <= 0) {
1849 if (mincnt == 0) mincnt = maxcnt;
1851 while (nread < mincnt) {
1854 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1856 readret = read(fd, buf + nread, maxcnt - nread);
1858 #else /* WITH_SSL */
1859 readret = read(fd, buf + nread, maxcnt - nread);
1860 #endif /* WITH_SSL */
1863 smb_read_error = READ_EOF;
1867 if (readret == -1) {
1868 smb_read_error = READ_ERROR;
1876 /* Most difficult - timeout read */
1877 /* If this is ever called on a disk file and
1878 mincnt is greater then the filesize then
1879 system performance will suffer severely as
1880 select always return true on disk files */
1882 /* Set initial timeout */
1883 timeout.tv_sec = time_out / 1000;
1884 timeout.tv_usec = 1000 * (time_out % 1000);
1886 for (nread=0; nread<mincnt; )
1891 selrtn = sys_select(&fds,&timeout);
1893 /* Check if error */
1895 /* something is wrong. Maybe the socket is dead? */
1896 smb_read_error = READ_ERROR;
1900 /* Did we timeout ? */
1902 smb_read_error = READ_TIMEOUT;
1908 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1910 readret = read(fd, buf + nread, maxcnt - nread);
1912 #else /* WITH_SSL */
1913 readret = read(fd, buf+nread, maxcnt-nread);
1914 #endif /* WITH_SSL */
1917 /* we got EOF on the file descriptor */
1918 smb_read_error = READ_EOF;
1922 if (readret == -1) {
1923 /* the descriptor is probably dead */
1924 smb_read_error = READ_ERROR;
1931 /* Return the number we got */
1935 /****************************************************************************
1936 read data from the client. Maxtime is in milliseconds
1937 ****************************************************************************/
1938 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1943 struct timeval timeout;
1948 timeout.tv_sec = maxtime / 1000;
1949 timeout.tv_usec = (maxtime % 1000) * 1000;
1951 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1953 if (!FD_ISSET(fd,&fds))
1956 nread = read_udp_socket(fd, buffer, bufsize);
1958 /* return the number got */
1962 /*******************************************************************
1963 find the difference in milliseconds between two struct timeval
1965 ********************************************************************/
1966 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1968 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1969 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1972 /****************************************************************************
1973 send a keepalive packet (rfc1002)
1974 ****************************************************************************/
1975 BOOL send_keepalive(int client)
1977 unsigned char buf[4];
1980 buf[1] = buf[2] = buf[3] = 0;
1982 return(write_data(client,(char *)buf,4) == 4);
1987 /****************************************************************************
1988 read data from the client, reading exactly N bytes.
1989 ****************************************************************************/
1990 int read_data(int fd,char *buffer,int N)
2001 ret = SSL_read(ssl, buffer + total, N - total);
2003 ret = read(fd,buffer + total,N - total);
2005 #else /* WITH_SSL */
2006 ret = read(fd,buffer + total,N - total);
2007 #endif /* WITH_SSL */
2011 smb_read_error = READ_EOF;
2016 smb_read_error = READ_ERROR;
2025 /****************************************************************************
2027 ****************************************************************************/
2028 int write_data(int fd,char *buffer,int N)
2037 ret = SSL_write(ssl,buffer + total,N - total);
2039 ret = write(fd,buffer + total,N - total);
2041 #else /* WITH_SSL */
2042 ret = write(fd,buffer + total,N - total);
2043 #endif /* WITH_SSL */
2045 if (ret == -1) return -1;
2046 if (ret == 0) return total;
2054 /****************************************************************************
2055 transfer some data between two fd's
2056 ****************************************************************************/
2057 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2059 static char *buf=NULL;
2064 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2067 size = lp_readsize();
2068 size = MAX(size,1024);
2071 while (!buf && size>0) {
2072 buf = (char *)Realloc(buf,size+8);
2073 if (!buf) size /= 2;
2077 DEBUG(0,("Can't allocate transfer buffer!\n"));
2081 abuf = buf + (align%8);
2088 int s = MIN(n,size);
2093 if (header && (headlen >= MIN(s,1024))) {
2103 if (header && headlen > 0)
2105 ret = MIN(headlen,size);
2106 memcpy(buf1,header,ret);
2109 if (headlen <= 0) header = NULL;
2113 ret += read(infd,buf1+ret,s-ret);
2117 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2118 if (ret2 > 0) total += ret2;
2119 /* if we can't write then dump excess data */
2121 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2123 if (ret <= 0 || ret2 != ret)
2131 /****************************************************************************
2132 read 4 bytes of a smb packet and return the smb length of the packet
2133 store the result in the buffer
2134 This version of the function will return a length of zero on receiving
2136 ****************************************************************************/
2137 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2139 int len=0, msg_type;
2145 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2147 ok = (read_data(fd,inbuf,4) == 4);
2152 len = smb_len(inbuf);
2153 msg_type = CVAL(inbuf,0);
2155 if (msg_type == 0x85)
2156 DEBUG(5,("Got keepalive packet\n"));
2159 DEBUG(10,("got smb length of %d\n",len));
2164 /****************************************************************************
2165 read 4 bytes of a smb packet and return the smb length of the packet
2166 store the result in the buffer. This version of the function will
2167 never return a session keepalive (length of zero).
2168 ****************************************************************************/
2169 int read_smb_length(int fd,char *inbuf,int timeout)
2175 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2180 /* Ignore session keepalives. */
2181 if(CVAL(inbuf,0) != 0x85)
2188 /****************************************************************************
2189 read an smb from a fd. Note that the buffer *MUST* be of size
2190 BUFFER_SIZE+SAFETY_MARGIN.
2191 The timeout is in milli seconds.
2193 This function will return on a
2194 receipt of a session keepalive packet.
2195 ****************************************************************************/
2196 BOOL receive_smb(int fd,char *buffer, int timeout)
2202 bzero(buffer,smb_size + 100);
2204 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2208 if (len > BUFFER_SIZE) {
2209 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2210 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2215 ret = read_data(fd,buffer+4,len);
2217 smb_read_error = READ_ERROR;
2224 /****************************************************************************
2225 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2226 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2227 The timeout is in milli seconds
2229 This is exactly the same as receive_smb except that it never returns
2230 a session keepalive packet (just as receive_smb used to do).
2231 receive_smb was changed to return keepalives as the oplock processing means this call
2232 should never go into a blocking read.
2233 ****************************************************************************/
2235 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2241 ret = receive_smb(fd, buffer, timeout);
2246 /* Ignore session keepalive packets. */
2247 if(CVAL(buffer,0) != 0x85)
2253 /****************************************************************************
2254 read a message from a udp fd.
2255 The timeout is in milli seconds
2256 ****************************************************************************/
2257 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2259 struct sockaddr_in from;
2260 int fromlen = sizeof(from);
2274 to.tv_sec = timeout / 1000;
2275 to.tv_usec = (timeout % 1000) * 1000;
2277 selrtn = sys_select(&fds,&to);
2279 /* Check if error */
2282 /* something is wrong. Maybe the socket is dead? */
2283 smb_read_error = READ_ERROR;
2287 /* Did we timeout ? */
2290 smb_read_error = READ_TIMEOUT;
2296 * Read a loopback udp message.
2298 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2299 buffer_len - UDP_CMD_HEADER_LEN, 0,
2300 (struct sockaddr *)&from, &fromlen);
2304 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2308 /* Validate message length. */
2309 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2311 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2313 buffer_len - UDP_CMD_HEADER_LEN));
2317 /* Validate message from address (must be localhost). */
2318 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2320 DEBUG(0,("receive_local_message: invalid 'from' address \
2321 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2325 /* Setup the message header */
2326 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2327 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2332 /****************************************************************************
2333 structure to hold a linked list of local messages.
2335 ****************************************************************************/
2338 ubi_slNode msg_next;
2341 } pending_message_list;
2343 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
2345 /****************************************************************************
2346 Function to push a message onto the tail of a linked list of smb messages ready
2348 ****************************************************************************/
2350 static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
2352 pending_message_list *msg = (pending_message_list *)
2353 malloc(sizeof(pending_message_list));
2357 DEBUG(0,("push_local_message: malloc fail (1)\n"));
2361 msg->msg_buf = (char *)malloc(msg_len);
2362 if(msg->msg_buf == NULL)
2364 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2369 memcpy(msg->msg_buf, buf, msg_len);
2370 msg->msg_len = msg_len;
2372 ubi_slAddTail( list_head, msg);
2377 /****************************************************************************
2378 Function to push a smb message onto a linked list of local smb messages ready
2380 ****************************************************************************/
2382 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
2384 return push_local_message(&smb_oplock_queue, buf, msg_len);
2387 /****************************************************************************
2388 Do a select on an two fd's - with timeout.
2390 If a local udp message has been pushed onto the
2391 queue (this can only happen during oplock break
2392 processing) return this first.
2394 If a pending smb message has been pushed onto the
2395 queue (this can only happen during oplock break
2396 processing) return this next.
2398 If the first smbfd is ready then read an smb from it.
2399 if the second (loopback UDP) fd is ready then read a message
2400 from it and setup the buffer header to identify the length
2402 Returns False on timeout or error.
2405 The timeout is in milli seconds
2406 ****************************************************************************/
2407 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2408 char *buffer, int buffer_len,
2409 int timeout, BOOL *got_smb)
2420 * Check to see if we already have a message on the smb queue.
2421 * If so - copy and return it.
2424 if(ubi_slCount(&smb_oplock_queue) != 0)
2426 pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
2427 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2429 /* Free the message we just copied. */
2430 free((char *)msg->msg_buf);
2434 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2440 FD_SET(oplock_fd,&fds);
2442 to.tv_sec = timeout / 1000;
2443 to.tv_usec = (timeout % 1000) * 1000;
2445 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2447 /* Check if error */
2449 /* something is wrong. Maybe the socket is dead? */
2450 smb_read_error = READ_ERROR;
2454 /* Did we timeout ? */
2456 smb_read_error = READ_TIMEOUT;
2460 if (FD_ISSET(smbfd,&fds))
2463 return receive_smb(smbfd, buffer, 0);
2467 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2471 /****************************************************************************
2473 ****************************************************************************/
2474 BOOL send_smb(int fd,char *buffer)
2478 len = smb_len(buffer) + 4;
2480 while (nwritten < len)
2482 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2485 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2497 /****************************************************************************
2498 find a pointer to a netbios name
2499 ****************************************************************************/
2500 char *name_ptr(char *buf,int ofs)
2502 unsigned char c = *(unsigned char *)(buf+ofs);
2504 if ((c & 0xC0) == 0xC0)
2508 memcpy(p,buf+ofs,2);
2511 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2518 /****************************************************************************
2519 extract a netbios name from a buf
2520 ****************************************************************************/
2521 int name_extract(char *buf,int ofs,char *name)
2523 char *p = name_ptr(buf,ofs);
2524 int d = PTR_DIFF(p,buf+ofs);
2526 if (d < -50 || d > 50) return(0);
2527 return(name_interpret(p,name));
2530 /****************************************************************************
2531 return the total storage length of a mangled name
2532 ****************************************************************************/
2533 int name_len( char *s )
2537 /* If the two high bits of the byte are set, return 2. */
2538 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2541 /* Add up the length bytes. */
2542 for( len = 1; (*s); s += (*s) + 1 )
2550 /****************************************************************************
2551 send a single packet to a port on another machine
2552 ****************************************************************************/
2553 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2557 struct sockaddr_in sock_out;
2562 /* create a socket to write to */
2563 out_fd = socket(AF_INET, type, 0);
2566 DEBUG(0,("socket failed"));
2570 /* set the address and port */
2571 bzero((char *)&sock_out,sizeof(sock_out));
2572 putip((char *)&sock_out.sin_addr,(char *)&ip);
2573 sock_out.sin_port = htons( port );
2574 sock_out.sin_family = AF_INET;
2577 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2578 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2581 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2584 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2585 inet_ntoa(ip),port,strerror(errno)));
2591 /*******************************************************************
2592 sleep for a specified number of milliseconds
2593 ********************************************************************/
2597 struct timeval tval,t1,t2;
2604 tval.tv_sec = (t-tdiff)/1000;
2605 tval.tv_usec = 1000*((t-tdiff)%1000);
2609 sys_select(&fds,&tval);
2612 tdiff = TvalDiff(&t1,&t2);
2616 /****************************************************************************
2617 check if a string is part of a list
2618 ****************************************************************************/
2619 BOOL in_list(char *s,char *list,BOOL casesensitive)
2624 if (!list) return(False);
2626 while (next_token(&p,tok,LIST_SEP))
2628 if (casesensitive) {
2629 if (strcmp(tok,s) == 0)
2632 if (StrCaseCmp(tok,s) == 0)
2639 /* this is used to prevent lots of mallocs of size 1 */
2640 static char *null_string = NULL;
2642 /****************************************************************************
2643 set a string value, allocing the space for the string
2644 ****************************************************************************/
2645 BOOL string_init(char **dest,char *src)
2656 null_string = (char *)malloc(1);
2659 *dest = null_string;
2663 (*dest) = (char *)malloc(l+1);
2664 if ((*dest) == NULL) {
2665 DEBUG(0,("Out of memory in string_init\n"));
2674 /****************************************************************************
2676 ****************************************************************************/
2677 void string_free(char **s)
2679 if (!s || !(*s)) return;
2680 if (*s == null_string)
2686 /****************************************************************************
2687 set a string value, allocing the space for the string, and deallocating any
2689 ****************************************************************************/
2690 BOOL string_set(char **dest,char *src)
2694 return(string_init(dest,src));
2697 /****************************************************************************
2698 substitute a string for a pattern in another string. Make sure there is
2701 This routine looks for pattern in s and replaces it with
2702 insert. It may do multiple replacements.
2704 return True if a substitution was done.
2705 ****************************************************************************/
2706 BOOL string_sub(char *s,char *pattern,char *insert)
2712 if (!insert || !pattern || !s) return(False);
2715 lp = strlen(pattern);
2716 li = strlen(insert);
2718 if (!*pattern) return(False);
2720 while (lp <= ls && (p = strstr(s,pattern)))
2723 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2724 memcpy(p,insert,li);
2731 /*********************************************************
2732 * Recursive routine that is called by unix_mask_match.
2733 * Does the actual matching. This is the 'original code'
2734 * used by the unix matcher.
2735 *********************************************************/
2736 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2740 for( p = regexp; *p && *str; ) {
2747 /* Look for a character matching
2748 the one after the '*' */
2751 return True; /* Automatic match */
2753 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2755 if(unix_do_match(str,p,case_sig))
2769 if(toupper(*str) != toupper(*p))
2779 if (!*p && str[0] == '.' && str[1] == 0)
2782 if (!*str && *p == '?')
2784 while (*p == '?') p++;
2788 if(!*str && (*p == '*' && p[1] == '\0'))
2794 /*********************************************************
2795 * Routine to match a given string with a regexp - uses
2796 * simplified regexp that takes * and ? only. Case can be
2797 * significant or not.
2798 * This is the 'original code' used by the unix matcher.
2799 *********************************************************/
2801 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2805 fstring ebase,eext,sbase,sext;
2809 /* Make local copies of str and regexp */
2810 StrnCpy(p1,regexp,sizeof(pstring)-1);
2811 StrnCpy(p2,str,sizeof(pstring)-1);
2813 if (!strchr(p2,'.')) {
2817 /* Remove any *? and ** as they are meaningless */
2818 for(p = p1; *p; p++)
2819 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2820 (void)pstrcpy( &p[1], &p[2]);
2822 if (strequal(p1,"*")) return(True);
2824 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2830 if ((p=strrchr(p1,'.'))) {
2839 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2849 matched = unix_do_match(sbase,ebase,case_sig) &&
2850 (trans2 || unix_do_match(sext,eext,case_sig));
2852 DEBUG(8,("unix_mask_match returning %d\n", matched));
2857 /*********************************************************
2858 * Recursive routine that is called by mask_match.
2859 * Does the actual matching. Returns True if matched,
2860 * False if failed. This is the 'new' NT style matcher.
2861 *********************************************************/
2863 BOOL do_match(char *str, char *regexp, int case_sig)
2867 for( p = regexp; *p && *str; ) {
2874 /* Look for a character matching
2875 the one after the '*' */
2878 return True; /* Automatic match */
2880 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2882 /* Now eat all characters that match, as
2883 we want the *last* character to match. */
2884 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2886 str--; /* We've eaten the match char after the '*' */
2887 if(do_match(str,p,case_sig)) {
2904 if(toupper(*str) != toupper(*p)) {
2916 if (!*p && str[0] == '.' && str[1] == 0) {
2920 if (!*str && *p == '?') {
2926 if(!*str && (*p == '*' && p[1] == '\0')) {
2934 /*********************************************************
2935 * Routine to match a given string with a regexp - uses
2936 * simplified regexp that takes * and ? only. Case can be
2937 * significant or not.
2938 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2939 * This is the new 'NT style' matcher.
2940 *********************************************************/
2942 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2945 pstring t_pattern, t_filename, te_pattern, te_filename;
2946 fstring ebase,eext,sbase,sext;
2948 BOOL matched = False;
2950 /* Make local copies of str and regexp */
2951 pstrcpy(t_pattern,regexp);
2952 pstrcpy(t_filename,str);
2956 * Not sure if this is a good idea. JRA.
2958 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2963 if (!strchr(t_filename,'.')) {
2964 pstrcat(t_filename,".");
2968 /* Remove any *? and ** as they are meaningless */
2969 string_sub(t_pattern, "*?", "*");
2970 string_sub(t_pattern, "**", "*");
2972 if (strequal(t_pattern,"*"))
2975 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2979 * Match each component of the regexp, split up by '.'
2982 char *fp, *rp, *cp2, *cp1;
2983 BOOL last_wcard_was_star = False;
2984 int num_path_components, num_regexp_components;
2986 pstrcpy(te_pattern,t_pattern);
2987 pstrcpy(te_filename,t_filename);
2989 * Remove multiple "*." patterns.
2991 string_sub(te_pattern, "*.*.", "*.");
2992 num_regexp_components = count_chars(te_pattern, '.');
2993 num_path_components = count_chars(te_filename, '.');
2996 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2998 if(num_regexp_components == 0)
2999 matched = do_match( te_filename, te_pattern, case_sig);
3001 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
3002 fp = strchr(cp2, '.');
3005 rp = strchr(cp1, '.');
3009 if(cp1[strlen(cp1)-1] == '*')
3010 last_wcard_was_star = True;
3012 last_wcard_was_star = False;
3014 if(!do_match(cp2, cp1, case_sig))
3017 cp1 = rp ? rp + 1 : NULL;
3018 cp2 = fp ? fp + 1 : "";
3020 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3021 /* Eat the extra path components. */
3024 for(i = 0; i < num_path_components - num_regexp_components; i++) {
3025 fp = strchr(cp2, '.');
3029 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3030 cp2 = fp ? fp + 1 : "";
3033 cp2 = fp ? fp + 1 : "";
3035 num_path_components -= i;
3038 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3043 /* -------------------------------------------------
3044 * Behaviour of Win95
3045 * for 8.3 filenames and 8.3 Wildcards
3046 * -------------------------------------------------
3048 if (strequal (t_filename, ".")) {
3050 * Patterns: *.* *. ?. ? are valid
3053 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3054 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3056 } else if (strequal (t_filename, "..")) {
3058 * Patterns: *.* *. ?. ? *.? are valid
3061 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3062 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3063 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3067 if ((p = strrchr (t_pattern, '.'))) {
3069 * Wildcard has a suffix.
3072 fstrcpy (ebase, t_pattern);
3074 fstrcpy (eext, p + 1);
3076 /* pattern ends in DOT: treat as if there is no DOT */
3078 if (strequal (ebase, "*"))
3083 * No suffix for wildcard.
3085 fstrcpy (ebase, t_pattern);
3089 p = strrchr (t_filename, '.');
3090 if (p && (p[1] == 0) ) {
3092 * Filename has an extension of '.' only.
3094 *p = 0; /* nuke dot at end of string */
3095 p = 0; /* and treat it as if there is no extension */
3100 * Filename has an extension.
3103 fstrcpy (sbase, t_filename);
3104 fstrcpy (sext, p + 1);
3106 matched = do_match(sbase, ebase, case_sig)
3107 && do_match(sext, eext, case_sig);
3109 /* pattern has no extension */
3110 /* Really: match complete filename with pattern ??? means exactly 3 chars */
3111 matched = do_match(str, ebase, case_sig);
3115 * Filename has no extension.
3117 fstrcpy (sbase, t_filename);
3120 /* pattern has extension */
3121 matched = do_match(sbase, ebase, case_sig)
3122 && do_match(sext, eext, case_sig);
3124 matched = do_match(sbase, ebase, case_sig);
3125 #ifdef EMULATE_WEIRD_W95_MATCHING
3127 * Even Microsoft has some problems
3128 * Behaviour Win95 -> local disk
3129 * is different from Win95 -> smb drive from Nt 4.0
3130 * This branch would reflect the Win95 local disk behaviour
3133 /* a? matches aa and a in w95 */
3134 fstrcat (sbase, ".");
3135 matched = do_match(sbase, ebase, case_sig);
3143 DEBUG(8,("mask_match returning %d\n", matched));
3148 /****************************************************************************
3149 become a daemon, discarding the controlling terminal
3150 ****************************************************************************/
3151 void become_daemon(void)
3157 /* detach from the terminal */
3160 #elif defined(TIOCNOTTY)
3162 int i = open("/dev/tty", O_RDWR);
3164 ioctl(i, (int) TIOCNOTTY, (char *)0);
3168 #endif /* HAVE_SETSID */
3170 /* Close fd's 0,1,2. Needed if started by rsh */
3175 /****************************************************************************
3176 put up a yes/no prompt
3177 ****************************************************************************/
3183 if (!fgets(ans,sizeof(ans)-1,stdin))
3186 if (*ans == 'y' || *ans == 'Y')
3192 /****************************************************************************
3193 read a line from a file with possible \ continuation chars.
3194 Blanks at the start or end of a line are stripped.
3195 The string will be allocated if s2 is NULL
3196 ****************************************************************************/
3197 char *fgets_slash(char *s2,int maxlen,FILE *f)
3202 BOOL start_of_line = True;
3209 maxlen = MIN(maxlen,8);
3210 s = (char *)Realloc(s,maxlen);
3213 if (!s || maxlen < 2) return(NULL);
3217 while (len < maxlen-1)
3225 while (len > 0 && s[len-1] == ' ')
3229 if (len > 0 && s[len-1] == '\\')
3232 start_of_line = True;
3237 if (len <= 0 && !s2)
3239 return(len>0?s:NULL);
3244 start_of_line = False;
3248 if (!s2 && len > maxlen-3)
3251 s = (char *)Realloc(s,maxlen);
3252 if (!s) return(NULL);
3260 /****************************************************************************
3261 set the length of a file from a filedescriptor.
3262 Returns 0 on success, -1 on failure.
3263 ****************************************************************************/
3264 int set_filelen(int fd, long len)
3266 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3267 extend a file with ftruncate. Provide alternate implementation
3270 #ifdef HAVE_FTRUNCATE_EXTEND
3271 return ftruncate(fd, len);
3275 long currpos = lseek(fd, 0L, SEEK_CUR);
3279 /* Do an fstat to see if the file is longer than
3280 the requested size (call ftruncate),
3281 or shorter, in which case seek to len - 1 and write 1
3283 if(fstat(fd, &st)<0)
3287 if (S_ISFIFO(st.st_mode)) return 0;
3290 if(st.st_size == len)
3292 if(st.st_size > len)
3293 return ftruncate(fd, len);
3295 if(lseek(fd, len-1, SEEK_SET) != len -1)
3297 if(write(fd, &c, 1)!=1)
3299 /* Seek to where we were */
3300 lseek(fd, currpos, SEEK_SET);
3306 /****************************************************************************
3307 return the byte checksum of some data
3308 ****************************************************************************/
3309 int byte_checksum(char *buf,int len)
3311 unsigned char *p = (unsigned char *)buf;
3321 /****************************************************************************
3322 this is a version of setbuffer() for those machines that only have setvbuf
3323 ****************************************************************************/
3324 void setbuffer(FILE *f,char *buf,int bufsize)
3326 setvbuf(f,buf,_IOFBF,bufsize);
3331 /****************************************************************************
3332 parse out a directory name from a path name. Assumes dos style filenames.
3333 ****************************************************************************/
3334 char *dirname_dos(char *path,char *buf)
3336 char *p = strrchr(path,'\\');
3351 /****************************************************************************
3352 parse out a filename from a path name. Assumes dos style filenames.
3353 ****************************************************************************/
3354 static char *filename_dos(char *path,char *buf)
3356 char *p = strrchr(path,'\\');
3368 /****************************************************************************
3369 expand a pointer to be a particular size
3370 ****************************************************************************/
3371 void *Realloc(void *p,int size)
3377 DEBUG(5,("Realloc asked for 0 bytes\n"));
3382 ret = (void *)malloc(size);
3384 ret = (void *)realloc(p,size);
3387 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3393 /****************************************************************************
3394 Signal handler for SIGPIPE (write on a disconnected socket)
3395 ****************************************************************************/
3398 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3402 /****************************************************************************
3403 get my own name and IP
3404 ****************************************************************************/
3405 BOOL get_myname(char *my_name,struct in_addr *ip)
3412 /* get my host name */
3413 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3415 DEBUG(0,("gethostname failed\n"));
3420 if ((hp = Get_Hostbyname(hostname)) == 0)
3422 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3428 /* split off any parts after an initial . */
3429 char *p = strchr(hostname,'.');
3432 fstrcpy(my_name,hostname);
3436 putip((char *)ip,(char *)hp->h_addr);
3442 /****************************************************************************
3443 true if two IP addresses are equal
3444 ****************************************************************************/
3445 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3448 a1 = ntohl(ip1.s_addr);
3449 a2 = ntohl(ip2.s_addr);
3454 /****************************************************************************
3455 open a socket of the specified type, port and address for incoming data
3456 ****************************************************************************/
3457 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3460 struct sockaddr_in sock;
3464 /* get my host name */
3465 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3466 { DEBUG(0,("gethostname failed\n")); return -1; }
3469 if ((hp = Get_Hostbyname(host_name)) == 0)
3471 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3475 bzero((char *)&sock,sizeof(sock));
3476 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3478 #ifdef HAVE_SOCK_SIN_LEN
3479 sock.sin_len = sizeof(sock);
3481 sock.sin_port = htons( port );
3482 sock.sin_family = hp->h_addrtype;
3483 sock.sin_addr.s_addr = socket_addr;
3484 res = socket(hp->h_addrtype, type, 0);
3486 { DEBUG(0,("socket failed\n")); return -1; }
3490 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3493 /* now we've got a socket - we need to bind it */
3494 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3497 if (port == SMB_PORT || port == NMB_PORT)
3498 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3499 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3502 if (dlevel > 0 && port < 1000)
3505 if (port >= 1000 && port < 9000)
3506 return(open_socket_in(type,port+1,dlevel,socket_addr));
3511 DEBUG(3,("bind succeeded on port %d\n",port));
3517 /****************************************************************************
3518 create an outgoing socket
3519 **************************************************************************/
3520 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3522 struct sockaddr_in sock_out;
3524 int connect_loop = 250; /* 250 milliseconds */
3525 int loops = (timeout * 1000) / connect_loop;
3527 /* create a socket to write to */
3528 res = socket(PF_INET, type, 0);
3530 { DEBUG(0,("socket error\n")); return -1; }
3532 if (type != SOCK_STREAM) return(res);
3534 bzero((char *)&sock_out,sizeof(sock_out));
3535 putip((char *)&sock_out.sin_addr,(char *)addr);
3537 sock_out.sin_port = htons( port );
3538 sock_out.sin_family = PF_INET;
3540 /* set it non-blocking */
3541 set_blocking(res,False);
3543 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3545 /* and connect it to the destination */
3547 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3549 /* Some systems return EAGAIN when they mean EINPROGRESS */
3550 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3551 errno == EAGAIN) && loops--) {
3552 msleep(connect_loop);
3556 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3558 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3564 if (ret < 0 && errno == EISCONN) {
3571 DEBUG(1,("error connecting to %s:%d (%s)\n",
3572 inet_ntoa(*addr),port,strerror(errno)));
3577 /* set it blocking again */
3578 set_blocking(res,True);
3584 /****************************************************************************
3585 interpret a protocol description string, with a default
3586 ****************************************************************************/
3587 int interpret_protocol(char *str,int def)
3589 if (strequal(str,"NT1"))
3590 return(PROTOCOL_NT1);
3591 if (strequal(str,"LANMAN2"))
3592 return(PROTOCOL_LANMAN2);
3593 if (strequal(str,"LANMAN1"))
3594 return(PROTOCOL_LANMAN1);
3595 if (strequal(str,"CORE"))
3596 return(PROTOCOL_CORE);
3597 if (strequal(str,"COREPLUS"))
3598 return(PROTOCOL_COREPLUS);
3599 if (strequal(str,"CORE+"))
3600 return(PROTOCOL_COREPLUS);
3602 DEBUG(0,("Unrecognised protocol level %s\n",str));
3607 /****************************************************************************
3608 interpret a security level
3609 ****************************************************************************/
3610 int interpret_security(char *str,int def)
3612 if (strequal(str,"SERVER"))
3614 if (strequal(str,"USER"))
3616 if (strequal(str,"SHARE"))
3619 DEBUG(0,("Unrecognised security level %s\n",str));
3625 /****************************************************************************
3626 interpret an internet address or name into an IP address in 4 byte form
3627 ****************************************************************************/
3628 uint32 interpret_addr(char *str)
3633 BOOL pure_address = True;
3635 if (strcmp(str,"0.0.0.0") == 0) return(0);
3636 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3638 for (i=0; pure_address && str[i]; i++)
3639 if (!(isdigit((int)str[i]) || str[i] == '.'))
3640 pure_address = False;
3642 /* if it's in the form of an IP address then get the lib to interpret it */
3644 res = inet_addr(str);
3646 /* otherwise assume it's a network name of some sort and use
3648 if ((hp = Get_Hostbyname(str)) == 0) {
3649 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3652 if(hp->h_addr == NULL) {
3653 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3656 putip((char *)&res,(char *)hp->h_addr);
3659 if (res == (uint32)-1) return(0);
3664 /*******************************************************************
3665 a convenient addition to interpret_addr()
3666 ******************************************************************/
3667 struct in_addr *interpret_addr2(char *str)
3669 static struct in_addr ret;
3670 uint32 a = interpret_addr(str);
3675 /*******************************************************************
3676 check if an IP is the 0.0.0.0
3677 ******************************************************************/
3678 BOOL zero_ip(struct in_addr ip)
3681 putip((char *)&a,(char *)&ip);
3686 /*******************************************************************
3687 matchname - determine if host name matches IP address
3688 ******************************************************************/
3689 static BOOL matchname(char *remotehost,struct in_addr addr)
3694 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3695 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3700 * Make sure that gethostbyname() returns the "correct" host name.
3701 * Unfortunately, gethostbyname("localhost") sometimes yields
3702 * "localhost.domain". Since the latter host name comes from the
3703 * local DNS, we just have to trust it (all bets are off if the local
3704 * DNS is perverted). We always check the address list, though.
3707 if (strcasecmp(remotehost, hp->h_name)
3708 && strcasecmp(remotehost, "localhost")) {
3709 DEBUG(0,("host name/name mismatch: %s != %s",
3710 remotehost, hp->h_name));
3714 /* Look up the host address in the address list we just got. */
3715 for (i = 0; hp->h_addr_list[i]; i++) {
3716 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3721 * The host name does not map to the original host address. Perhaps
3722 * someone has compromised a name server. More likely someone botched
3723 * it, but that could be dangerous, too.
3726 DEBUG(0,("host name/address mismatch: %s != %s",
3727 inet_ntoa(addr), hp->h_name));
3731 /*******************************************************************
3732 Reset the 'done' variables so after a client process is created
3733 from a fork call these calls will be re-done. This should be
3734 expanded if more variables need reseting.
3735 ******************************************************************/
3737 static BOOL global_client_name_done = False;
3738 static BOOL global_client_addr_done = False;
3740 void reset_globals_after_fork(void)
3742 global_client_name_done = False;
3743 global_client_addr_done = False;
3746 * Re-seed the random crypto generator, so all smbd's
3747 * started from the same parent won't generate the same
3751 unsigned char dummy;
3752 generate_random_buffer( &dummy, 1, True);
3756 /*******************************************************************
3757 return the DNS name of the client
3758 ******************************************************************/
3759 char *client_name(int fd)
3762 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3763 int length = sizeof(sa);
3764 static pstring name_buf;
3766 static int last_fd=-1;
3768 if (global_client_name_done && last_fd == fd)
3772 global_client_name_done = False;
3774 pstrcpy(name_buf,"UNKNOWN");
3780 if (getpeername(fd, &sa, &length) < 0) {
3781 DEBUG(0,("getpeername failed\n"));
3785 /* Look up the remote host name. */
3786 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3787 sizeof(sockin->sin_addr),
3789 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3790 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3792 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3793 if (!matchname(name_buf, sockin->sin_addr)) {
3794 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3795 pstrcpy(name_buf,"UNKNOWN");
3798 global_client_name_done = True;
3802 /*******************************************************************
3803 return the IP addr of the client as a string
3804 ******************************************************************/
3805 char *client_addr(int fd)
3808 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3809 int length = sizeof(sa);
3810 static fstring addr_buf;
3811 static int last_fd = -1;
3813 if (global_client_addr_done && fd == last_fd)
3817 global_client_addr_done = False;
3819 fstrcpy(addr_buf,"0.0.0.0");
3825 if (getpeername(fd, &sa, &length) < 0) {
3826 DEBUG(0,("getpeername failed\n"));
3830 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3832 global_client_addr_done = True;
3836 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3837 /******************************************************************
3838 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3839 Based on a fix from <Thomas.Hepper@icem.de>.
3840 *******************************************************************/
3842 static void strip_mount_options( pstring *str)
3847 while(*p && !isspace(*p))
3849 while(*p && isspace(*p))
3854 pstrcpy(tmp_str, p);
3855 pstrcpy(*str, tmp_str);
3860 /*******************************************************************
3861 Patch from jkf@soton.ac.uk
3862 Split Luke's automount_server into YP lookup and string splitter
3863 so can easily implement automount_path().
3864 As we may end up doing both, cache the last YP result.
3865 *******************************************************************/
3867 #ifdef WITH_NISPLUS_HOME
3868 static char *automount_lookup(char *user_name)
3870 static fstring last_key = "";
3871 static pstring last_value = "";
3873 char *nis_map = (char *)lp_nis_home_map_name();
3875 char nis_domain[NIS_MAXNAMELEN + 1];
3876 char buffer[NIS_MAXATTRVAL + 1];
3881 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3882 nis_domain[NIS_MAXNAMELEN] = '\0';
3884 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3886 if (strcmp(user_name, last_key))
3888 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3889 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3891 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3893 if (result->status != NIS_SUCCESS)
3895 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3896 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3900 object = result->objects.objects_val;
3901 if (object->zo_data.zo_type == ENTRY_OBJ)
3903 entry = &object->zo_data.objdata_u.en_data;
3904 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3905 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3907 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3908 string_sub(last_value, "&", user_name);
3909 fstrcpy(last_key, user_name);
3913 nis_freeresult(result);
3916 strip_mount_options(&last_value);
3918 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3921 #else /* WITH_NISPLUS_HOME */
3922 static char *automount_lookup(char *user_name)
3924 static fstring last_key = "";
3925 static pstring last_value = "";
3927 int nis_error; /* returned by yp all functions */
3928 char *nis_result; /* yp_match inits this */
3929 int nis_result_len; /* and set this */
3930 char *nis_domain; /* yp_get_default_domain inits this */
3931 char *nis_map = (char *)lp_nis_home_map_name();
3933 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3935 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3939 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3941 if (!strcmp(user_name, last_key))
3943 nis_result = last_value;
3944 nis_result_len = strlen(last_value);
3949 if ((nis_error = yp_match(nis_domain, nis_map,
3950 user_name, strlen(user_name),
3951 &nis_result, &nis_result_len)) != 0)
3953 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3954 yperr_string(nis_error), user_name, nis_map));
3956 if (!nis_error && nis_result_len >= sizeof(pstring))
3958 nis_result_len = sizeof(pstring)-1;
3960 fstrcpy(last_key, user_name);
3961 strncpy(last_value, nis_result, nis_result_len);
3962 last_value[nis_result_len] = '\0';
3965 strip_mount_options(&last_value);
3967 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3970 #endif /* WITH_NISPLUS_HOME */
3973 /*******************************************************************
3974 Patch from jkf@soton.ac.uk
3975 This is Luke's original function with the NIS lookup code
3976 moved out to a separate function.
3977 *******************************************************************/
3979 char *automount_server(char *user_name)
3981 static pstring server_name;
3983 /* use the local machine name as the default */
3984 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3985 pstrcpy(server_name, local_machine);
3987 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3989 if (lp_nis_home_map())
3991 int home_server_len;
3992 char *automount_value = automount_lookup(user_name);
3993 home_server_len = strcspn(automount_value,":");
3994 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3995 if (home_server_len > sizeof(pstring))
3997 home_server_len = sizeof(pstring);
3999 strncpy(server_name, automount_value, home_server_len);
4000 server_name[home_server_len] = '\0';
4004 DEBUG(4,("Home server: %s\n", server_name));
4009 /*******************************************************************
4010 Patch from jkf@soton.ac.uk
4011 Added this to implement %p (NIS auto-map version of %H)
4012 *******************************************************************/
4014 char *automount_path(char *user_name)
4016 static pstring server_path;
4018 /* use the passwd entry as the default */
4019 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
4020 /* pstrcpy() copes with get_home_dir() returning NULL */
4021 pstrcpy(server_path, get_home_dir(user_name));
4023 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
4025 if (lp_nis_home_map())
4027 char *home_path_start;
4028 char *automount_value = automount_lookup(user_name);
4029 home_path_start = strchr(automount_value,':');
4030 if (home_path_start != NULL)
4032 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
4033 home_path_start?(home_path_start+1):""));
4034 pstrcpy(server_path, home_path_start+1);
4039 DEBUG(4,("Home server path: %s\n", server_path));
4045 /*******************************************************************
4046 sub strings with useful parameters
4047 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4048 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4049 ********************************************************************/
4050 void standard_sub_basic(char *str)
4054 struct passwd *pass;
4055 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4057 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4063 if ((pass = Get_Pwnam(username,False))!=NULL)
4065 string_sub(p,"%G",gidtoname(pass->pw_gid));
4073 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4074 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4075 case 'L' : string_sub(p,"%L", local_machine); break;
4076 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4077 case 'R' : string_sub(p,"%R", remote_proto); break;
4078 case 'T' : string_sub(p,"%T", timestring()); break;
4079 case 'U' : string_sub(p,"%U", username); break;
4080 case 'a' : string_sub(p,"%a", remote_arch); break;
4083 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4084 string_sub(p,"%d", pidstr);
4087 case 'h' : string_sub(p,"%h", myhostname); break;
4088 case 'm' : string_sub(p,"%m", remote_machine); break;
4089 case 'v' : string_sub(p,"%v", VERSION); break;
4090 case '$' : /* Expand environment variables */
4092 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4103 if ((q = strchr(p,')')) == NULL)
4105 DEBUG(0,("standard_sub_basic: Unterminated environment \
4106 variable [%s]\n", p));
4112 copylen = MIN((q-r),(sizeof(envname)-1));
4113 strncpy(envname,r,copylen);
4114 envname[copylen] = '\0';
4116 if ((envval = getenv(envname)) == NULL)
4118 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4124 copylen = MIN((q+1-p),(sizeof(envname)-1));
4125 strncpy(envname,p,copylen);
4126 envname[copylen] = '\0';
4127 string_sub(p,envname,envval);
4130 case '\0': p++; break; /* don't run off end if last character is % */
4131 default : p+=2; break;
4138 /****************************************************************************
4139 do some standard substitutions in a string
4140 ****************************************************************************/
4141 void standard_sub(connection_struct *conn,char *str)
4145 for (s=str; (p=strchr(s, '%'));s=p) {
4148 if ((home = get_home_dir(conn->user))) {
4149 string_sub(p,"%H",home);
4156 string_sub(p,"%P",conn->connectpath);
4161 lp_servicename(SNUM(conn)));
4166 gidtoname(conn->gid));
4169 string_sub(p,"%u",conn->user);
4172 /* Patch from jkf@soton.ac.uk Left the %N (NIS
4173 * server name) in standard_sub_basic as it is
4174 * a feature for logon servers, hence uses the
4175 * username. The %p (NIS server path) code is
4176 * here as it is used instead of the default
4177 * "path =" string in [homes] and so needs the
4178 * service name, not the username. */
4181 automount_path(lp_servicename(SNUM(conn))));
4185 break; /* don't run off the end of the string
4193 standard_sub_basic(str);
4198 /*******************************************************************
4199 are two IPs on the same subnet?
4200 ********************************************************************/
4201 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4203 uint32 net1,net2,nmask;
4205 nmask = ntohl(mask.s_addr);
4206 net1 = ntohl(ip1.s_addr);
4207 net2 = ntohl(ip2.s_addr);
4209 return((net1 & nmask) == (net2 & nmask));
4213 /*******************************************************************
4214 write a string in unicoode format
4215 ********************************************************************/
4216 int PutUniCode(char *dst,char *src)
4220 dst[ret++] = src[0];
4229 /****************************************************************************
4230 a wrapper for gethostbyname() that tries with all lower and all upper case
4231 if the initial name fails
4232 ****************************************************************************/
4233 struct hostent *Get_Hostbyname(char *name)
4235 char *name2 = strdup(name);
4236 struct hostent *ret;
4240 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4246 * This next test is redundent and causes some systems (with
4247 * broken isalnum() calls) problems.
4252 if (!isalnum(*name2))
4259 ret = sys_gethostbyname(name2);
4266 /* try with all lowercase */
4268 ret = sys_gethostbyname(name2);
4275 /* try with all uppercase */
4277 ret = sys_gethostbyname(name2);
4284 /* nothing works :-( */
4290 /****************************************************************************
4291 check if a process exists. Does this work on all unixes?
4292 ****************************************************************************/
4293 BOOL process_exists(int pid)
4295 return(kill(pid,0) == 0 || errno != ESRCH);
4299 /*******************************************************************
4300 turn a uid into a user name
4301 ********************************************************************/
4302 char *uidtoname(int uid)
4304 static char name[40];
4305 struct passwd *pass = getpwuid(uid);
4306 if (pass) return(pass->pw_name);
4307 slprintf(name, sizeof(name) - 1, "%d",uid);
4311 /*******************************************************************
4312 turn a gid into a group name
4313 ********************************************************************/
4314 char *gidtoname(int gid)
4316 static char name[40];
4317 struct group *grp = getgrgid(gid);
4318 if (grp) return(grp->gr_name);
4319 slprintf(name,sizeof(name) - 1, "%d",gid);
4324 /*******************************************************************
4325 my own panic function - not suitable for general use
4326 ********************************************************************/
4327 void ajt_panic(void)
4329 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
4334 /*******************************************************************
4335 a readdir wrapper which just returns the file name
4336 also return the inode number if requested
4337 ********************************************************************/
4338 char *readdirname(void *p)
4343 if (!p) return(NULL);
4345 ptr = (struct dirent *)readdir(p);
4346 if (!ptr) return(NULL);
4348 dname = ptr->d_name;
4351 if (telldir(p) < 0) return(NULL);
4354 #ifdef HAVE_BROKEN_READDIR
4355 /* using /usr/ucb/cc is BAD */
4361 memcpy(buf, dname, NAMLEN(ptr)+1);
4362 unix_to_dos(buf, True);
4369 /*******************************************************************
4370 Utility function used to decide if the last component
4371 of a path matches a (possibly wildcarded) entry in a namelist.
4372 ********************************************************************/
4374 BOOL is_in_path(char *name, name_compare_entry *namelist)
4376 pstring last_component;
4379 DEBUG(8, ("is_in_path: %s\n", name));
4381 /* if we have no list it's obviously not in the path */
4382 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4384 DEBUG(8,("is_in_path: no name list.\n"));
4388 /* Get the last component of the unix name. */
4389 p = strrchr(name, '/');
4390 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4391 last_component[sizeof(last_component)-1] = '\0';
4393 for(; namelist->name != NULL; namelist++)
4395 if(namelist->is_wild)
4398 * Look for a wildcard match. Use the old
4399 * 'unix style' mask match, rather than the
4402 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4404 DEBUG(8,("is_in_path: mask match succeeded\n"));
4410 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4411 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4413 DEBUG(8,("is_in_path: match succeeded\n"));
4418 DEBUG(8,("is_in_path: match not found\n"));
4423 /*******************************************************************
4424 Strip a '/' separated list into an array of
4425 name_compare_enties structures suitable for
4426 passing to is_in_path(). We do this for
4427 speed so we can pre-parse all the names in the list
4428 and don't do it for each call to is_in_path().
4429 namelist is modified here and is assumed to be
4430 a copy owned by the caller.
4431 We also check if the entry contains a wildcard to
4432 remove a potentially expensive call to mask_match
4434 ********************************************************************/
4436 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4439 char *nameptr = namelist;
4440 int num_entries = 0;
4443 (*ppname_array) = NULL;
4445 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4448 /* We need to make two passes over the string. The
4449 first to count the number of elements, the second
4454 if ( *nameptr == '/' )
4456 /* cope with multiple (useless) /s) */
4460 /* find the next / */
4461 name_end = strchr(nameptr, '/');
4463 /* oops - the last check for a / didn't find one. */
4464 if (name_end == NULL)
4467 /* next segment please */
4468 nameptr = name_end + 1;
4472 if(num_entries == 0)
4475 if(( (*ppname_array) = (name_compare_entry *)malloc(
4476 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4478 DEBUG(0,("set_namearray: malloc fail\n"));
4482 /* Now copy out the names */
4487 if ( *nameptr == '/' )
4489 /* cope with multiple (useless) /s) */
4493 /* find the next / */
4494 if ((name_end = strchr(nameptr, '/')) != NULL)
4499 /* oops - the last check for a / didn't find one. */
4500 if(name_end == NULL)
4503 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4504 (strchr( nameptr, '*')!=NULL));
4505 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4507 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4511 /* next segment please */
4512 nameptr = name_end + 1;
4516 (*ppname_array)[i].name = NULL;
4521 /****************************************************************************
4522 routine to free a namearray.
4523 ****************************************************************************/
4525 void free_namearray(name_compare_entry *name_array)
4530 if(name_array->name != NULL)
4531 free(name_array->name);
4533 free((char *)name_array);
4536 /****************************************************************************
4537 routine to do file locking
4538 ****************************************************************************/
4539 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4547 * NB - this code will need re-writing to cope with large (64bit)
4548 * lock requests. JRA.
4551 if(lp_ole_locking_compat()) {
4552 uint32 mask = 0xC0000000;
4554 /* make sure the count is reasonable, we might kill the lockd otherwise */
4557 /* the offset is often strange - remove 2 of its bits if either of
4558 the top two bits are set. Shift the top ones by two bits. This
4559 still allows OLE2 apps to operate, but should stop lockd from
4561 if ((offset & mask) != 0)
4562 offset = (offset & ~mask) | ((offset & mask) >> 2);
4564 uint32 mask = ((unsigned)1<<31);
4565 int32 s_count = (int32) count; /* Signed count. */
4566 int32 s_offset = (int32)offset; /* Signed offset. */
4568 /* interpret negative counts as large numbers */
4572 /* no negative offsets */
4576 /* count + offset must be in range */
4577 while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
4583 offset = (uint32)s_offset;
4584 count = (uint32)s_count;
4588 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4591 lock.l_whence = SEEK_SET;
4592 lock.l_start = (int)offset;
4593 lock.l_len = (int)count;
4598 ret = fcntl(fd,op,&lock);
4601 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4607 (lock.l_type != F_UNLCK) &&
4608 (lock.l_pid != 0) &&
4609 (lock.l_pid != getpid()))
4611 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4615 /* it must be not locked or locked by me */
4619 /* a lock set or unset */
4622 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4623 offset,count,op,type,strerror(errno)));
4625 /* perhaps it doesn't support this sort of locking?? */
4626 if (errno == EINVAL)
4628 DEBUG(3,("locking not supported? returning True\n"));
4635 /* everything went OK */
4636 DEBUG(8,("Lock call successful\n"));
4644 /*******************************************************************
4645 lock a file - returning a open file descriptor or -1 on failure
4646 The timeout is in seconds. 0 means no timeout
4647 ********************************************************************/
4648 int file_lock(char *name,int timeout)
4650 int fd = open(name,O_RDWR|O_CREAT,0666);
4652 if (fd < 0) return(-1);
4655 if (timeout) t = time(NULL);
4656 while (!timeout || (time(NULL)-t < timeout)) {
4657 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4658 msleep(LOCK_RETRY_TIMEOUT);
4666 /*******************************************************************
4667 unlock a file locked by file_lock
4668 ********************************************************************/
4669 void file_unlock(int fd)
4673 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4678 /*******************************************************************
4679 is the name specified one of my netbios names
4680 returns true is it is equal, false otherwise
4681 ********************************************************************/
4682 BOOL is_myname(char *s)
4687 for (n=0; my_netbios_names[n]; n++) {
4688 if (strequal(my_netbios_names[n], s))
4691 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4695 /*******************************************************************
4696 set the horrid remote_arch string based on an enum.
4697 ********************************************************************/
4698 void set_remote_arch(enum remote_arch_types type)
4704 fstrcpy(remote_arch, "WfWg");
4707 fstrcpy(remote_arch, "OS2");
4710 fstrcpy(remote_arch, "Win95");
4713 fstrcpy(remote_arch, "WinNT");
4716 fstrcpy(remote_arch,"Samba");
4719 ra_type = RA_UNKNOWN;
4720 fstrcpy(remote_arch, "UNKNOWN");
4725 /*******************************************************************
4726 Get the remote_arch type.
4727 ********************************************************************/
4728 enum remote_arch_types get_remote_arch(void)
4734 /*******************************************************************
4735 skip past some unicode strings in a buffer
4736 ********************************************************************/
4737 char *skip_unicode_string(char *buf,int n)
4748 /*******************************************************************
4749 Return a ascii version of a unicode string
4750 Hack alert: uses fixed buffer(s) and only handles ascii strings
4751 ********************************************************************/
4753 char *unistrn2(uint16 *buf, int len)
4755 static char lbufs[8][MAXUNI];
4757 char *lbuf = lbufs[nexti];
4760 nexti = (nexti+1)%8;
4762 DEBUG(10, ("unistrn2: "));
4764 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4766 DEBUG(10, ("%4x ", *buf));
4776 /*******************************************************************
4777 Return a ascii version of a unicode string
4778 Hack alert: uses fixed buffer(s) and only handles ascii strings
4779 ********************************************************************/
4781 char *unistr2(uint16 *buf)
4783 static char lbufs[8][MAXUNI];
4785 char *lbuf = lbufs[nexti];
4788 nexti = (nexti+1)%8;
4790 DEBUG(10, ("unistr2: "));
4792 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4794 DEBUG(10, ("%4x ", *buf));
4804 /*******************************************************************
4805 create a null-terminated unicode string from a null-terminated ascii string.
4806 return number of unicode chars copied, excluding the null character.
4808 only handles ascii strings
4809 ********************************************************************/
4811 int struni2(uint16 *p, char *buf)
4815 if (p == NULL) return 0;
4817 DEBUG(10, ("struni2: "));
4821 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4823 DEBUG(10, ("%2x ", *buf));
4835 /*******************************************************************
4836 Return a ascii version of a unicode string
4837 Hack alert: uses fixed buffer(s) and only handles ascii strings
4838 ********************************************************************/
4840 char *unistr(char *buf)
4842 static char lbufs[8][MAXUNI];
4844 char *lbuf = lbufs[nexti];
4847 nexti = (nexti+1)%8;
4849 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4857 /*******************************************************************
4858 strncpy for unicode strings
4859 ********************************************************************/
4860 int unistrncpy(char *dst, char *src, int len)
4864 while (*src && len > 0)
4878 /*******************************************************************
4879 strcpy for unicode strings. returns length (in num of wide chars)
4880 ********************************************************************/
4881 int unistrcpy(char *dst, char *src)
4897 /*******************************************************************
4898 safe string copy into a known length string. maxlength does not
4899 include the terminating zero.
4900 ********************************************************************/
4901 char *safe_strcpy(char *dest, char *src, int maxlength)
4906 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4917 if (len > maxlength) {
4918 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4919 len-maxlength, src));
4923 memcpy(dest, src, len);
4928 /*******************************************************************
4929 safe string cat into a string. maxlength does not
4930 include the terminating zero.
4931 ********************************************************************/
4932 char *safe_strcat(char *dest, char *src, int maxlength)
4934 int src_len, dest_len;
4937 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4945 src_len = strlen(src);
4946 dest_len = strlen(dest);
4948 if (src_len + dest_len > maxlength) {
4949 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4950 src_len + dest_len - maxlength, src));
4951 src_len = maxlength - dest_len;
4954 memcpy(&dest[dest_len], src, src_len);
4955 dest[dest_len + src_len] = 0;
4959 /*******************************************************************
4960 align a pointer to a multiple of 4 bytes
4961 ********************************************************************/
4962 char *align4(char *q, char *base)
4966 q += 4 - ((q - base) & 3);
4971 /*******************************************************************
4972 align a pointer to a multiple of 2 bytes
4973 ********************************************************************/
4974 char *align2(char *q, char *base)
4983 /*******************************************************************
4984 align a pointer to a multiple of align_offset bytes. looks like it
4985 will work for offsets of 0, 2 and 4...
4986 ********************************************************************/
4987 char *align_offset(char *q, char *base, int align_offset_len)
4989 int mod = ((q - base) & (align_offset_len-1));
4990 if (align_offset_len != 0 && mod != 0)
4992 q += align_offset_len - mod;
4997 void print_asc(int level, unsigned char *buf,int len)
5001 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
5004 void dump_data(int level,char *buf1,int len)
5006 unsigned char *buf = (unsigned char *)buf1;
5010 DEBUG(level,("[%03X] ",i));
5012 DEBUG(level,("%02X ",(int)buf[i]));
5014 if (i%8 == 0) DEBUG(level,(" "));
5016 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
5017 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
5018 if (i<len) DEBUG(level,("[%03X] ",i));
5026 if (n>8) DEBUG(level,(" "));
5027 while (n--) DEBUG(level,(" "));
5030 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
5032 if (n>0) print_asc(level,&buf[i-n],n);
5033 DEBUG(level,("\n"));
5037 char *tab_depth(int depth)
5039 static pstring spaces;
5040 memset(spaces, ' ', depth * 4);
5041 spaces[depth * 4] = 0;
5045 /*****************************************************************
5046 Convert a SID to an ascii string.
5047 *****************************************************************/
5049 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
5053 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5054 uint32 ia = (sid->id_auth[5]) +
5055 (sid->id_auth[4] << 8 ) +
5056 (sid->id_auth[3] << 16) +
5057 (sid->id_auth[2] << 24);
5059 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
5061 for (i = 0; i < sid->num_auths; i++)
5063 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
5064 pstrcat(sidstr_out, subauth);
5067 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
5071 /*****************************************************************
5072 Convert a string to a SID. Returns True on success, False on fail.
5073 *****************************************************************/
5075 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
5079 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5082 memset((char *)sidout, '\0', sizeof(DOM_SID));
5084 if(StrnCaseCmp( sidstr, "S-", 2)) {
5085 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
5090 if(!next_token(&p, tok, "-")) {
5091 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5095 /* Get the revision number. */
5096 sidout->sid_rev_num = atoi(tok);
5098 if(!next_token(&p, tok, "-")) {
5099 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5103 /* identauth in decimal should be < 2^32 */
5106 /* NOTE - the ia value is in big-endian format. */
5107 sidout->id_auth[0] = 0;
5108 sidout->id_auth[1] = 0;
5109 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
5110 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
5111 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
5112 sidout->id_auth[5] = (ia & 0x000000ff);
5114 sidout->num_auths = 0;
5116 while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) {
5118 * NOTE - the subauths are in native machine-endian format. They
5119 * are converted to little-endian when linearized onto the wire.
5121 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
5124 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
5129 /*****************************************************************************
5130 * Provide a checksum on a string
5132 * Input: s - the nul-terminated character string for which the checksum
5133 * will be calculated.
5135 * Output: The checksum value calculated for s.
5137 * ****************************************************************************
5139 int str_checksum(char *s)
5147 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
5152 } /* str_checksum */