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;
43 int Protocol = PROTOCOL_COREPLUS;
45 /* a default finfo structure to ensure all fields are sensible */
46 file_info def_finfo = {-1,0,0,0,0,0,0,""};
48 /* the client file descriptor */
51 /* this is used by the chaining code */
57 case handling on filenames
59 int case_default = CASE_LOWER;
61 /* the following control case operations - they are put here so the
62 client can link easily */
65 BOOL use_mangled_map = False;
66 BOOL short_case_preserve;
69 fstring remote_machine="";
70 fstring local_machine="";
71 fstring remote_arch="UNKNOWN";
72 static enum remote_arch_types ra_type = RA_UNKNOWN;
73 fstring remote_proto="UNKNOWN";
74 pstring myhostname="";
75 pstring user_socket_options="";
77 pstring sesssetup_user="";
78 pstring samlogon_user="";
80 BOOL sam_logon_in_ssb = False;
82 pstring global_myname = "";
83 fstring global_myworkgroup = "";
84 char **my_netbios_names;
86 static char *filename_dos(char *path,char *buf);
90 /****************************************************************************
91 find a suitable temporary directory. The result should be copied immediately
92 as it may be overwritten by a subsequent call
93 ****************************************************************************/
97 if ((p = getenv("TMPDIR"))) {
105 /****************************************************************************
106 prompte a dptr (to make it recently used)
107 ****************************************************************************/
108 static void array_promote(char *array,int elsize,int element)
114 p = (char *)malloc(elsize);
118 DEBUG(5,("Ahh! Can't malloc\n"));
121 memcpy(p,array + element * elsize, elsize);
122 memmove(array + elsize,array,elsize*element);
123 memcpy(array,p,elsize);
127 /****************************************************************************
128 determine whether we are in the specified group
129 ****************************************************************************/
131 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
135 if (group == current_gid) return(True);
137 for (i=0;i<ngroups;i++)
138 if (group == groups[i])
145 /****************************************************************************
146 like atoi but gets the value up to the separater character
147 ****************************************************************************/
148 char *Atoic(char *p, int *n, char *c)
152 DEBUG(5, ("Atoic: malformed number\n"));
158 while ((*p) && isdigit(*p))
163 if (strchr(c, *p) == NULL)
165 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
172 /*************************************************************************
173 reads a list of numbers
174 *************************************************************************/
175 char *get_numlist(char *p, uint32 **num, int *count)
179 if (num == NULL || count == NULL)
187 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
189 (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
194 (*num)[(*count)] = val;
202 /*******************************************************************
203 copy an IP address from one buffer to another
204 ********************************************************************/
205 void putip(void *dest,void *src)
211 #define TRUNCATE_NETBIOS_NAME 1
213 /*******************************************************************
214 convert, possibly using a stupid microsoft-ism which has destroyed
215 the transport independence of netbios (for CIFS vendors that usually
216 use the Win95-type methods, not for NT to NT communication, which uses
217 DCE/RPC and therefore full-length unicode strings...) a dns name into
220 the netbios name (NOT necessarily null-terminated) is truncated to 15
223 ******************************************************************/
224 char *dns_to_netbios_name(char *dns_name)
226 static char netbios_name[16];
228 StrnCpy(netbios_name, dns_name, 15);
229 netbios_name[15] = 0;
231 #ifdef TRUNCATE_NETBIOS_NAME
232 /* ok. this is because of a stupid microsoft-ism. if the called host
233 name contains a '.', microsoft clients expect you to truncate the
234 netbios name up to and including the '.' this even applies, by
235 mistake, to workgroup (domain) names, which is _really_ daft.
237 for (i = 15; i >= 0; i--)
239 if (netbios_name[i] == '.')
245 #endif /* TRUNCATE_NETBIOS_NAME */
251 /****************************************************************************
252 interpret the weird netbios "name". Return the name type
253 ****************************************************************************/
254 static int name_interpret(char *in,char *out)
257 int len = (*in++) / 2;
261 if (len > 30 || len<1) return(0);
265 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
269 *out = ((in[0]-'A')<<4) + (in[1]-'A');
277 /* Handle any scope names */
280 *out++ = '.'; /* Scope names are separated by periods */
281 len = *(unsigned char *)in++;
282 StrnCpy(out, in, len);
291 /****************************************************************************
292 mangle a name into netbios format
294 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
295 ****************************************************************************/
296 int name_mangle( char *In, char *Out, char name_type )
304 /* Safely copy the input string, In, into buf[]. */
305 (void)memset( buf, 0, 20 );
306 if (strcmp(In,"*") == 0)
309 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
311 /* Place the length of the first field into the output buffer. */
315 /* Now convert the name to the rfc1001/1002 format. */
316 for( i = 0; i < 16; i++ )
318 c = toupper( buf[i] );
319 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
320 p[(i*2)+1] = (c & 0x000F) + 'A';
325 /* Add the scope string. */
326 for( i = 0, len = 0; NULL != scope; i++, len++ )
334 return( name_len(Out) );
346 return( name_len(Out) );
349 /*******************************************************************
350 check if a file exists
351 ********************************************************************/
352 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
355 if (!sbuf) sbuf = &st;
357 if (dos_stat(fname,sbuf) != 0)
360 return(S_ISREG(sbuf->st_mode));
363 /*******************************************************************
364 check a files mod time
365 ********************************************************************/
366 time_t file_modtime(char *fname)
370 if (dos_stat(fname,&st) != 0)
376 /*******************************************************************
377 check if a directory exists
378 ********************************************************************/
379 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
386 if (dos_stat(dname,st) != 0)
389 ret = S_ISDIR(st->st_mode);
395 /*******************************************************************
396 returns the size in bytes of the named file
397 ********************************************************************/
398 SMB_OFF_T file_size(char *file_name)
402 dos_stat(file_name,&buf);
406 /*******************************************************************
407 return a string representing an attribute for a file
408 ********************************************************************/
409 char *attrib_string(uint16 mode)
411 static fstring attrstr;
415 if (mode & aVOLID) fstrcat(attrstr,"V");
416 if (mode & aDIR) fstrcat(attrstr,"D");
417 if (mode & aARCH) fstrcat(attrstr,"A");
418 if (mode & aHIDDEN) fstrcat(attrstr,"H");
419 if (mode & aSYSTEM) fstrcat(attrstr,"S");
420 if (mode & aRONLY) fstrcat(attrstr,"R");
427 /****************************************************************************
428 make a file into unix format
429 ****************************************************************************/
430 void unix_format(char *fname)
432 string_replace(fname,'\\','/');
435 /****************************************************************************
436 make a file into dos format
437 ****************************************************************************/
438 void dos_format(char *fname)
440 string_replace(fname,'/','\\');
443 /*******************************************************************
444 show a smb message structure
445 ********************************************************************/
446 void show_msg(char *buf)
451 if (DEBUGLEVEL < 5) return;
453 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
455 (int)CVAL(buf,smb_com),
456 (int)CVAL(buf,smb_rcls),
457 (int)CVAL(buf,smb_reh),
458 (int)SVAL(buf,smb_err),
459 (int)CVAL(buf,smb_flg),
460 (int)SVAL(buf,smb_flg2)));
461 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
462 (int)SVAL(buf,smb_tid),
463 (int)SVAL(buf,smb_pid),
464 (int)SVAL(buf,smb_uid),
465 (int)SVAL(buf,smb_mid),
466 (int)CVAL(buf,smb_wct)));
468 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
470 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
471 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
474 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
476 DEBUG(5,("smb_bcc=%d\n",bcc));
478 if (DEBUGLEVEL < 10) return;
485 dump_data(10, smb_buf(buf), bcc);
487 /*******************************************************************
488 return the length of an smb packet
489 ********************************************************************/
490 int smb_len(char *buf)
492 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
495 /*******************************************************************
496 set the length of an smb packet
497 ********************************************************************/
498 void _smb_setlen(char *buf,int len)
501 buf[1] = (len&0x10000)>>16;
502 buf[2] = (len&0xFF00)>>8;
506 /*******************************************************************
507 set the length and marker of an smb packet
508 ********************************************************************/
509 void smb_setlen(char *buf,int len)
511 _smb_setlen(buf,len);
519 /*******************************************************************
520 setup the word count and byte count for a smb message
521 ********************************************************************/
522 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
525 bzero(buf + smb_size,num_words*2 + num_bytes);
526 CVAL(buf,smb_wct) = num_words;
527 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
528 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
529 return (smb_size + num_words*2 + num_bytes);
532 /*******************************************************************
533 return the number of smb words
534 ********************************************************************/
535 static int smb_numwords(char *buf)
537 return (CVAL(buf,smb_wct));
540 /*******************************************************************
541 return the size of the smb_buf region of a message
542 ********************************************************************/
543 int smb_buflen(char *buf)
545 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
548 /*******************************************************************
549 return a pointer to the smb_buf data area
550 ********************************************************************/
551 static int smb_buf_ofs(char *buf)
553 return (smb_size + CVAL(buf,smb_wct)*2);
556 /*******************************************************************
557 return a pointer to the smb_buf data area
558 ********************************************************************/
559 char *smb_buf(char *buf)
561 return (buf + smb_buf_ofs(buf));
564 /*******************************************************************
565 return the SMB offset into an SMB buffer
566 ********************************************************************/
567 int smb_offset(char *p,char *buf)
569 return(PTR_DIFF(p,buf+4) + chain_size);
574 /*******************************************************************
575 reduce a file name, removing .. elements.
576 ********************************************************************/
577 void dos_clean_name(char *s)
581 DEBUG(3,("dos_clean_name [%s]\n",s));
583 /* remove any double slashes */
584 string_sub(s, "\\\\", "\\");
586 while ((p = strstr(s,"\\..\\")) != NULL)
593 if ((p=strrchr(s,'\\')) != NULL)
600 trim_string(s,NULL,"\\..");
602 string_sub(s, "\\.\\", "\\");
605 /*******************************************************************
606 reduce a file name, removing .. elements.
607 ********************************************************************/
608 void unix_clean_name(char *s)
612 DEBUG(3,("unix_clean_name [%s]\n",s));
614 /* remove any double slashes */
615 string_sub(s, "//","/");
617 /* Remove leading ./ characters */
618 if(strncmp(s, "./", 2) == 0) {
619 trim_string(s, "./", NULL);
624 while ((p = strstr(s,"/../")) != NULL)
631 if ((p=strrchr(s,'/')) != NULL)
638 trim_string(s,NULL,"/..");
642 /*******************************************************************
643 a wrapper for the normal chdir() function
644 ********************************************************************/
645 int ChDir(char *path)
648 static pstring LastDir="";
650 if (strcsequal(path,".")) return(0);
652 if (*path == '/' && strcsequal(LastDir,path)) return(0);
653 DEBUG(3,("chdir to %s\n",path));
654 res = dos_chdir(path);
656 pstrcpy(LastDir,path);
660 /* number of list structures for a caching GetWd function. */
661 #define MAX_GETWDCACHE (50)
665 SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
666 SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
667 char *text; /* The pathname in DOS format. */
669 } ino_list[MAX_GETWDCACHE];
671 BOOL use_getwd_cache=True;
673 /*******************************************************************
674 return the absolute current directory path - given a UNIX pathname.
675 Note that this path is returned in DOS format, not UNIX
677 ********************************************************************/
678 char *GetWd(char *str)
681 static BOOL getwd_cache_init = False;
682 SMB_STRUCT_STAT st, st2;
687 if (!use_getwd_cache)
688 return(dos_getwd(str));
691 if (!getwd_cache_init)
693 getwd_cache_init = True;
694 for (i=0;i<MAX_GETWDCACHE;i++)
696 string_init(&ino_list[i].text,"");
697 ino_list[i].valid = False;
701 /* Get the inode of the current directory, if this doesn't work we're
704 if (dos_stat(".",&st) == -1)
706 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
707 return(dos_getwd(str));
711 for (i=0; i<MAX_GETWDCACHE; i++)
712 if (ino_list[i].valid)
715 /* If we have found an entry with a matching inode and dev number
716 then find the inode number for the directory in the cached string.
717 If this agrees with that returned by the stat for the current
718 directory then all is o.k. (but make sure it is a directory all
721 if (st.st_ino == ino_list[i].inode &&
722 st.st_dev == ino_list[i].dev)
724 if (dos_stat(ino_list[i].text,&st2) == 0)
726 if (st.st_ino == st2.st_ino &&
727 st.st_dev == st2.st_dev &&
728 (st2.st_mode & S_IFMT) == S_IFDIR)
730 pstrcpy (str, ino_list[i].text);
732 /* promote it for future use */
733 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
738 /* If the inode is different then something's changed,
739 scrub the entry and start from scratch. */
740 ino_list[i].valid = False;
747 /* We don't have the information to hand so rely on traditional methods.
748 The very slow getcwd, which spawns a process on some systems, or the
749 not quite so bad getwd. */
753 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
759 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
761 /* add it to the cache */
762 i = MAX_GETWDCACHE - 1;
763 string_set(&ino_list[i].text,s);
764 ino_list[i].dev = st.st_dev;
765 ino_list[i].inode = st.st_ino;
766 ino_list[i].valid = True;
768 /* put it at the top of the list */
769 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
776 /*******************************************************************
777 reduce a file name, removing .. elements and checking that
778 it is below dir in the heirachy. This uses GetWd() and so must be run
779 on the system that has the referenced file system.
781 widelinks are allowed if widelinks is true
782 ********************************************************************/
783 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
793 BOOL relative = (*s != '/');
795 *dir2 = *wd = *base_name = *newname = 0;
800 /* can't have a leading .. */
801 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
803 DEBUG(3,("Illegal file name? (%s)\n",s));
813 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
815 /* remove any double slashes */
816 string_sub(s,"//","/");
818 pstrcpy(base_name,s);
819 p = strrchr(base_name,'/');
826 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
832 DEBUG(0,("couldn't chdir to %s\n",dir));
838 DEBUG(0,("couldn't getwd for %s\n",dir));
844 if (p && (p != base_name))
847 if (strcmp(p+1,".")==0)
849 if (strcmp(p+1,"..")==0)
853 if (ChDir(base_name) != 0)
856 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
863 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
867 if (p && (p != base_name))
869 pstrcat(newname,"/");
870 pstrcat(newname,p+1);
874 int l = strlen(dir2);
875 if (dir2[l-1] == '/')
878 if (strncmp(newname,dir2,l) != 0)
881 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
887 if (newname[l] == '/')
888 pstrcpy(s,newname + l + 1);
890 pstrcpy(s,newname+l);
901 DEBUG(3,("reduced to %s\n",s));
906 /****************************************************************************
908 ****************************************************************************/
909 static void expand_one(char *Mask,int len)
912 while ((p1 = strchr(Mask,'*')) != NULL)
914 int lfill = (len+1) - strlen(Mask);
918 memset(tmp+l1,'?',lfill);
919 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
924 /****************************************************************************
925 parse out a directory name from a path name. Assumes dos style filenames.
926 ****************************************************************************/
927 static void dirname_dos(char *path,char *buf)
929 split_at_last_component(path, buf, '\\', NULL);
933 /****************************************************************************
934 expand a wildcard expression, replacing *s with ?s
935 ****************************************************************************/
936 void expand_mask(char *Mask,BOOL doext)
943 BOOL absolute = (*Mask == '\\');
945 *mbeg = *mext = *dirpart = *filepart = 0;
947 /* parse the directory and filename */
948 if (strchr(Mask,'\\'))
949 dirname_dos(Mask,dirpart);
951 filename_dos(Mask,filepart);
953 pstrcpy(mbeg,filepart);
954 if ((p1 = strchr(mbeg,'.')) != NULL)
964 if (strlen(mbeg) > 8)
966 pstrcpy(mext,mbeg + 8);
972 pstrcpy(mbeg,"????????");
973 if ((*mext == 0) && doext && !hasdot)
976 if (strequal(mbeg,"*") && *mext==0)
984 pstrcpy(Mask,dirpart);
985 if (*dirpart || absolute) pstrcat(Mask,"\\");
990 DEBUG(6,("Mask expanded to [%s]\n",Mask));
995 /****************************************************************************
997 ****************************************************************************/
998 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
1003 pstrcpy(mask2,mask);
1005 if ((mode & aDIR) != 0)
1008 memset(buf+1,' ',11);
1009 if ((p = strchr(mask2,'.')) != NULL)
1012 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1013 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1017 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1019 bzero(buf+21,DIR_STRUCT_SIZE-21);
1020 CVAL(buf,21) = mode;
1021 put_dos_date(buf,22,date);
1022 SSVAL(buf,26,size & 0xFFFF);
1023 SSVAL(buf,28,(size >> 16)&0xFFFF);
1024 StrnCpy(buf+30,fname,12);
1025 if (!case_sensitive)
1027 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1031 /*******************************************************************
1032 close the low 3 fd's and open dev/null in their place
1033 ********************************************************************/
1034 void close_low_fds(void)
1038 close(0); close(1); close(2);
1039 /* try and use up these file descriptors, so silly
1040 library routines writing to stdout etc won't cause havoc */
1042 fd = open("/dev/null",O_RDWR,0);
1043 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1045 DEBUG(0,("Can't open /dev/null\n"));
1049 DEBUG(0,("Didn't get file descriptor %d\n",i));
1055 /****************************************************************************
1056 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1058 if SYSV use O_NDELAY
1060 ****************************************************************************/
1061 int set_blocking(int fd, BOOL set)
1065 #define FLAG_TO_SET O_NONBLOCK
1068 #define FLAG_TO_SET O_NDELAY
1070 #define FLAG_TO_SET FNDELAY
1074 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1076 if(set) /* Turn blocking on - ie. clear nonblock flag */
1077 val &= ~FLAG_TO_SET;
1080 return fcntl( fd, F_SETFL, val);
1085 /*******************************************************************
1086 find the difference in milliseconds between two struct timeval
1088 ********************************************************************/
1089 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1091 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1092 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1097 /****************************************************************************
1098 transfer some data between two fd's
1099 ****************************************************************************/
1100 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
1102 static char *buf=NULL;
1105 SMB_OFF_T total = 0;
1107 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
1110 size = lp_readsize();
1111 size = MAX(size,1024);
1114 while (!buf && size>0) {
1115 buf = (char *)Realloc(buf,size+8);
1116 if (!buf) size /= 2;
1120 DEBUG(0,("Can't allocate transfer buffer!\n"));
1124 abuf = buf + (align%8);
1131 int s = (int)MIN(n,(SMB_OFF_T)size);
1136 if (header && (headlen >= MIN(s,1024))) {
1146 if (header && headlen > 0)
1148 ret = MIN(headlen,size);
1149 memcpy(buf1,header,ret);
1152 if (headlen <= 0) header = NULL;
1156 ret += read(infd,buf1+ret,s-ret);
1160 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1161 if (ret2 > 0) total += ret2;
1162 /* if we can't write then dump excess data */
1164 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1166 if (ret <= 0 || ret2 != ret)
1175 /****************************************************************************
1176 find a pointer to a netbios name
1177 ****************************************************************************/
1178 static char *name_ptr(char *buf,int ofs)
1180 unsigned char c = *(unsigned char *)(buf+ofs);
1182 if ((c & 0xC0) == 0xC0)
1186 memcpy(p,buf+ofs,2);
1189 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1196 /****************************************************************************
1197 extract a netbios name from a buf
1198 ****************************************************************************/
1199 int name_extract(char *buf,int ofs,char *name)
1201 char *p = name_ptr(buf,ofs);
1202 int d = PTR_DIFF(p,buf+ofs);
1204 if (d < -50 || d > 50) return(0);
1205 return(name_interpret(p,name));
1208 /****************************************************************************
1209 return the total storage length of a mangled name
1210 ****************************************************************************/
1211 int name_len(char *s1)
1213 /* NOTE: this argument _must_ be unsigned */
1214 unsigned char *s = (unsigned char *)s1;
1217 /* If the two high bits of the byte are set, return 2. */
1218 if (0xC0 == (*s & 0xC0))
1221 /* Add up the length bytes. */
1222 for (len = 1; (*s); s += (*s) + 1) {
1224 SMB_ASSERT(len < 80);
1231 /*******************************************************************
1232 sleep for a specified number of milliseconds
1233 ********************************************************************/
1237 struct timeval tval,t1,t2;
1244 tval.tv_sec = (t-tdiff)/1000;
1245 tval.tv_usec = 1000*((t-tdiff)%1000);
1249 sys_select(0,&fds,&tval);
1252 tdiff = TvalDiff(&t1,&t2);
1257 /*********************************************************
1258 * Recursive routine that is called by unix_mask_match.
1259 * Does the actual matching. This is the 'original code'
1260 * used by the unix matcher.
1261 *********************************************************/
1262 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
1266 for( p = regexp; *p && *str; ) {
1273 /* Look for a character matching
1274 the one after the '*' */
1277 return True; /* Automatic match */
1279 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1281 if(unix_do_match(str,p,case_sig))
1295 if(toupper(*str) != toupper(*p))
1305 if (!*p && str[0] == '.' && str[1] == 0)
1308 if (!*str && *p == '?')
1310 while (*p == '?') p++;
1314 if(!*str && (*p == '*' && p[1] == '\0'))
1320 /*********************************************************
1321 * Routine to match a given string with a regexp - uses
1322 * simplified regexp that takes * and ? only. Case can be
1323 * significant or not.
1324 * This is the 'original code' used by the unix matcher.
1325 *********************************************************/
1327 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
1331 fstring ebase,eext,sbase,sext;
1335 /* Make local copies of str and regexp */
1336 StrnCpy(p1,regexp,sizeof(pstring)-1);
1337 StrnCpy(p2,str,sizeof(pstring)-1);
1339 if (!strchr(p2,'.')) {
1343 /* Remove any *? and ** as they are meaningless */
1344 for(p = p1; *p; p++)
1345 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
1346 (void)pstrcpy( &p[1], &p[2]);
1348 if (strequal(p1,"*")) return(True);
1350 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
1356 if ((p=strrchr(p1,'.'))) {
1365 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
1375 matched = unix_do_match(sbase,ebase,case_sig) &&
1376 (trans2 || unix_do_match(sext,eext,case_sig));
1378 DEBUG(8,("unix_mask_match returning %d\n", matched));
1383 /*********************************************************
1384 * Recursive routine that is called by mask_match.
1385 * Does the actual matching. Returns True if matched,
1386 * False if failed. This is the 'new' NT style matcher.
1387 *********************************************************/
1389 BOOL do_match(char *str, char *regexp, int case_sig)
1393 for( p = regexp; *p && *str; ) {
1400 /* Look for a character matching
1401 the one after the '*' */
1404 return True; /* Automatic match */
1406 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
1408 /* Now eat all characters that match, as
1409 we want the *last* character to match. */
1410 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
1412 str--; /* We've eaten the match char after the '*' */
1413 if(do_match(str,p,case_sig)) {
1430 if(toupper(*str) != toupper(*p)) {
1442 if (!*p && str[0] == '.' && str[1] == 0) {
1446 if (!*str && *p == '?') {
1452 if(!*str && (*p == '*' && p[1] == '\0')) {
1460 /*********************************************************
1461 * Routine to match a given string with a regexp - uses
1462 * simplified regexp that takes * and ? only. Case can be
1463 * significant or not.
1464 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
1465 * This is the new 'NT style' matcher.
1466 *********************************************************/
1468 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
1471 pstring t_pattern, t_filename, te_pattern, te_filename;
1472 fstring ebase,eext,sbase,sext;
1474 BOOL matched = False;
1476 /* Make local copies of str and regexp */
1477 pstrcpy(t_pattern,regexp);
1478 pstrcpy(t_filename,str);
1482 * Not sure if this is a good idea. JRA.
1484 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
1489 if (!strchr(t_filename,'.')) {
1490 pstrcat(t_filename,".");
1494 /* Remove any *? and ** as they are meaningless */
1495 string_sub(t_pattern, "*?", "*");
1496 string_sub(t_pattern, "**", "*");
1498 if (strequal(t_pattern,"*"))
1501 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
1505 * Match each component of the regexp, split up by '.'
1508 char *fp, *rp, *cp2, *cp1;
1509 BOOL last_wcard_was_star = False;
1510 int num_path_components, num_regexp_components;
1512 pstrcpy(te_pattern,t_pattern);
1513 pstrcpy(te_filename,t_filename);
1515 * Remove multiple "*." patterns.
1517 string_sub(te_pattern, "*.*.", "*.");
1518 num_regexp_components = count_chars(te_pattern, '.');
1519 num_path_components = count_chars(te_filename, '.');
1522 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
1524 if(num_regexp_components == 0)
1525 matched = do_match( te_filename, te_pattern, case_sig);
1527 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
1528 fp = strchr(cp2, '.');
1531 rp = strchr(cp1, '.');
1535 if(cp1[strlen(cp1)-1] == '*')
1536 last_wcard_was_star = True;
1538 last_wcard_was_star = False;
1540 if(!do_match(cp2, cp1, case_sig))
1543 cp1 = rp ? rp + 1 : NULL;
1544 cp2 = fp ? fp + 1 : "";
1546 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
1547 /* Eat the extra path components. */
1550 for(i = 0; i < num_path_components - num_regexp_components; i++) {
1551 fp = strchr(cp2, '.');
1555 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
1556 cp2 = fp ? fp + 1 : "";
1559 cp2 = fp ? fp + 1 : "";
1561 num_path_components -= i;
1564 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
1569 /* -------------------------------------------------
1570 * Behaviour of Win95
1571 * for 8.3 filenames and 8.3 Wildcards
1572 * -------------------------------------------------
1574 if (strequal (t_filename, ".")) {
1576 * Patterns: *.* *. ?. ? are valid
1579 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1580 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
1582 } else if (strequal (t_filename, "..")) {
1584 * Patterns: *.* *. ?. ? *.? are valid
1587 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
1588 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
1589 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
1593 if ((p = strrchr (t_pattern, '.'))) {
1595 * Wildcard has a suffix.
1598 fstrcpy (ebase, t_pattern);
1600 fstrcpy (eext, p + 1);
1602 /* pattern ends in DOT: treat as if there is no DOT */
1604 if (strequal (ebase, "*"))
1609 * No suffix for wildcard.
1611 fstrcpy (ebase, t_pattern);
1615 p = strrchr (t_filename, '.');
1616 if (p && (p[1] == 0) ) {
1618 * Filename has an extension of '.' only.
1620 *p = 0; /* nuke dot at end of string */
1621 p = 0; /* and treat it as if there is no extension */
1626 * Filename has an extension.
1629 fstrcpy (sbase, t_filename);
1630 fstrcpy (sext, p + 1);
1632 matched = do_match(sbase, ebase, case_sig)
1633 && do_match(sext, eext, case_sig);
1635 /* pattern has no extension */
1636 /* Really: match complete filename with pattern ??? means exactly 3 chars */
1637 matched = do_match(str, ebase, case_sig);
1641 * Filename has no extension.
1643 fstrcpy (sbase, t_filename);
1646 /* pattern has extension */
1647 matched = do_match(sbase, ebase, case_sig)
1648 && do_match(sext, eext, case_sig);
1650 matched = do_match(sbase, ebase, case_sig);
1651 #ifdef EMULATE_WEIRD_W95_MATCHING
1653 * Even Microsoft has some problems
1654 * Behaviour Win95 -> local disk
1655 * is different from Win95 -> smb drive from Nt 4.0
1656 * This branch would reflect the Win95 local disk behaviour
1659 /* a? matches aa and a in w95 */
1660 fstrcat (sbase, ".");
1661 matched = do_match(sbase, ebase, case_sig);
1669 DEBUG(8,("mask_match returning %d\n", matched));
1674 /****************************************************************************
1675 become a daemon, discarding the controlling terminal
1676 ****************************************************************************/
1677 void become_daemon(void)
1683 /* detach from the terminal */
1686 #elif defined(TIOCNOTTY)
1688 int i = open("/dev/tty", O_RDWR);
1690 ioctl(i, (int) TIOCNOTTY, (char *)0);
1694 #endif /* HAVE_SETSID */
1696 /* Close fd's 0,1,2. Needed if started by rsh */
1701 /****************************************************************************
1702 put up a yes/no prompt
1703 ****************************************************************************/
1709 if (!fgets(ans,sizeof(ans)-1,stdin))
1712 if (*ans == 'y' || *ans == 'Y')
1720 /****************************************************************************
1721 set the length of a file from a filedescriptor.
1722 Returns 0 on success, -1 on failure.
1723 ****************************************************************************/
1724 int set_filelen(int fd, SMB_OFF_T len)
1726 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1727 extend a file with ftruncate. Provide alternate implementation
1730 #ifdef HAVE_FTRUNCATE_EXTEND
1731 return sys_ftruncate(fd, len);
1735 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
1739 /* Do an fstat to see if the file is longer than
1740 the requested size (call ftruncate),
1741 or shorter, in which case seek to len - 1 and write 1
1743 if(sys_fstat(fd, &st)<0)
1747 if (S_ISFIFO(st.st_mode)) return 0;
1750 if(st.st_size == len)
1752 if(st.st_size > len)
1753 return sys_ftruncate(fd, len);
1755 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
1757 if(write(fd, &c, 1)!=1)
1759 /* Seek to where we were */
1760 if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
1768 /****************************************************************************
1769 this is a version of setbuffer() for those machines that only have setvbuf
1770 ****************************************************************************/
1771 void setbuffer(FILE *f,char *buf,int bufsize)
1773 setvbuf(f,buf,_IOFBF,bufsize);
1778 /****************************************************************************
1779 parse out a filename from a path name. Assumes dos style filenames.
1780 ****************************************************************************/
1781 static char *filename_dos(char *path,char *buf)
1783 char *p = strrchr(path,'\\');
1795 /****************************************************************************
1796 expand a pointer to be a particular size
1797 ****************************************************************************/
1798 void *Realloc(void *p,size_t size)
1804 DEBUG(5,("Realloc asked for 0 bytes\n"));
1809 ret = (void *)malloc(size);
1811 ret = (void *)realloc(p,size);
1816 smb_mem_write_info(ret, dbf);
1821 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
1827 /****************************************************************************
1828 get my own name and IP
1829 ****************************************************************************/
1830 BOOL get_myname(char *my_name,struct in_addr *ip)
1837 /* get my host name */
1838 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
1840 DEBUG(0,("gethostname failed\n"));
1845 if ((hp = Get_Hostbyname(hostname)) == 0)
1847 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
1853 /* split off any parts after an initial . */
1854 char *p = strchr(hostname,'.');
1857 fstrcpy(my_name,hostname);
1861 putip((char *)ip,(char *)hp->h_addr);
1867 /****************************************************************************
1868 true if two IP addresses are equal
1869 ****************************************************************************/
1870 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
1873 a1 = ntohl(ip1.s_addr);
1874 a2 = ntohl(ip2.s_addr);
1879 /****************************************************************************
1880 interpret a protocol description string, with a default
1881 ****************************************************************************/
1882 int interpret_protocol(char *str,int def)
1884 if (strequal(str,"NT1"))
1885 return(PROTOCOL_NT1);
1886 if (strequal(str,"LANMAN2"))
1887 return(PROTOCOL_LANMAN2);
1888 if (strequal(str,"LANMAN1"))
1889 return(PROTOCOL_LANMAN1);
1890 if (strequal(str,"CORE"))
1891 return(PROTOCOL_CORE);
1892 if (strequal(str,"COREPLUS"))
1893 return(PROTOCOL_COREPLUS);
1894 if (strequal(str,"CORE+"))
1895 return(PROTOCOL_COREPLUS);
1897 DEBUG(0,("Unrecognised protocol level %s\n",str));
1903 /****************************************************************************
1904 interpret an internet address or name into an IP address in 4 byte form
1905 ****************************************************************************/
1906 uint32 interpret_addr(char *str)
1911 BOOL pure_address = True;
1913 if (strcmp(str,"0.0.0.0") == 0) return(0);
1914 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
1916 for (i=0; pure_address && str[i]; i++)
1917 if (!(isdigit((int)str[i]) || str[i] == '.'))
1918 pure_address = False;
1920 /* if it's in the form of an IP address then get the lib to interpret it */
1922 res = inet_addr(str);
1924 /* otherwise assume it's a network name of some sort and use
1926 if ((hp = Get_Hostbyname(str)) == 0) {
1927 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
1930 if(hp->h_addr == NULL) {
1931 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
1934 putip((char *)&res,(char *)hp->h_addr);
1937 if (res == (uint32)-1) return(0);
1942 /*******************************************************************
1943 a convenient addition to interpret_addr()
1944 ******************************************************************/
1945 struct in_addr *interpret_addr2(char *str)
1947 static struct in_addr ret;
1948 uint32 a = interpret_addr(str);
1953 /*******************************************************************
1954 check if an IP is the 0.0.0.0
1955 ******************************************************************/
1956 BOOL zero_ip(struct in_addr ip)
1959 putip((char *)&a,(char *)&ip);
1964 /*******************************************************************
1965 matchname - determine if host name matches IP address
1966 ******************************************************************/
1967 BOOL matchname(char *remotehost,struct in_addr addr)
1972 if ((hp = Get_Hostbyname(remotehost)) == 0) {
1973 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
1978 * Make sure that gethostbyname() returns the "correct" host name.
1979 * Unfortunately, gethostbyname("localhost") sometimes yields
1980 * "localhost.domain". Since the latter host name comes from the
1981 * local DNS, we just have to trust it (all bets are off if the local
1982 * DNS is perverted). We always check the address list, though.
1985 if (strcasecmp(remotehost, hp->h_name)
1986 && strcasecmp(remotehost, "localhost")) {
1987 DEBUG(0,("host name/name mismatch: %s != %s",
1988 remotehost, hp->h_name));
1992 /* Look up the host address in the address list we just got. */
1993 for (i = 0; hp->h_addr_list[i]; i++) {
1994 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
1999 * The host name does not map to the original host address. Perhaps
2000 * someone has compromised a name server. More likely someone botched
2001 * it, but that could be dangerous, too.
2004 DEBUG(0,("host name/address mismatch: %s != %s",
2005 inet_ntoa(addr), hp->h_name));
2010 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
2011 /******************************************************************
2012 Remove any mount options such as -rsize=2048,wsize=2048 etc.
2013 Based on a fix from <Thomas.Hepper@icem.de>.
2014 *******************************************************************/
2016 static void strip_mount_options( pstring *str)
2021 while(*p && !isspace(*p))
2023 while(*p && isspace(*p))
2028 pstrcpy(tmp_str, p);
2029 pstrcpy(*str, tmp_str);
2034 /*******************************************************************
2035 Patch from jkf@soton.ac.uk
2036 Split Luke's automount_server into YP lookup and string splitter
2037 so can easily implement automount_path().
2038 As we may end up doing both, cache the last YP result.
2039 *******************************************************************/
2041 #ifdef WITH_NISPLUS_HOME
2042 static char *automount_lookup(char *user_name)
2044 static fstring last_key = "";
2045 static pstring last_value = "";
2047 char *nis_map = (char *)lp_nis_home_map_name();
2049 char nis_domain[NIS_MAXNAMELEN + 1];
2050 char buffer[NIS_MAXATTRVAL + 1];
2055 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
2056 nis_domain[NIS_MAXNAMELEN] = '\0';
2058 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
2060 if (strcmp(user_name, last_key))
2062 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
2063 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
2065 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
2067 if (result->status != NIS_SUCCESS)
2069 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
2070 fstrcpy(last_key, ""); pstrcpy(last_value, "");
2074 object = result->objects.objects_val;
2075 if (object->zo_data.zo_type == ENTRY_OBJ)
2077 entry = &object->zo_data.objdata_u.en_data;
2078 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
2079 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
2081 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
2082 string_sub(last_value, "&", user_name);
2083 fstrcpy(last_key, user_name);
2087 nis_freeresult(result);
2090 strip_mount_options(&last_value);
2092 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
2095 #else /* WITH_NISPLUS_HOME */
2096 static char *automount_lookup(char *user_name)
2098 static fstring last_key = "";
2099 static pstring last_value = "";
2101 int nis_error; /* returned by yp all functions */
2102 char *nis_result; /* yp_match inits this */
2103 int nis_result_len; /* and set this */
2104 char *nis_domain; /* yp_get_default_domain inits this */
2105 char *nis_map = (char *)lp_nis_home_map_name();
2107 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
2109 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
2113 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
2115 if (!strcmp(user_name, last_key))
2117 nis_result = last_value;
2118 nis_result_len = strlen(last_value);
2123 if ((nis_error = yp_match(nis_domain, nis_map,
2124 user_name, strlen(user_name),
2125 &nis_result, &nis_result_len)) != 0)
2127 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
2128 yperr_string(nis_error), user_name, nis_map));
2130 if (!nis_error && nis_result_len >= sizeof(pstring))
2132 nis_result_len = sizeof(pstring)-1;
2134 fstrcpy(last_key, user_name);
2135 strncpy(last_value, nis_result, nis_result_len);
2136 last_value[nis_result_len] = '\0';
2139 strip_mount_options(&last_value);
2141 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
2144 #endif /* WITH_NISPLUS_HOME */
2147 /*******************************************************************
2148 Patch from jkf@soton.ac.uk
2149 This is Luke's original function with the NIS lookup code
2150 moved out to a separate function.
2151 *******************************************************************/
2152 static char *automount_server(char *user_name)
2154 static pstring server_name;
2156 /* use the local machine name as the default */
2157 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2158 pstrcpy(server_name, local_machine);
2160 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2162 if (lp_nis_home_map())
2164 int home_server_len;
2165 char *automount_value = automount_lookup(user_name);
2166 home_server_len = strcspn(automount_value,":");
2167 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
2168 if (home_server_len > sizeof(pstring))
2170 home_server_len = sizeof(pstring);
2172 strncpy(server_name, automount_value, home_server_len);
2173 server_name[home_server_len] = '\0';
2177 DEBUG(4,("Home server: %s\n", server_name));
2182 /*******************************************************************
2183 Patch from jkf@soton.ac.uk
2184 Added this to implement %p (NIS auto-map version of %H)
2185 *******************************************************************/
2186 static char *automount_path(char *user_name)
2188 static pstring server_path;
2190 /* use the passwd entry as the default */
2191 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
2192 /* pstrcpy() copes with get_home_dir() returning NULL */
2193 pstrcpy(server_path, get_home_dir(user_name));
2195 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
2197 if (lp_nis_home_map())
2199 char *home_path_start;
2200 char *automount_value = automount_lookup(user_name);
2201 home_path_start = strchr(automount_value,':');
2202 if (home_path_start != NULL)
2204 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
2205 home_path_start?(home_path_start+1):""));
2206 pstrcpy(server_path, home_path_start+1);
2211 DEBUG(4,("Home server path: %s\n", server_path));
2217 /*******************************************************************
2218 sub strings with useful parameters
2219 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
2220 Paul Rippin <pr3245@nopc.eurostat.cec.be>
2221 ********************************************************************/
2222 void standard_sub_basic(char *str)
2226 struct passwd *pass;
2227 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
2229 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
2235 if ((pass = Get_Pwnam(username,False))!=NULL)
2237 string_sub(p,"%G",gidtoname(pass->pw_gid));
2245 case 'N' : string_sub(p,"%N", automount_server(username)); break;
2246 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
2247 case 'L' : string_sub(p,"%L", local_machine); break;
2248 case 'M' : string_sub(p,"%M", client_name(Client)); break;
2249 case 'R' : string_sub(p,"%R", remote_proto); break;
2250 case 'T' : string_sub(p,"%T", timestring()); break;
2251 case 'U' : string_sub(p,"%U", username); break;
2252 case 'a' : string_sub(p,"%a", remote_arch); break;
2255 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
2256 string_sub(p,"%d", pidstr);
2259 case 'h' : string_sub(p,"%h", myhostname); break;
2260 case 'm' : string_sub(p,"%m", remote_machine); break;
2261 case 'v' : string_sub(p,"%v", VERSION); break;
2262 case '$' : /* Expand environment variables */
2264 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
2275 if ((q = strchr(p,')')) == NULL)
2277 DEBUG(0,("standard_sub_basic: Unterminated environment \
2278 variable [%s]\n", p));
2284 copylen = MIN((q-r),(sizeof(envname)-1));
2285 strncpy(envname,r,copylen);
2286 envname[copylen] = '\0';
2288 if ((envval = getenv(envname)) == NULL)
2290 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
2296 copylen = MIN((q+1-p),(sizeof(envname)-1));
2297 strncpy(envname,p,copylen);
2298 envname[copylen] = '\0';
2299 string_sub(p,envname,envval);
2302 case '\0': p++; break; /* don't run off end if last character is % */
2303 default : p+=2; break;
2310 /****************************************************************************
2311 do some standard substitutions in a string
2312 ****************************************************************************/
2313 void standard_sub(connection_struct *conn,char *str)
2317 for (s=str; (p=strchr(s, '%'));s=p) {
2320 if ((home = get_home_dir(conn->user))) {
2321 string_sub(p,"%H",home);
2328 string_sub(p,"%P",conn->connectpath);
2333 lp_servicename(SNUM(conn)));
2338 gidtoname(conn->gid));
2341 string_sub(p,"%u",conn->user);
2344 /* Patch from jkf@soton.ac.uk Left the %N (NIS
2345 * server name) in standard_sub_basic as it is
2346 * a feature for logon servers, hence uses the
2347 * username. The %p (NIS server path) code is
2348 * here as it is used instead of the default
2349 * "path =" string in [homes] and so needs the
2350 * service name, not the username. */
2353 automount_path(lp_servicename(SNUM(conn))));
2357 break; /* don't run off the end of the string
2365 standard_sub_basic(str);
2370 /*******************************************************************
2371 are two IPs on the same subnet?
2372 ********************************************************************/
2373 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2375 uint32 net1,net2,nmask;
2377 nmask = ntohl(mask.s_addr);
2378 net1 = ntohl(ip1.s_addr);
2379 net2 = ntohl(ip2.s_addr);
2381 return((net1 & nmask) == (net2 & nmask));
2385 /****************************************************************************
2386 a wrapper for gethostbyname() that tries with all lower and all upper case
2387 if the initial name fails
2388 ****************************************************************************/
2389 struct hostent *Get_Hostbyname(char *name)
2391 char *name2 = strdup(name);
2392 struct hostent *ret;
2396 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
2402 * This next test is redundent and causes some systems (with
2403 * broken isalnum() calls) problems.
2408 if (!isalnum(*name2))
2415 ret = sys_gethostbyname(name2);
2422 /* try with all lowercase */
2424 ret = sys_gethostbyname(name2);
2431 /* try with all uppercase */
2433 ret = sys_gethostbyname(name2);
2440 /* nothing works :-( */
2446 /****************************************************************************
2447 check if a process exists. Does this work on all unixes?
2448 ****************************************************************************/
2450 BOOL process_exists(int pid)
2452 return(kill(pid,0) == 0 || errno != ESRCH);
2456 /*******************************************************************
2457 turn a uid into a user name
2458 ********************************************************************/
2459 char *uidtoname(uid_t uid)
2461 static char name[40];
2462 struct passwd *pass = getpwuid(uid);
2463 if (pass) return(pass->pw_name);
2464 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
2469 /*******************************************************************
2470 turn a gid into a group name
2471 ********************************************************************/
2473 char *gidtoname(gid_t gid)
2475 static char name[40];
2476 struct group *grp = getgrgid(gid);
2477 if (grp) return(grp->gr_name);
2478 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
2482 /*******************************************************************
2483 turn a user name into a uid
2484 ********************************************************************/
2485 uid_t nametouid(const char *name)
2487 struct passwd *pass = getpwnam(name);
2488 if (pass) return(pass->pw_uid);
2492 /*******************************************************************
2493 something really nasty happened - panic!
2494 ********************************************************************/
2495 void smb_panic(char *why)
2497 char *cmd = lp_panic_action();
2501 DEBUG(0,("PANIC: %s\n", why));
2507 /*******************************************************************
2508 a readdir wrapper which just returns the file name
2509 ********************************************************************/
2510 char *readdirname(void *p)
2515 if (!p) return(NULL);
2517 ptr = (struct dirent *)readdir(p);
2518 if (!ptr) return(NULL);
2520 dname = ptr->d_name;
2523 if (telldir(p) < 0) return(NULL);
2526 #ifdef HAVE_BROKEN_READDIR
2527 /* using /usr/ucb/cc is BAD */
2533 memcpy(buf, dname, NAMLEN(ptr)+1);
2534 unix_to_dos(buf, True);
2541 /*******************************************************************
2542 Utility function used to decide if the last component
2543 of a path matches a (possibly wildcarded) entry in a namelist.
2544 ********************************************************************/
2546 BOOL is_in_path(char *name, name_compare_entry *namelist)
2548 pstring last_component;
2551 DEBUG(8, ("is_in_path: %s\n", name));
2553 /* if we have no list it's obviously not in the path */
2554 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
2556 DEBUG(8,("is_in_path: no name list.\n"));
2560 /* Get the last component of the unix name. */
2561 p = strrchr(name, '/');
2562 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
2563 last_component[sizeof(last_component)-1] = '\0';
2565 for(; namelist->name != NULL; namelist++)
2567 if(namelist->is_wild)
2570 * Look for a wildcard match. Use the old
2571 * 'unix style' mask match, rather than the
2574 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
2576 DEBUG(8,("is_in_path: mask match succeeded\n"));
2582 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
2583 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
2585 DEBUG(8,("is_in_path: match succeeded\n"));
2590 DEBUG(8,("is_in_path: match not found\n"));
2595 /*******************************************************************
2596 Strip a '/' separated list into an array of
2597 name_compare_enties structures suitable for
2598 passing to is_in_path(). We do this for
2599 speed so we can pre-parse all the names in the list
2600 and don't do it for each call to is_in_path().
2601 namelist is modified here and is assumed to be
2602 a copy owned by the caller.
2603 We also check if the entry contains a wildcard to
2604 remove a potentially expensive call to mask_match
2606 ********************************************************************/
2608 void set_namearray(name_compare_entry **ppname_array, char *namelist)
2611 char *nameptr = namelist;
2612 int num_entries = 0;
2615 (*ppname_array) = NULL;
2617 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
2620 /* We need to make two passes over the string. The
2621 first to count the number of elements, the second
2626 if ( *nameptr == '/' )
2628 /* cope with multiple (useless) /s) */
2632 /* find the next / */
2633 name_end = strchr(nameptr, '/');
2635 /* oops - the last check for a / didn't find one. */
2636 if (name_end == NULL)
2639 /* next segment please */
2640 nameptr = name_end + 1;
2644 if(num_entries == 0)
2647 if(( (*ppname_array) = (name_compare_entry *)malloc(
2648 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
2650 DEBUG(0,("set_namearray: malloc fail\n"));
2654 /* Now copy out the names */
2659 if ( *nameptr == '/' )
2661 /* cope with multiple (useless) /s) */
2665 /* find the next / */
2666 if ((name_end = strchr(nameptr, '/')) != NULL)
2671 /* oops - the last check for a / didn't find one. */
2672 if(name_end == NULL)
2675 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
2676 (strchr( nameptr, '*')!=NULL));
2677 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
2679 DEBUG(0,("set_namearray: malloc fail (1)\n"));
2683 /* next segment please */
2684 nameptr = name_end + 1;
2688 (*ppname_array)[i].name = NULL;
2693 /****************************************************************************
2694 routine to free a namearray.
2695 ****************************************************************************/
2697 void free_namearray(name_compare_entry *name_array)
2702 if(name_array->name != NULL)
2703 free(name_array->name);
2705 free((char *)name_array);
2708 /****************************************************************************
2709 routine to do file locking
2710 ****************************************************************************/
2711 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
2714 SMB_STRUCT_FLOCK lock;
2717 if(lp_ole_locking_compat()) {
2718 SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
2719 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
2721 /* make sure the count is reasonable, we might kill the lockd otherwise */
2724 /* the offset is often strange - remove 2 of its bits if either of
2725 the top two bits are set. Shift the top ones by two bits. This
2726 still allows OLE2 apps to operate, but should stop lockd from
2728 if ((offset & mask) != 0)
2729 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
2731 SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
2732 SMB_OFF_T neg_mask = ~mask;
2734 /* interpret negative counts as large numbers */
2738 /* no negative offsets */
2742 /* count + offset must be in range */
2743 while ((offset < 0 || (offset + count < 0)) && mask)
2746 mask = ((mask >> 1) & neg_mask);
2750 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
2753 lock.l_whence = SEEK_SET;
2754 lock.l_start = offset;
2760 ret = fcntl(fd,op,&lock);
2765 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
2766 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
2767 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
2769 /* 32 bit NFS file system, retry with smaller offset */
2771 lock.l_len = count & 0xffffffff;
2772 ret = fcntl(fd,op,&lock);
2776 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
2779 if (op == SMB_F_GETLK)
2782 (lock.l_type != F_UNLCK) &&
2783 (lock.l_pid != 0) &&
2784 (lock.l_pid != getpid()))
2786 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
2790 /* it must be not locked or locked by me */
2794 /* a lock set or unset */
2797 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
2798 (double)offset,(double)count,op,type,strerror(errno)));
2800 /* perhaps it doesn't support this sort of locking?? */
2801 if (errno == EINVAL)
2803 DEBUG(3,("locking not supported? returning True\n"));
2810 /* everything went OK */
2811 DEBUG(8,("Lock call successful\n"));
2819 /*******************************************************************
2820 is the name specified one of my netbios names
2821 returns true is it is equal, false otherwise
2822 ********************************************************************/
2823 BOOL is_myname(char *s)
2828 for (n=0; my_netbios_names[n]; n++) {
2829 if (strequal(my_netbios_names[n], s))
2832 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2836 /*******************************************************************
2837 set the horrid remote_arch string based on an enum.
2838 ********************************************************************/
2839 void set_remote_arch(enum remote_arch_types type)
2845 fstrcpy(remote_arch, "WfWg");
2848 fstrcpy(remote_arch, "OS2");
2851 fstrcpy(remote_arch, "Win95");
2854 fstrcpy(remote_arch, "WinNT");
2857 fstrcpy(remote_arch,"Samba");
2860 ra_type = RA_UNKNOWN;
2861 fstrcpy(remote_arch, "UNKNOWN");
2866 /*******************************************************************
2867 Get the remote_arch type.
2868 ********************************************************************/
2869 enum remote_arch_types get_remote_arch(void)
2875 /*******************************************************************
2876 align a pointer to a multiple of 2 bytes
2877 ********************************************************************/
2878 char *align2(char *q, char *base)
2887 void out_ascii(FILE *f, unsigned char *buf,int len)
2892 fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
2896 void out_data(FILE *f,char *buf1,int len, int per_line)
2898 unsigned char *buf = (unsigned char *)buf1;
2905 fprintf(f, "[%03X] ",i);
2908 fprintf(f, "%02X ",(int)buf[i]);
2910 if (i%(per_line/2) == 0) fprintf(f, " ");
2911 if (i%per_line == 0)
2913 out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
2914 out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
2915 if (i<len) fprintf(f, "[%03X] ",i);
2918 if ((i%per_line) != 0)
2922 n = per_line - (i%per_line);
2924 if (n>(per_line/2)) fprintf(f, " ");
2929 n = MIN(per_line/2,i%per_line);
2930 out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
2931 n = (i%per_line) - n;
2932 if (n>0) out_ascii(f,&buf[i-n],n);
2937 void print_asc(int level, unsigned char *buf,int len)
2941 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2944 void dump_data(int level,char *buf1,int len)
2946 unsigned char *buf = (unsigned char *)buf1;
2950 DEBUG(level,("[%03X] ",i));
2952 DEBUG(level,("%02X ",(int)buf[i]));
2954 if (i%8 == 0) DEBUG(level,(" "));
2956 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
2957 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
2958 if (i<len) DEBUG(level,("[%03X] ",i));
2966 if (n>8) DEBUG(level,(" "));
2967 while (n--) DEBUG(level,(" "));
2970 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
2972 if (n>0) print_asc(level,&buf[i-n],n);
2973 DEBUG(level,("\n"));
2977 char *tab_depth(int depth)
2979 static pstring spaces;
2980 memset(spaces, ' ', depth * 4);
2981 spaces[depth * 4] = 0;
2985 /*****************************************************************************
2986 * Provide a checksum on a string
2988 * Input: s - the null-terminated character string for which the checksum
2989 * will be calculated.
2991 * Output: The checksum value calculated for s.
2993 * ****************************************************************************
2995 int str_checksum(const char *s)
3003 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
3008 } /* str_checksum */
3012 /*****************************************************************
3013 zero a memory area then free it. Used to catch bugs faster
3014 *****************************************************************/
3015 void zero_free(void *p, size_t size)
3022 /*****************************************************************
3023 set our open file limit to a requested max and return the limit
3024 *****************************************************************/
3025 int set_maxfiles(int requested_max)
3027 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
3029 getrlimit(RLIMIT_NOFILE, &rlp);
3030 /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
3031 * account for the extra fd we need
3032 * as well as the log files and standard
3034 rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
3035 setrlimit(RLIMIT_NOFILE, &rlp);
3036 getrlimit(RLIMIT_NOFILE, &rlp);
3037 return rlp.rlim_cur;
3040 * No way to know - just guess...
3042 return requested_max;
3047 /*****************************************************************
3048 splits out the last subkey of a key
3049 *****************************************************************/
3050 void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
3052 split_at_last_component(full_keyname, key_name, '\\', subkey_name);
3055 /*****************************************************************
3056 splits out the start of the key (HKLM or HKU) and the rest of the key
3057 *****************************************************************/
3058 BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
3062 if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
3069 DEBUG(10, ("reg_split_key: hive %s\n", tmp));
3071 if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
3073 (*reg_type) = HKEY_LOCAL_MACHINE;
3075 else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
3077 (*reg_type) = HKEY_USERS;
3081 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
3085 if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
3087 fstrcpy(key_name, tmp);
3094 DEBUG(10, ("reg_split_key: name %s\n", key_name));