ypserver not available: AUTOMOUNT server and path don't work.
[Samba.git] / source / lib / util.c
blob46fda4ae8b948e74b038497072e2c2a4773c6dea
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
24 #if (defined(NETGROUP) && defined (AUTOMOUNT))
25 #include "rpcsvc/ypclnt.h"
26 #endif
28 pstring scope = "";
30 int DEBUGLEVEL = 1;
32 BOOL passive = False;
34 int Protocol = PROTOCOL_COREPLUS;
36 /* a default finfo structure to ensure all fields are sensible */
37 file_info def_finfo = {-1,0,0,0,0,0,0,""};
39 /* these are some file handles where debug info will be stored */
40 FILE *dbf = NULL;
42 /* the client file descriptor */
43 int Client = -1;
45 /* the last IP received from */
46 struct in_addr lastip;
48 /* the last port received from */
49 int lastport=0;
51 /* this is used by the chaining code */
52 int chain_size = 0;
54 int trans_num = 0;
57 case handling on filenames
59 int case_default = CASE_LOWER;
61 pstring debugf = "";
62 int syslog_level;
64 /* the following control case operations - they are put here so the
65 client can link easily */
66 BOOL case_sensitive;
67 BOOL case_preserve;
68 BOOL use_mangled_map = False;
69 BOOL short_case_preserve;
70 BOOL case_mangle;
72 fstring remote_machine="";
73 fstring local_machine="";
74 fstring remote_arch="UNKNOWN";
75 static enum remote_arch_types ra_type = RA_UNKNOWN;
76 fstring remote_proto="UNKNOWN";
77 pstring myhostname="";
78 pstring user_socket_options="";
80 pstring sesssetup_user="";
81 pstring samlogon_user="";
83 BOOL sam_logon_in_ssb = False;
85 pstring myname = "";
86 fstring myworkgroup = "";
87 char **my_netbios_names;
89 int smb_read_error = 0;
91 static BOOL stdout_logging = False;
93 static char *filename_dos(char *path,char *buf);
95 #if defined(SIGUSR2)
96 /******************************************************************************
97 catch a sigusr2 - decrease the debug log level.
98 *****************************************************************************/
99 int sig_usr2(void)
101 BlockSignals( True, SIGUSR2);
103 DEBUGLEVEL--;
105 if(DEBUGLEVEL < 0)
106 DEBUGLEVEL = 0;
108 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
110 BlockSignals( False, SIGUSR2);
111 #ifndef DONT_REINSTALL_SIG
112 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
113 #endif
114 return(0);
116 #endif /* SIGUSR1 */
118 #if defined(SIGUSR1)
119 /**************************************************************************** **
120 catch a sigusr1 - increase the debug log level.
121 **************************************************************************** */
122 int sig_usr1(void)
124 BlockSignals( True, SIGUSR1);
126 DEBUGLEVEL++;
128 if(DEBUGLEVEL > 10)
129 DEBUGLEVEL = 10;
131 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
133 BlockSignals( False, SIGUSR1);
134 #ifndef DONT_REINSTALL_SIG
135 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
136 #endif
137 return(0);
139 #endif /* SIGUSR1 */
142 /*******************************************************************
143 get ready for syslog stuff
144 ******************************************************************/
145 void setup_logging(char *pname,BOOL interactive)
147 #ifdef SYSLOG
148 if (!interactive) {
149 char *p = strrchr(pname,'/');
150 if (p) pname = p+1;
151 #ifdef LOG_DAEMON
152 openlog(pname, LOG_PID, SYSLOG_FACILITY);
153 #else /* for old systems that have no facility codes. */
154 openlog(pname, LOG_PID);
155 #endif
157 #endif
158 if (interactive) {
159 stdout_logging = True;
160 dbf = stdout;
165 BOOL append_log=False;
168 /****************************************************************************
169 reopen the log files
170 ****************************************************************************/
171 void reopen_logs(void)
173 pstring fname;
175 if (DEBUGLEVEL > 0)
177 strcpy(fname,debugf);
178 if (lp_loaded() && (*lp_logfile()))
179 strcpy(fname,lp_logfile());
181 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
183 int oldumask = umask(022);
184 strcpy(debugf,fname);
185 if (dbf) fclose(dbf);
186 if (append_log)
187 dbf = fopen(debugf,"a");
188 else
189 dbf = fopen(debugf,"w");
190 if (dbf) setbuf(dbf,NULL);
191 umask(oldumask);
194 else
196 if (dbf)
198 fclose(dbf);
199 dbf = NULL;
205 /*******************************************************************
206 check if the log has grown too big
207 ********************************************************************/
208 static void check_log_size(void)
210 static int debug_count=0;
211 int maxlog;
212 struct stat st;
214 if (debug_count++ < 100 || getuid() != 0) return;
216 maxlog = lp_max_log_size() * 1024;
217 if (!dbf || maxlog <= 0) return;
219 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
220 fclose(dbf); dbf = NULL;
221 reopen_logs();
222 if (dbf && file_size(debugf) > maxlog) {
223 pstring name;
224 fclose(dbf); dbf = NULL;
225 sprintf(name,"%s.old",debugf);
226 sys_rename(debugf,name);
227 reopen_logs();
230 debug_count=0;
234 /*******************************************************************
235 write an debug message on the debugfile. This is called by the DEBUG
236 macro
237 ********************************************************************/
238 #ifdef __STDC__
239 int Debug1(char *format_str, ...)
241 #else
242 int Debug1(va_alist)
243 va_dcl
245 char *format_str;
246 #endif
247 va_list ap;
248 int old_errno = errno;
250 if (stdout_logging) {
251 #ifdef __STDC__
252 va_start(ap, format_str);
253 #else
254 va_start(ap);
255 format_str = va_arg(ap,char *);
256 #endif
257 vfprintf(dbf,format_str,ap);
258 va_end(ap);
259 errno = old_errno;
260 return(0);
263 #ifdef SYSLOG
264 if (!lp_syslog_only())
265 #endif
267 if (!dbf) {
268 int oldumask = umask(022);
269 dbf = fopen(debugf,"w");
270 umask(oldumask);
271 if (dbf) {
272 setbuf(dbf,NULL);
273 } else {
274 errno = old_errno;
275 return(0);
280 #ifdef SYSLOG
281 if (syslog_level < lp_syslog())
284 * map debug levels to syslog() priorities
285 * note that not all DEBUG(0, ...) calls are
286 * necessarily errors
288 static int priority_map[] = {
289 LOG_ERR, /* 0 */
290 LOG_WARNING, /* 1 */
291 LOG_NOTICE, /* 2 */
292 LOG_INFO, /* 3 */
294 int priority;
295 pstring msgbuf;
297 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
298 syslog_level < 0)
299 priority = LOG_DEBUG;
300 else
301 priority = priority_map[syslog_level];
303 #ifdef __STDC__
304 va_start(ap, format_str);
305 #else
306 va_start(ap);
307 format_str = va_arg(ap,char *);
308 #endif
309 vsprintf(msgbuf, format_str, ap);
310 va_end(ap);
312 msgbuf[255] = '\0';
313 syslog(priority, "%s", msgbuf);
315 #endif
317 #ifdef SYSLOG
318 if (!lp_syslog_only())
319 #endif
321 #ifdef __STDC__
322 va_start(ap, format_str);
323 #else
324 va_start(ap);
325 format_str = va_arg(ap,char *);
326 #endif
327 vfprintf(dbf,format_str,ap);
328 va_end(ap);
329 fflush(dbf);
332 check_log_size();
334 errno = old_errno;
336 return(0);
339 /****************************************************************************
340 find a suitable temporary directory. The result should be copied immediately
341 as it may be overwritten by a subsequent call
342 ****************************************************************************/
343 char *tmpdir(void)
345 char *p;
346 if ((p = getenv("TMPDIR"))) {
347 return p;
349 return "/tmp";
354 /****************************************************************************
355 determine if a file descriptor is in fact a socket
356 ****************************************************************************/
357 BOOL is_a_socket(int fd)
359 int v,l;
360 l = sizeof(int);
361 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
365 static char *last_ptr=NULL;
367 /****************************************************************************
368 Get the next token from a string, return False if none found
369 handles double-quotes.
370 Based on a routine by GJC@VILLAGE.COM.
371 Extensively modified by Andrew.Tridgell@anu.edu.au
372 ****************************************************************************/
373 BOOL next_token(char **ptr,char *buff,char *sep)
375 char *s;
376 BOOL quoted;
378 if (!ptr) ptr = &last_ptr;
379 if (!ptr) return(False);
381 s = *ptr;
383 /* default to simple separators */
384 if (!sep) sep = " \t\n\r";
386 /* find the first non sep char */
387 while(*s && strchr(sep,*s)) s++;
389 /* nothing left? */
390 if (! *s) return(False);
392 /* copy over the token */
393 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
395 if (*s == '\"')
396 quoted = !quoted;
397 else
398 *buff++ = *s;
401 *ptr = (*s) ? s+1 : s;
402 *buff = 0;
403 last_ptr = *ptr;
405 return(True);
408 /****************************************************************************
409 Convert list of tokens to array; dependent on above routine.
410 Uses last_ptr from above - bit of a hack.
411 ****************************************************************************/
412 char **toktocliplist(int *ctok, char *sep)
414 char *s=last_ptr;
415 int ictok=0;
416 char **ret, **iret;
418 if (!sep) sep = " \t\n\r";
420 while(*s && strchr(sep,*s)) s++;
422 /* nothing left? */
423 if (!*s) return(NULL);
425 do {
426 ictok++;
427 while(*s && (!strchr(sep,*s))) s++;
428 while(*s && strchr(sep,*s)) *s++=0;
429 } while(*s);
431 *ctok=ictok;
432 s=last_ptr;
434 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
436 while(ictok--) {
437 *iret++=s;
438 while(*s++);
439 while(!*s) s++;
442 return ret;
445 #ifndef HAVE_MEMMOVE
446 /*******************************************************************
447 safely copies memory, ensuring no overlap problems.
448 this is only used if the machine does not have it's own memmove().
449 this is not the fastest algorithm in town, but it will do for our
450 needs.
451 ********************************************************************/
452 void *MemMove(void *dest,void *src,int size)
454 unsigned long d,s;
455 int i;
456 if (dest==src || !size) return(dest);
458 d = (unsigned long)dest;
459 s = (unsigned long)src;
461 if ((d >= (s+size)) || (s >= (d+size))) {
462 /* no overlap */
463 memcpy(dest,src,size);
464 return(dest);
467 if (d < s)
469 /* we can forward copy */
470 if (s-d >= sizeof(int) &&
471 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
472 /* do it all as words */
473 int *idest = (int *)dest;
474 int *isrc = (int *)src;
475 size /= sizeof(int);
476 for (i=0;i<size;i++) idest[i] = isrc[i];
477 } else {
478 /* simplest */
479 char *cdest = (char *)dest;
480 char *csrc = (char *)src;
481 for (i=0;i<size;i++) cdest[i] = csrc[i];
484 else
486 /* must backward copy */
487 if (d-s >= sizeof(int) &&
488 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
489 /* do it all as words */
490 int *idest = (int *)dest;
491 int *isrc = (int *)src;
492 size /= sizeof(int);
493 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
494 } else {
495 /* simplest */
496 char *cdest = (char *)dest;
497 char *csrc = (char *)src;
498 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
501 return(dest);
503 #endif
506 /****************************************************************************
507 prompte a dptr (to make it recently used)
508 ****************************************************************************/
509 void array_promote(char *array,int elsize,int element)
511 char *p;
512 if (element == 0)
513 return;
515 p = (char *)malloc(elsize);
517 if (!p)
519 DEBUG(5,("Ahh! Can't malloc\n"));
520 return;
522 memcpy(p,array + element * elsize, elsize);
523 memmove(array + elsize,array,elsize*element);
524 memcpy(array,p,elsize);
525 free(p);
528 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
530 struct
532 char *name;
533 int level;
534 int option;
535 int value;
536 int opttype;
537 } socket_options[] = {
538 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
539 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
540 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
541 #ifdef TCP_NODELAY
542 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
543 #endif
544 #ifdef IPTOS_LOWDELAY
545 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
546 #endif
547 #ifdef IPTOS_THROUGHPUT
548 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
549 #endif
550 #ifdef SO_SNDBUF
551 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
552 #endif
553 #ifdef SO_RCVBUF
554 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
555 #endif
556 #ifdef SO_SNDLOWAT
557 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
558 #endif
559 #ifdef SO_RCVLOWAT
560 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
561 #endif
562 #ifdef SO_SNDTIMEO
563 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
564 #endif
565 #ifdef SO_RCVTIMEO
566 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
567 #endif
568 {NULL,0,0,0,0}};
572 /****************************************************************************
573 set user socket options
574 ****************************************************************************/
575 void set_socket_options(int fd, char *options)
577 string tok;
579 while (next_token(&options,tok," \t,"))
581 int ret=0,i;
582 int value = 1;
583 char *p;
584 BOOL got_value = False;
586 if ((p = strchr(tok,'=')))
588 *p = 0;
589 value = atoi(p+1);
590 got_value = True;
593 for (i=0;socket_options[i].name;i++)
594 if (strequal(socket_options[i].name,tok))
595 break;
597 if (!socket_options[i].name)
599 DEBUG(0,("Unknown socket option %s\n",tok));
600 continue;
603 switch (socket_options[i].opttype)
605 case OPT_BOOL:
606 case OPT_INT:
607 ret = setsockopt(fd,socket_options[i].level,
608 socket_options[i].option,(char *)&value,sizeof(int));
609 break;
611 case OPT_ON:
612 if (got_value)
613 DEBUG(0,("syntax error - %s does not take a value\n",tok));
616 int on = socket_options[i].value;
617 ret = setsockopt(fd,socket_options[i].level,
618 socket_options[i].option,(char *)&on,sizeof(int));
620 break;
623 if (ret != 0)
624 DEBUG(0,("Failed to set socket option %s\n",tok));
630 /****************************************************************************
631 close the socket communication
632 ****************************************************************************/
633 void close_sockets(void )
635 close(Client);
636 Client = 0;
639 /****************************************************************************
640 determine whether we are in the specified group
641 ****************************************************************************/
642 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
644 int i;
646 if (group == current_gid) return(True);
648 for (i=0;i<ngroups;i++)
649 if (group == groups[i])
650 return(True);
652 return(False);
655 /****************************************************************************
656 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
657 ****************************************************************************/
658 char *StrCpy(char *dest,char *src)
660 char *d = dest;
662 #if AJT
663 /* I don't want to get lazy with these ... */
664 if (!dest || !src) {
665 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
666 ajt_panic();
668 #endif
670 if (!dest) return(NULL);
671 if (!src) {
672 *dest = 0;
673 return(dest);
675 while ((*d++ = *src++)) ;
676 return(dest);
679 /****************************************************************************
680 line strncpy but always null terminates. Make sure there is room!
681 ****************************************************************************/
682 char *StrnCpy(char *dest,char *src,int n)
684 char *d = dest;
685 if (!dest) return(NULL);
686 if (!src) {
687 *dest = 0;
688 return(dest);
690 while (n-- && (*d++ = *src++)) ;
691 *d = 0;
692 return(dest);
696 /*******************************************************************
697 copy an IP address from one buffer to another
698 ********************************************************************/
699 void putip(void *dest,void *src)
701 memcpy(dest,src,4);
705 /****************************************************************************
706 interpret the weird netbios "name". Return the name type
707 ****************************************************************************/
708 static int name_interpret(char *in,char *out)
710 int ret;
711 int len = (*in++) / 2;
713 *out=0;
715 if (len > 30 || len<1) return(0);
717 while (len--)
719 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
720 *out = 0;
721 return(0);
723 *out = ((in[0]-'A')<<4) + (in[1]-'A');
724 in += 2;
725 out++;
727 *out = 0;
728 ret = out[-1];
730 #ifdef NETBIOS_SCOPE
731 /* Handle any scope names */
732 while(*in)
734 *out++ = '.'; /* Scope names are separated by periods */
735 len = *(unsigned char *)in++;
736 StrnCpy(out, in, len);
737 out += len;
738 *out=0;
739 in += len;
741 #endif
742 return(ret);
745 /****************************************************************************
746 mangle a name into netbios format
748 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
749 ****************************************************************************/
750 int name_mangle( char *In, char *Out, char name_type )
752 int i;
753 int c;
754 int len;
755 char buf[20];
756 char *p = Out;
758 /* Safely copy the input string, In, into buf[]. */
759 (void)memset( buf, 0, 20 );
760 if( '*' == In[0] )
761 buf[0] = '*';
762 else
763 (void)sprintf( buf, "%-15.15s%c", In, name_type );
765 /* Place the length of the first field into the output buffer. */
766 p[0] = 32;
767 p++;
769 /* Now convert the name to the rfc1001/1002 format. */
770 for( i = 0; i < 16; i++ )
772 c = toupper( buf[i] );
773 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
774 p[(i*2)+1] = (c & 0x000F) + 'A';
776 p += 32;
777 p[0] = '\0';
779 /* Add the scope string. */
780 for( i = 0, len = 0; NULL != scope; i++, len++ )
782 switch( scope[i] )
784 case '\0':
785 p[0] = len;
786 if( len > 0 )
787 p[len+1] = 0;
788 return( name_len(Out) );
789 case '.':
790 p[0] = len;
791 p += (len + 1);
792 len = 0;
793 break;
794 default:
795 p[len+1] = scope[i];
796 break;
800 return( name_len(Out) );
801 } /* name_mangle */
803 /*******************************************************************
804 check if a file exists
805 ********************************************************************/
806 BOOL file_exist(char *fname,struct stat *sbuf)
808 struct stat st;
809 if (!sbuf) sbuf = &st;
811 if (sys_stat(fname,sbuf) != 0)
812 return(False);
814 return(S_ISREG(sbuf->st_mode));
817 /*******************************************************************
818 check a files mod time
819 ********************************************************************/
820 time_t file_modtime(char *fname)
822 struct stat st;
824 if (sys_stat(fname,&st) != 0)
825 return(0);
827 return(st.st_mtime);
830 /*******************************************************************
831 check if a directory exists
832 ********************************************************************/
833 BOOL directory_exist(char *dname,struct stat *st)
835 struct stat st2;
836 BOOL ret;
838 if (!st) st = &st2;
840 if (sys_stat(dname,st) != 0)
841 return(False);
843 ret = S_ISDIR(st->st_mode);
844 if(!ret)
845 errno = ENOTDIR;
846 return ret;
849 /*******************************************************************
850 returns the size in bytes of the named file
851 ********************************************************************/
852 uint32 file_size(char *file_name)
854 struct stat buf;
855 buf.st_size = 0;
856 sys_stat(file_name,&buf);
857 return(buf.st_size);
860 /*******************************************************************
861 return a string representing an attribute for a file
862 ********************************************************************/
863 char *attrib_string(int mode)
865 static char attrstr[10];
867 attrstr[0] = 0;
869 if (mode & aVOLID) strcat(attrstr,"V");
870 if (mode & aDIR) strcat(attrstr,"D");
871 if (mode & aARCH) strcat(attrstr,"A");
872 if (mode & aHIDDEN) strcat(attrstr,"H");
873 if (mode & aSYSTEM) strcat(attrstr,"S");
874 if (mode & aRONLY) strcat(attrstr,"R");
876 return(attrstr);
880 /*******************************************************************
881 case insensitive string compararison
882 ********************************************************************/
883 int StrCaseCmp(char *s, char *t)
885 /* compare until we run out of string, either t or s, or find a difference */
886 /* We *must* use toupper rather than tolower here due to the
887 asynchronous upper to lower mapping.
889 #if !defined(KANJI_WIN95_COMPATIBILITY)
891 * For completeness we should put in equivalent code for code pages
892 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
893 * doubt anyone wants Samba to behave differently from Win95 and WinNT
894 * here. They both treat full width ascii characters as case senstive
895 * filenames (ie. they don't do the work we do here).
896 * JRA.
899 if(lp_client_code_page() == KANJI_CODEPAGE)
901 /* Win95 treats full width ascii characters as case sensitive. */
902 int diff;
903 for (;;)
905 if (!*s || !*t)
906 return toupper (*s) - toupper (*t);
907 else if (is_sj_alph (*s) && is_sj_alph (*t))
909 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
910 if (diff)
911 return diff;
912 s += 2;
913 t += 2;
915 else if (is_shift_jis (*s) && is_shift_jis (*t))
917 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
918 if (diff)
919 return diff;
920 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
921 if (diff)
922 return diff;
923 s += 2;
924 t += 2;
926 else if (is_shift_jis (*s))
927 return 1;
928 else if (is_shift_jis (*t))
929 return -1;
930 else
932 diff = toupper (*s) - toupper (*t);
933 if (diff)
934 return diff;
935 s++;
936 t++;
940 else
941 #endif /* KANJI_WIN95_COMPATIBILITY */
943 while (*s && *t && toupper(*s) == toupper(*t))
945 s++;
946 t++;
949 return(toupper(*s) - toupper(*t));
953 /*******************************************************************
954 case insensitive string compararison, length limited
955 ********************************************************************/
956 int StrnCaseCmp(char *s, char *t, int n)
958 /* compare until we run out of string, either t or s, or chars */
959 /* We *must* use toupper rather than tolower here due to the
960 asynchronous upper to lower mapping.
962 #if !defined(KANJI_WIN95_COMPATIBILITY)
964 * For completeness we should put in equivalent code for code pages
965 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
966 * doubt anyone wants Samba to behave differently from Win95 and WinNT
967 * here. They both treat full width ascii characters as case senstive
968 * filenames (ie. they don't do the work we do here).
969 * JRA.
972 if(lp_client_code_page() == KANJI_CODEPAGE)
974 /* Win95 treats full width ascii characters as case sensitive. */
975 int diff;
976 for (;n > 0;)
978 if (!*s || !*t)
979 return toupper (*s) - toupper (*t);
980 else if (is_sj_alph (*s) && is_sj_alph (*t))
982 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
983 if (diff)
984 return diff;
985 s += 2;
986 t += 2;
987 n -= 2;
989 else if (is_shift_jis (*s) && is_shift_jis (*t))
991 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
992 if (diff)
993 return diff;
994 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
995 if (diff)
996 return diff;
997 s += 2;
998 t += 2;
999 n -= 2;
1001 else if (is_shift_jis (*s))
1002 return 1;
1003 else if (is_shift_jis (*t))
1004 return -1;
1005 else
1007 diff = toupper (*s) - toupper (*t);
1008 if (diff)
1009 return diff;
1010 s++;
1011 t++;
1012 n--;
1015 return 0;
1017 else
1018 #endif /* KANJI_WIN95_COMPATIBILITY */
1020 while (n && *s && *t && toupper(*s) == toupper(*t))
1022 s++;
1023 t++;
1024 n--;
1027 /* not run out of chars - strings are different lengths */
1028 if (n)
1029 return(toupper(*s) - toupper(*t));
1031 /* identical up to where we run out of chars,
1032 and strings are same length */
1033 return(0);
1037 /*******************************************************************
1038 compare 2 strings
1039 ********************************************************************/
1040 BOOL strequal(char *s1, char *s2)
1042 if (s1 == s2) return(True);
1043 if (!s1 || !s2) return(False);
1045 return(StrCaseCmp(s1,s2)==0);
1048 /*******************************************************************
1049 compare 2 strings up to and including the nth char.
1050 ******************************************************************/
1051 BOOL strnequal(char *s1,char *s2,int n)
1053 if (s1 == s2) return(True);
1054 if (!s1 || !s2 || !n) return(False);
1056 return(StrnCaseCmp(s1,s2,n)==0);
1059 /*******************************************************************
1060 compare 2 strings (case sensitive)
1061 ********************************************************************/
1062 BOOL strcsequal(char *s1,char *s2)
1064 if (s1 == s2) return(True);
1065 if (!s1 || !s2) return(False);
1067 return(strcmp(s1,s2)==0);
1071 /*******************************************************************
1072 convert a string to lower case
1073 ********************************************************************/
1074 void strlower(char *s)
1076 while (*s)
1078 #if !defined(KANJI_WIN95_COMPATIBILITY)
1080 * For completeness we should put in equivalent code for code pages
1081 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1082 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1083 * here. They both treat full width ascii characters as case senstive
1084 * filenames (ie. they don't do the work we do here).
1085 * JRA.
1088 if(lp_client_code_page() == KANJI_CODEPAGE)
1090 /* Win95 treats full width ascii characters as case sensitive. */
1091 if (is_shift_jis (*s))
1093 if (is_sj_upper (s[0], s[1]))
1094 s[1] = sj_tolower2 (s[1]);
1095 s += 2;
1097 else if (is_kana (*s))
1099 s++;
1101 else
1103 if (isupper(*s))
1104 *s = tolower(*s);
1105 s++;
1108 else
1109 #endif /* KANJI_WIN95_COMPATIBILITY */
1111 if (isupper(*s))
1112 *s = tolower(*s);
1113 s++;
1118 /*******************************************************************
1119 convert a string to upper case
1120 ********************************************************************/
1121 void strupper(char *s)
1123 while (*s)
1125 #if !defined(KANJI_WIN95_COMPATIBILITY)
1127 * For completeness we should put in equivalent code for code pages
1128 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1129 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1130 * here. They both treat full width ascii characters as case senstive
1131 * filenames (ie. they don't do the work we do here).
1132 * JRA.
1135 if(lp_client_code_page() == KANJI_CODEPAGE)
1137 /* Win95 treats full width ascii characters as case sensitive. */
1138 if (is_shift_jis (*s))
1140 if (is_sj_lower (s[0], s[1]))
1141 s[1] = sj_toupper2 (s[1]);
1142 s += 2;
1144 else if (is_kana (*s))
1146 s++;
1148 else
1150 if (islower(*s))
1151 *s = toupper(*s);
1152 s++;
1155 else
1156 #endif /* KANJI_WIN95_COMPATIBILITY */
1158 if (islower(*s))
1159 *s = toupper(*s);
1160 s++;
1165 /*******************************************************************
1166 convert a string to "normal" form
1167 ********************************************************************/
1168 void strnorm(char *s)
1170 if (case_default == CASE_UPPER)
1171 strupper(s);
1172 else
1173 strlower(s);
1176 /*******************************************************************
1177 check if a string is in "normal" case
1178 ********************************************************************/
1179 BOOL strisnormal(char *s)
1181 if (case_default == CASE_UPPER)
1182 return(!strhaslower(s));
1184 return(!strhasupper(s));
1188 /****************************************************************************
1189 string replace
1190 ****************************************************************************/
1191 void string_replace(char *s,char oldc,char newc)
1193 while (*s)
1195 #if !defined(KANJI_WIN95_COMPATIBILITY)
1197 * For completeness we should put in equivalent code for code pages
1198 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1199 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1200 * here. They both treat full width ascii characters as case senstive
1201 * filenames (ie. they don't do the work we do here).
1202 * JRA.
1205 if(lp_client_code_page() == KANJI_CODEPAGE)
1207 /* Win95 treats full width ascii characters as case sensitive. */
1208 if (is_shift_jis (*s))
1209 s += 2;
1210 else if (is_kana (*s))
1211 s++;
1212 else
1214 if (oldc == *s)
1215 *s = newc;
1216 s++;
1219 else
1220 #endif /* KANJI_WIN95_COMPATIBILITY */
1222 if (oldc == *s)
1223 *s = newc;
1224 s++;
1229 /****************************************************************************
1230 make a file into unix format
1231 ****************************************************************************/
1232 void unix_format(char *fname)
1234 pstring namecopy;
1235 string_replace(fname,'\\','/');
1237 if (*fname == '/')
1239 pstrcpy(namecopy,fname);
1240 strcpy(fname,".");
1241 strcat(fname,namecopy);
1245 /****************************************************************************
1246 make a file into dos format
1247 ****************************************************************************/
1248 void dos_format(char *fname)
1250 string_replace(fname,'/','\\');
1254 /*******************************************************************
1255 show a smb message structure
1256 ********************************************************************/
1257 void show_msg(char *buf)
1259 int i;
1260 int bcc=0;
1262 if (DEBUGLEVEL < 5) return;
1264 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1265 smb_len(buf),
1266 (int)CVAL(buf,smb_com),
1267 (int)CVAL(buf,smb_rcls),
1268 (int)CVAL(buf,smb_reh),
1269 (int)SVAL(buf,smb_err),
1270 (int)CVAL(buf,smb_flg),
1271 (int)SVAL(buf,smb_flg2)));
1272 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1273 (int)SVAL(buf,smb_tid),
1274 (int)SVAL(buf,smb_pid),
1275 (int)SVAL(buf,smb_uid),
1276 (int)SVAL(buf,smb_mid),
1277 (int)CVAL(buf,smb_wct)));
1279 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1280 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1281 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1283 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1284 DEBUG(5,("smb_bcc=%d\n",bcc));
1286 if (DEBUGLEVEL < 10) return;
1288 dump_data(10, smb_buf(buf), MIN(bcc, 512));
1291 /*******************************************************************
1292 return the length of an smb packet
1293 ********************************************************************/
1294 int smb_len(char *buf)
1296 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1299 /*******************************************************************
1300 set the length of an smb packet
1301 ********************************************************************/
1302 void _smb_setlen(char *buf,int len)
1304 buf[0] = 0;
1305 buf[1] = (len&0x10000)>>16;
1306 buf[2] = (len&0xFF00)>>8;
1307 buf[3] = len&0xFF;
1310 /*******************************************************************
1311 set the length and marker of an smb packet
1312 ********************************************************************/
1313 void smb_setlen(char *buf,int len)
1315 _smb_setlen(buf,len);
1317 CVAL(buf,4) = 0xFF;
1318 CVAL(buf,5) = 'S';
1319 CVAL(buf,6) = 'M';
1320 CVAL(buf,7) = 'B';
1323 /*******************************************************************
1324 setup the word count and byte count for a smb message
1325 ********************************************************************/
1326 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1328 if (zero)
1329 bzero(buf + smb_size,num_words*2 + num_bytes);
1330 CVAL(buf,smb_wct) = num_words;
1331 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1332 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1333 return (smb_size + num_words*2 + num_bytes);
1336 /*******************************************************************
1337 return the number of smb words
1338 ********************************************************************/
1339 int smb_numwords(char *buf)
1341 return (CVAL(buf,smb_wct));
1344 /*******************************************************************
1345 return the size of the smb_buf region of a message
1346 ********************************************************************/
1347 int smb_buflen(char *buf)
1349 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1352 /*******************************************************************
1353 return a pointer to the smb_buf data area
1354 ********************************************************************/
1355 int smb_buf_ofs(char *buf)
1357 return (smb_size + CVAL(buf,smb_wct)*2);
1360 /*******************************************************************
1361 return a pointer to the smb_buf data area
1362 ********************************************************************/
1363 char *smb_buf(char *buf)
1365 return (buf + smb_buf_ofs(buf));
1368 /*******************************************************************
1369 return the SMB offset into an SMB buffer
1370 ********************************************************************/
1371 int smb_offset(char *p,char *buf)
1373 return(PTR_DIFF(p,buf+4) + chain_size);
1377 /*******************************************************************
1378 skip past some strings in a buffer
1379 ********************************************************************/
1380 char *skip_string(char *buf,int n)
1382 while (n--)
1383 buf += strlen(buf) + 1;
1384 return(buf);
1387 /*******************************************************************
1388 trim the specified elements off the front and back of a string
1389 ********************************************************************/
1390 BOOL trim_string(char *s,char *front,char *back)
1392 BOOL ret = False;
1393 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1395 char *p = s;
1396 ret = True;
1397 while (1)
1399 if (!(*p = p[strlen(front)]))
1400 break;
1401 p++;
1404 while (back && *back && strlen(s) >= strlen(back) &&
1405 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1407 ret = True;
1408 s[strlen(s)-strlen(back)] = 0;
1410 return(ret);
1414 /*******************************************************************
1415 reduce a file name, removing .. elements.
1416 ********************************************************************/
1417 void dos_clean_name(char *s)
1419 char *p=NULL;
1421 DEBUG(3,("dos_clean_name [%s]\n",s));
1423 /* remove any double slashes */
1424 string_sub(s, "\\\\", "\\");
1426 while ((p = strstr(s,"\\..\\")) != NULL)
1428 pstring s1;
1430 *p = 0;
1431 pstrcpy(s1,p+3);
1433 if ((p=strrchr(s,'\\')) != NULL)
1434 *p = 0;
1435 else
1436 *s = 0;
1437 strcat(s,s1);
1440 trim_string(s,NULL,"\\..");
1442 string_sub(s, "\\.\\", "\\");
1445 /*******************************************************************
1446 reduce a file name, removing .. elements.
1447 ********************************************************************/
1448 void unix_clean_name(char *s)
1450 char *p=NULL;
1452 DEBUG(3,("unix_clean_name [%s]\n",s));
1454 /* remove any double slashes */
1455 string_sub(s, "//","/");
1457 /* Remove leading ./ characters */
1458 if(strncmp(s, "./", 2) == 0) {
1459 trim_string(s, "./", NULL);
1460 if(*s == 0)
1461 strcpy(s,"./");
1464 while ((p = strstr(s,"/../")) != NULL)
1466 pstring s1;
1468 *p = 0;
1469 pstrcpy(s1,p+3);
1471 if ((p=strrchr(s,'/')) != NULL)
1472 *p = 0;
1473 else
1474 *s = 0;
1475 strcat(s,s1);
1478 trim_string(s,NULL,"/..");
1482 /*******************************************************************
1483 a wrapper for the normal chdir() function
1484 ********************************************************************/
1485 int ChDir(char *path)
1487 int res;
1488 static pstring LastDir="";
1490 if (strcsequal(path,".")) return(0);
1492 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1493 DEBUG(3,("chdir to %s\n",path));
1494 res = sys_chdir(path);
1495 if (!res)
1496 pstrcpy(LastDir,path);
1497 return(res);
1500 /* number of list structures for a caching GetWd function. */
1501 #define MAX_GETWDCACHE (50)
1503 struct
1505 ino_t inode;
1506 dev_t dev;
1507 char *text;
1508 BOOL valid;
1509 } ino_list[MAX_GETWDCACHE];
1511 BOOL use_getwd_cache=True;
1513 /*******************************************************************
1514 return the absolute current directory path
1515 ********************************************************************/
1516 char *GetWd(char *str)
1518 pstring s;
1519 static BOOL getwd_cache_init = False;
1520 struct stat st, st2;
1521 int i;
1523 *s = 0;
1525 if (!use_getwd_cache)
1526 return(sys_getwd(str));
1528 /* init the cache */
1529 if (!getwd_cache_init)
1531 getwd_cache_init = True;
1532 for (i=0;i<MAX_GETWDCACHE;i++)
1534 string_init(&ino_list[i].text,"");
1535 ino_list[i].valid = False;
1539 /* Get the inode of the current directory, if this doesn't work we're
1540 in trouble :-) */
1542 if (stat(".",&st) == -1)
1544 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1545 return(sys_getwd(str));
1549 for (i=0; i<MAX_GETWDCACHE; i++)
1550 if (ino_list[i].valid)
1553 /* If we have found an entry with a matching inode and dev number
1554 then find the inode number for the directory in the cached string.
1555 If this agrees with that returned by the stat for the current
1556 directory then all is o.k. (but make sure it is a directory all
1557 the same...) */
1559 if (st.st_ino == ino_list[i].inode &&
1560 st.st_dev == ino_list[i].dev)
1562 if (stat(ino_list[i].text,&st2) == 0)
1564 if (st.st_ino == st2.st_ino &&
1565 st.st_dev == st2.st_dev &&
1566 (st2.st_mode & S_IFMT) == S_IFDIR)
1568 strcpy (str, ino_list[i].text);
1570 /* promote it for future use */
1571 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1572 return (str);
1574 else
1576 /* If the inode is different then something's changed,
1577 scrub the entry and start from scratch. */
1578 ino_list[i].valid = False;
1585 /* We don't have the information to hand so rely on traditional methods.
1586 The very slow getcwd, which spawns a process on some systems, or the
1587 not quite so bad getwd. */
1589 if (!sys_getwd(s))
1591 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1592 return (NULL);
1595 strcpy(str,s);
1597 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1599 /* add it to the cache */
1600 i = MAX_GETWDCACHE - 1;
1601 string_set(&ino_list[i].text,s);
1602 ino_list[i].dev = st.st_dev;
1603 ino_list[i].inode = st.st_ino;
1604 ino_list[i].valid = True;
1606 /* put it at the top of the list */
1607 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1609 return (str);
1614 /*******************************************************************
1615 reduce a file name, removing .. elements and checking that
1616 it is below dir in the heirachy. This uses GetWd() and so must be run
1617 on the system that has the referenced file system.
1619 widelinks are allowed if widelinks is true
1620 ********************************************************************/
1621 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1623 #ifndef REDUCE_PATHS
1624 return True;
1625 #else
1626 pstring dir2;
1627 pstring wd;
1628 pstring base_name;
1629 pstring newname;
1630 char *p=NULL;
1631 BOOL relative = (*s != '/');
1633 *dir2 = *wd = *base_name = *newname = 0;
1635 if (widelinks)
1637 unix_clean_name(s);
1638 /* can't have a leading .. */
1639 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1641 DEBUG(3,("Illegal file name? (%s)\n",s));
1642 return(False);
1645 if (strlen(s) == 0)
1646 strcpy(s,"./");
1648 return(True);
1651 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1653 /* remove any double slashes */
1654 string_sub(s,"//","/");
1656 pstrcpy(base_name,s);
1657 p = strrchr(base_name,'/');
1659 if (!p)
1660 return(True);
1662 if (!GetWd(wd))
1664 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1665 return(False);
1668 if (ChDir(dir) != 0)
1670 DEBUG(0,("couldn't chdir to %s\n",dir));
1671 return(False);
1674 if (!GetWd(dir2))
1676 DEBUG(0,("couldn't getwd for %s\n",dir));
1677 ChDir(wd);
1678 return(False);
1682 if (p && (p != base_name))
1684 *p = 0;
1685 if (strcmp(p+1,".")==0)
1686 p[1]=0;
1687 if (strcmp(p+1,"..")==0)
1688 *p = '/';
1691 if (ChDir(base_name) != 0)
1693 ChDir(wd);
1694 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1695 return(False);
1698 if (!GetWd(newname))
1700 ChDir(wd);
1701 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1702 return(False);
1705 if (p && (p != base_name))
1707 strcat(newname,"/");
1708 strcat(newname,p+1);
1712 int l = strlen(dir2);
1713 if (dir2[l-1] == '/')
1714 l--;
1716 if (strncmp(newname,dir2,l) != 0)
1718 ChDir(wd);
1719 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1720 return(False);
1723 if (relative)
1725 if (newname[l] == '/')
1726 pstrcpy(s,newname + l + 1);
1727 else
1728 pstrcpy(s,newname+l);
1730 else
1731 pstrcpy(s,newname);
1734 ChDir(wd);
1736 if (strlen(s) == 0)
1737 strcpy(s,"./");
1739 DEBUG(3,("reduced to %s\n",s));
1740 return(True);
1741 #endif
1744 /****************************************************************************
1745 expand some *s
1746 ****************************************************************************/
1747 static void expand_one(char *Mask,int len)
1749 char *p1;
1750 while ((p1 = strchr(Mask,'*')) != NULL)
1752 int lfill = (len+1) - strlen(Mask);
1753 int l1= (p1 - Mask);
1754 pstring tmp;
1755 pstrcpy(tmp,Mask);
1756 memset(tmp+l1,'?',lfill);
1757 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1758 pstrcpy(Mask,tmp);
1762 /****************************************************************************
1763 expand a wildcard expression, replacing *s with ?s
1764 ****************************************************************************/
1765 void expand_mask(char *Mask,BOOL doext)
1767 pstring mbeg,mext;
1768 pstring dirpart;
1769 pstring filepart;
1770 BOOL hasdot = False;
1771 char *p1;
1772 BOOL absolute = (*Mask == '\\');
1774 *mbeg = *mext = *dirpart = *filepart = 0;
1776 /* parse the directory and filename */
1777 if (strchr(Mask,'\\'))
1778 dirname_dos(Mask,dirpart);
1780 filename_dos(Mask,filepart);
1782 pstrcpy(mbeg,filepart);
1783 if ((p1 = strchr(mbeg,'.')) != NULL)
1785 hasdot = True;
1786 *p1 = 0;
1787 p1++;
1788 pstrcpy(mext,p1);
1790 else
1792 strcpy(mext,"");
1793 if (strlen(mbeg) > 8)
1795 pstrcpy(mext,mbeg + 8);
1796 mbeg[8] = 0;
1800 if (*mbeg == 0)
1801 strcpy(mbeg,"????????");
1802 if ((*mext == 0) && doext && !hasdot)
1803 strcpy(mext,"???");
1805 if (strequal(mbeg,"*") && *mext==0)
1806 strcpy(mext,"*");
1808 /* expand *'s */
1809 expand_one(mbeg,8);
1810 if (*mext)
1811 expand_one(mext,3);
1813 pstrcpy(Mask,dirpart);
1814 if (*dirpart || absolute) strcat(Mask,"\\");
1815 strcat(Mask,mbeg);
1816 strcat(Mask,".");
1817 strcat(Mask,mext);
1819 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1823 /****************************************************************************
1824 does a string have any uppercase chars in it?
1825 ****************************************************************************/
1826 BOOL strhasupper(char *s)
1828 while (*s)
1830 #if !defined(KANJI_WIN95_COMPATIBILITY)
1832 * For completeness we should put in equivalent code for code pages
1833 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1834 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1835 * here. They both treat full width ascii characters as case senstive
1836 * filenames (ie. they don't do the work we do here).
1837 * JRA.
1840 if(lp_client_code_page() == KANJI_CODEPAGE)
1842 /* Win95 treats full width ascii characters as case sensitive. */
1843 if (is_shift_jis (*s))
1844 s += 2;
1845 else if (is_kana (*s))
1846 s++;
1847 else
1849 if (isupper(*s))
1850 return(True);
1851 s++;
1854 else
1855 #endif /* KANJI_WIN95_COMPATIBILITY */
1857 if (isupper(*s))
1858 return(True);
1859 s++;
1862 return(False);
1865 /****************************************************************************
1866 does a string have any lowercase chars in it?
1867 ****************************************************************************/
1868 BOOL strhaslower(char *s)
1870 while (*s)
1872 #if !defined(KANJI_WIN95_COMPATIBILITY)
1874 * For completeness we should put in equivalent code for code pages
1875 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1876 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1877 * here. They both treat full width ascii characters as case senstive
1878 * filenames (ie. they don't do the work we do here).
1879 * JRA.
1882 if(lp_client_code_page() == KANJI_CODEPAGE)
1884 /* Win95 treats full width ascii characters as case sensitive. */
1885 if (is_shift_jis (*s))
1887 if (is_sj_upper (s[0], s[1]))
1888 return(True);
1889 if (is_sj_lower (s[0], s[1]))
1890 return (True);
1891 s += 2;
1893 else if (is_kana (*s))
1895 s++;
1897 else
1899 if (islower(*s))
1900 return(True);
1901 s++;
1904 else
1905 #endif /* KANJI_WIN95_COMPATIBILITY */
1907 if (islower(*s))
1908 return(True);
1909 s++;
1912 return(False);
1915 /****************************************************************************
1916 find the number of chars in a string
1917 ****************************************************************************/
1918 int count_chars(char *s,char c)
1920 int count=0;
1922 #if !defined(KANJI_WIN95_COMPATIBILITY)
1924 * For completeness we should put in equivalent code for code pages
1925 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1926 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1927 * here. They both treat full width ascii characters as case senstive
1928 * filenames (ie. they don't do the work we do here).
1929 * JRA.
1932 if(lp_client_code_page() == KANJI_CODEPAGE)
1934 /* Win95 treats full width ascii characters as case sensitive. */
1935 while (*s)
1937 if (is_shift_jis (*s))
1938 s += 2;
1939 else
1941 if (*s == c)
1942 count++;
1943 s++;
1947 else
1948 #endif /* KANJI_WIN95_COMPATIBILITY */
1950 while (*s)
1952 if (*s == c)
1953 count++;
1954 s++;
1957 return(count);
1961 /****************************************************************************
1962 make a dir struct
1963 ****************************************************************************/
1964 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1966 char *p;
1967 pstring mask2;
1969 pstrcpy(mask2,mask);
1971 if ((mode & aDIR) != 0)
1972 size = 0;
1974 memset(buf+1,' ',11);
1975 if ((p = strchr(mask2,'.')) != NULL)
1977 *p = 0;
1978 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1979 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1980 *p = '.';
1982 else
1983 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1985 bzero(buf+21,DIR_STRUCT_SIZE-21);
1986 CVAL(buf,21) = mode;
1987 put_dos_date(buf,22,date);
1988 SSVAL(buf,26,size & 0xFFFF);
1989 SSVAL(buf,28,size >> 16);
1990 StrnCpy(buf+30,fname,12);
1991 if (!case_sensitive)
1992 strupper(buf+30);
1993 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1997 /*******************************************************************
1998 close the low 3 fd's and open dev/null in their place
1999 ********************************************************************/
2000 void close_low_fds(void)
2002 int fd;
2003 int i;
2004 close(0); close(1); close(2);
2005 /* try and use up these file descriptors, so silly
2006 library routines writing to stdout etc won't cause havoc */
2007 for (i=0;i<3;i++) {
2008 fd = open("/dev/null",O_RDWR,0);
2009 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2010 if (fd < 0) {
2011 DEBUG(0,("Can't open /dev/null\n"));
2012 return;
2014 if (fd != i) {
2015 DEBUG(0,("Didn't get file descriptor %d\n",i));
2016 return;
2021 /****************************************************************************
2022 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2023 else
2024 if SYSV use O_NDELAY
2025 if BSD use FNDELAY
2026 ****************************************************************************/
2027 int set_blocking(int fd, BOOL set)
2029 int val;
2030 #ifdef O_NONBLOCK
2031 #define FLAG_TO_SET O_NONBLOCK
2032 #else
2033 #ifdef SYSV
2034 #define FLAG_TO_SET O_NDELAY
2035 #else /* BSD */
2036 #define FLAG_TO_SET FNDELAY
2037 #endif
2038 #endif
2040 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2041 return -1;
2042 if(set) /* Turn blocking on - ie. clear nonblock flag */
2043 val &= ~FLAG_TO_SET;
2044 else
2045 val |= FLAG_TO_SET;
2046 return fcntl( fd, F_SETFL, val);
2047 #undef FLAG_TO_SET
2051 /****************************************************************************
2052 write to a socket
2053 ****************************************************************************/
2054 int write_socket(int fd,char *buf,int len)
2056 int ret=0;
2058 if (passive)
2059 return(len);
2060 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2061 ret = write_data(fd,buf,len);
2063 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2064 if(ret <= 0)
2065 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2066 len, fd, strerror(errno) ));
2068 return(ret);
2071 /****************************************************************************
2072 read from a socket
2073 ****************************************************************************/
2074 int read_udp_socket(int fd,char *buf,int len)
2076 int ret;
2077 struct sockaddr_in sock;
2078 int socklen;
2080 socklen = sizeof(sock);
2081 bzero((char *)&sock,socklen);
2082 bzero((char *)&lastip,sizeof(lastip));
2083 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2084 if (ret <= 0) {
2085 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2086 return(0);
2089 lastip = sock.sin_addr;
2090 lastport = ntohs(sock.sin_port);
2092 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2093 inet_ntoa(lastip), lastport, ret));
2095 return(ret);
2098 /****************************************************************************
2099 read data from a device with a timout in msec.
2100 mincount = if timeout, minimum to read before returning
2101 maxcount = number to be read.
2102 ****************************************************************************/
2103 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2105 fd_set fds;
2106 int selrtn;
2107 int readret;
2108 int nread = 0;
2109 struct timeval timeout;
2111 /* just checking .... */
2112 if (maxcnt <= 0) return(0);
2114 smb_read_error = 0;
2116 /* Blocking read */
2117 if (time_out <= 0) {
2118 if (mincnt == 0) mincnt = maxcnt;
2120 while (nread < mincnt) {
2121 readret = read(fd, buf + nread, maxcnt - nread);
2122 if (readret == 0) {
2123 smb_read_error = READ_EOF;
2124 return -1;
2127 if (readret == -1) {
2128 smb_read_error = READ_ERROR;
2129 return -1;
2131 nread += readret;
2133 return(nread);
2136 /* Most difficult - timeout read */
2137 /* If this is ever called on a disk file and
2138 mincnt is greater then the filesize then
2139 system performance will suffer severely as
2140 select always return true on disk files */
2142 /* Set initial timeout */
2143 timeout.tv_sec = time_out / 1000;
2144 timeout.tv_usec = 1000 * (time_out % 1000);
2146 for (nread=0; nread<mincnt; )
2148 FD_ZERO(&fds);
2149 FD_SET(fd,&fds);
2151 selrtn = sys_select(&fds,&timeout);
2153 /* Check if error */
2154 if(selrtn == -1) {
2155 /* something is wrong. Maybe the socket is dead? */
2156 smb_read_error = READ_ERROR;
2157 return -1;
2160 /* Did we timeout ? */
2161 if (selrtn == 0) {
2162 smb_read_error = READ_TIMEOUT;
2163 return -1;
2166 readret = read(fd, buf+nread, maxcnt-nread);
2167 if (readret == 0) {
2168 /* we got EOF on the file descriptor */
2169 smb_read_error = READ_EOF;
2170 return -1;
2173 if (readret == -1) {
2174 /* the descriptor is probably dead */
2175 smb_read_error = READ_ERROR;
2176 return -1;
2179 nread += readret;
2182 /* Return the number we got */
2183 return(nread);
2186 /****************************************************************************
2187 read data from the client. Maxtime is in milliseconds
2188 ****************************************************************************/
2189 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2191 fd_set fds;
2192 int selrtn;
2193 int nread;
2194 struct timeval timeout;
2196 FD_ZERO(&fds);
2197 FD_SET(fd,&fds);
2199 timeout.tv_sec = maxtime / 1000;
2200 timeout.tv_usec = (maxtime % 1000) * 1000;
2202 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2204 if (!FD_ISSET(fd,&fds))
2205 return 0;
2207 nread = read_udp_socket(fd, buffer, bufsize);
2209 /* return the number got */
2210 return(nread);
2213 /*******************************************************************
2214 find the difference in milliseconds between two struct timeval
2215 values
2216 ********************************************************************/
2217 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2219 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2220 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2223 /****************************************************************************
2224 send a keepalive packet (rfc1002)
2225 ****************************************************************************/
2226 BOOL send_keepalive(int client)
2228 unsigned char buf[4];
2230 buf[0] = 0x85;
2231 buf[1] = buf[2] = buf[3] = 0;
2233 return(write_data(client,(char *)buf,4) == 4);
2238 /****************************************************************************
2239 read data from the client, reading exactly N bytes.
2240 ****************************************************************************/
2241 int read_data(int fd,char *buffer,int N)
2243 int ret;
2244 int total=0;
2246 smb_read_error = 0;
2248 while (total < N)
2250 ret = read(fd,buffer + total,N - total);
2251 if (ret == 0) {
2252 smb_read_error = READ_EOF;
2253 return 0;
2255 if (ret == -1) {
2256 smb_read_error = READ_ERROR;
2257 return -1;
2259 total += ret;
2261 return total;
2265 /****************************************************************************
2266 write data to a fd
2267 ****************************************************************************/
2268 int write_data(int fd,char *buffer,int N)
2270 int total=0;
2271 int ret;
2273 while (total < N)
2275 ret = write(fd,buffer + total,N - total);
2277 if (ret == -1) return -1;
2278 if (ret == 0) return total;
2280 total += ret;
2282 return total;
2286 /****************************************************************************
2287 transfer some data between two fd's
2288 ****************************************************************************/
2289 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2291 static char *buf=NULL;
2292 static int size=0;
2293 char *buf1,*abuf;
2294 int total = 0;
2296 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2298 if (size == 0) {
2299 size = lp_readsize();
2300 size = MAX(size,1024);
2303 while (!buf && size>0) {
2304 buf = (char *)Realloc(buf,size+8);
2305 if (!buf) size /= 2;
2308 if (!buf) {
2309 DEBUG(0,("Can't allocate transfer buffer!\n"));
2310 exit(1);
2313 abuf = buf + (align%8);
2315 if (header)
2316 n += headlen;
2318 while (n > 0)
2320 int s = MIN(n,size);
2321 int ret,ret2=0;
2323 ret = 0;
2325 if (header && (headlen >= MIN(s,1024))) {
2326 buf1 = header;
2327 s = headlen;
2328 ret = headlen;
2329 headlen = 0;
2330 header = NULL;
2331 } else {
2332 buf1 = abuf;
2335 if (header && headlen > 0)
2337 ret = MIN(headlen,size);
2338 memcpy(buf1,header,ret);
2339 headlen -= ret;
2340 header += ret;
2341 if (headlen <= 0) header = NULL;
2344 if (s > ret)
2345 ret += read(infd,buf1+ret,s-ret);
2347 if (ret > 0)
2349 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2350 if (ret2 > 0) total += ret2;
2351 /* if we can't write then dump excess data */
2352 if (ret2 != ret)
2353 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2355 if (ret <= 0 || ret2 != ret)
2356 return(total);
2357 n -= ret;
2359 return(total);
2363 /****************************************************************************
2364 read 4 bytes of a smb packet and return the smb length of the packet
2365 store the result in the buffer
2366 This version of the function will return a length of zero on receiving
2367 a keepalive packet.
2368 ****************************************************************************/
2369 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2371 int len=0, msg_type;
2372 BOOL ok=False;
2374 while (!ok)
2376 if (timeout > 0)
2377 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2378 else
2379 ok = (read_data(fd,inbuf,4) == 4);
2381 if (!ok)
2382 return(-1);
2384 len = smb_len(inbuf);
2385 msg_type = CVAL(inbuf,0);
2387 if (msg_type == 0x85)
2388 DEBUG(5,("Got keepalive packet\n"));
2391 DEBUG(10,("got smb length of %d\n",len));
2393 return(len);
2396 /****************************************************************************
2397 read 4 bytes of a smb packet and return the smb length of the packet
2398 store the result in the buffer. This version of the function will
2399 never return a session keepalive (length of zero).
2400 ****************************************************************************/
2401 int read_smb_length(int fd,char *inbuf,int timeout)
2403 int len;
2405 for(;;)
2407 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2409 if(len < 0)
2410 return len;
2412 /* Ignore session keepalives. */
2413 if(CVAL(inbuf,0) != 0x85)
2414 break;
2417 return len;
2420 /****************************************************************************
2421 read an smb from a fd. Note that the buffer *MUST* be of size
2422 BUFFER_SIZE+SAFETY_MARGIN.
2423 The timeout is in milli seconds.
2425 This function will return on a
2426 receipt of a session keepalive packet.
2427 ****************************************************************************/
2428 BOOL receive_smb(int fd,char *buffer, int timeout)
2430 int len,ret;
2432 smb_read_error = 0;
2434 bzero(buffer,smb_size + 100);
2436 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2437 if (len < 0)
2438 return(False);
2440 if (len > BUFFER_SIZE) {
2441 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2442 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2443 exit(1);
2446 if(len > 0) {
2447 ret = read_data(fd,buffer+4,len);
2448 if (ret != len) {
2449 smb_read_error = READ_ERROR;
2450 return False;
2453 return(True);
2456 /****************************************************************************
2457 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2458 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2459 The timeout is in milli seconds
2461 This is exactly the same as receive_smb except that it never returns
2462 a session keepalive packet (just as receive_smb used to do).
2463 receive_smb was changed to return keepalives as the oplock processing means this call
2464 should never go into a blocking read.
2465 ****************************************************************************/
2467 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2469 BOOL ret;
2471 for(;;)
2473 ret = receive_smb(fd, buffer, timeout);
2475 if(ret == False)
2476 return ret;
2478 /* Ignore session keepalive packets. */
2479 if(CVAL(buffer,0) != 0x85)
2480 break;
2482 return ret;
2485 /****************************************************************************
2486 read a message from a udp fd.
2487 The timeout is in milli seconds
2488 ****************************************************************************/
2489 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2491 struct sockaddr_in from;
2492 int fromlen = sizeof(from);
2493 int32 msg_len = 0;
2495 smb_read_error = 0;
2497 if(timeout != 0)
2499 struct timeval to;
2500 fd_set fds;
2501 int selrtn;
2503 FD_ZERO(&fds);
2504 FD_SET(fd,&fds);
2506 to.tv_sec = timeout / 1000;
2507 to.tv_usec = (timeout % 1000) * 1000;
2509 selrtn = sys_select(&fds,&to);
2511 /* Check if error */
2512 if(selrtn == -1)
2514 /* something is wrong. Maybe the socket is dead? */
2515 smb_read_error = READ_ERROR;
2516 return False;
2519 /* Did we timeout ? */
2520 if (selrtn == 0)
2522 smb_read_error = READ_TIMEOUT;
2523 return False;
2528 * Read a loopback udp message.
2530 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2531 buffer_len - UDP_CMD_HEADER_LEN, 0,
2532 (struct sockaddr *)&from, &fromlen);
2534 if(msg_len < 0)
2536 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2537 return False;
2540 /* Validate message length. */
2541 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2543 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2544 msg_len,
2545 buffer_len - UDP_CMD_HEADER_LEN));
2546 return False;
2549 /* Validate message from address (must be localhost). */
2550 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2552 DEBUG(0,("receive_local_message: invalid 'from' address \
2553 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2554 return False;
2557 /* Setup the message header */
2558 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2559 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2561 return True;
2564 /****************************************************************************
2565 structure to hold a linked list of local messages.
2566 for processing.
2567 ****************************************************************************/
2569 typedef struct _message_list {
2570 struct _message_list *msg_next;
2571 char *msg_buf;
2572 int msg_len;
2573 } pending_message_list;
2575 static pending_message_list *smb_msg_head = NULL;
2577 /****************************************************************************
2578 Function to push a linked list of local messages ready
2579 for processing.
2580 ****************************************************************************/
2582 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2584 pending_message_list *msg = (pending_message_list *)
2585 malloc(sizeof(pending_message_list));
2587 if(msg == NULL)
2589 DEBUG(0,("push_message: malloc fail (1)\n"));
2590 return False;
2593 msg->msg_buf = (char *)malloc(msg_len);
2594 if(msg->msg_buf == NULL)
2596 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2597 free((char *)msg);
2598 return False;
2601 memcpy(msg->msg_buf, buf, msg_len);
2602 msg->msg_len = msg_len;
2604 msg->msg_next = *pml;
2605 *pml = msg;
2607 return True;
2610 /****************************************************************************
2611 Function to push a linked list of local smb messages ready
2612 for processing.
2613 ****************************************************************************/
2615 BOOL push_smb_message(char *buf, int msg_len)
2617 return push_local_message(&smb_msg_head, buf, msg_len);
2620 /****************************************************************************
2621 Do a select on an two fd's - with timeout.
2623 If a local udp message has been pushed onto the
2624 queue (this can only happen during oplock break
2625 processing) return this first.
2627 If a pending smb message has been pushed onto the
2628 queue (this can only happen during oplock break
2629 processing) return this next.
2631 If the first smbfd is ready then read an smb from it.
2632 if the second (loopback UDP) fd is ready then read a message
2633 from it and setup the buffer header to identify the length
2634 and from address.
2635 Returns False on timeout or error.
2636 Else returns True.
2638 The timeout is in milli seconds
2639 ****************************************************************************/
2640 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2641 char *buffer, int buffer_len,
2642 int timeout, BOOL *got_smb)
2644 fd_set fds;
2645 int selrtn;
2646 struct timeval to;
2648 smb_read_error = 0;
2650 *got_smb = False;
2653 * Check to see if we already have a message on the smb queue.
2654 * If so - copy and return it.
2657 if(smb_msg_head)
2659 pending_message_list *msg = smb_msg_head;
2660 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2661 smb_msg_head = msg->msg_next;
2663 /* Free the message we just copied. */
2664 free((char *)msg->msg_buf);
2665 free((char *)msg);
2666 *got_smb = True;
2668 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2669 return True;
2672 FD_ZERO(&fds);
2673 FD_SET(smbfd,&fds);
2674 FD_SET(oplock_fd,&fds);
2676 to.tv_sec = timeout / 1000;
2677 to.tv_usec = (timeout % 1000) * 1000;
2679 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2681 /* Check if error */
2682 if(selrtn == -1) {
2683 /* something is wrong. Maybe the socket is dead? */
2684 smb_read_error = READ_ERROR;
2685 return False;
2688 /* Did we timeout ? */
2689 if (selrtn == 0) {
2690 smb_read_error = READ_TIMEOUT;
2691 return False;
2694 if (FD_ISSET(smbfd,&fds))
2696 *got_smb = True;
2697 return receive_smb(smbfd, buffer, 0);
2699 else
2701 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2705 /****************************************************************************
2706 send an smb to a fd
2707 ****************************************************************************/
2708 BOOL send_smb(int fd,char *buffer)
2710 int len;
2711 int ret,nwritten=0;
2712 len = smb_len(buffer) + 4;
2714 while (nwritten < len)
2716 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2717 if (ret <= 0)
2719 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2720 close_sockets();
2721 exit(1);
2723 nwritten += ret;
2727 return True;
2731 /****************************************************************************
2732 find a pointer to a netbios name
2733 ****************************************************************************/
2734 char *name_ptr(char *buf,int ofs)
2736 unsigned char c = *(unsigned char *)(buf+ofs);
2738 if ((c & 0xC0) == 0xC0)
2740 uint16 l;
2741 char p[2];
2742 memcpy(p,buf+ofs,2);
2743 p[0] &= ~0xC0;
2744 l = RSVAL(p,0);
2745 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2746 return(buf + l);
2748 else
2749 return(buf+ofs);
2752 /****************************************************************************
2753 extract a netbios name from a buf
2754 ****************************************************************************/
2755 int name_extract(char *buf,int ofs,char *name)
2757 char *p = name_ptr(buf,ofs);
2758 int d = PTR_DIFF(p,buf+ofs);
2759 strcpy(name,"");
2760 if (d < -50 || d > 50) return(0);
2761 return(name_interpret(p,name));
2764 /****************************************************************************
2765 return the total storage length of a mangled name
2766 ****************************************************************************/
2767 int name_len( char *s )
2769 int len;
2771 /* If the two high bits of the byte are set, return 2. */
2772 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2773 return(2);
2775 /* Add up the length bytes. */
2776 for( len = 1; (*s); s += (*s) + 1 )
2778 len += *s + 1;
2781 return( len );
2782 } /* name_len */
2784 /****************************************************************************
2785 send a single packet to a port on another machine
2786 ****************************************************************************/
2787 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2789 BOOL ret;
2790 int out_fd;
2791 struct sockaddr_in sock_out;
2793 if (passive)
2794 return(True);
2796 /* create a socket to write to */
2797 out_fd = socket(AF_INET, type, 0);
2798 if (out_fd == -1)
2800 DEBUG(0,("socket failed"));
2801 return False;
2804 /* set the address and port */
2805 bzero((char *)&sock_out,sizeof(sock_out));
2806 putip((char *)&sock_out.sin_addr,(char *)&ip);
2807 sock_out.sin_port = htons( port );
2808 sock_out.sin_family = AF_INET;
2810 if (DEBUGLEVEL > 0)
2811 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2812 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2814 /* send it */
2815 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2817 if (!ret)
2818 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2819 inet_ntoa(ip),port,strerror(errno)));
2821 close(out_fd);
2822 return(ret);
2825 /*******************************************************************
2826 sleep for a specified number of milliseconds
2827 ********************************************************************/
2828 void msleep(int t)
2830 int tdiff=0;
2831 struct timeval tval,t1,t2;
2832 fd_set fds;
2834 GetTimeOfDay(&t1);
2835 GetTimeOfDay(&t2);
2837 while (tdiff < t) {
2838 tval.tv_sec = (t-tdiff)/1000;
2839 tval.tv_usec = 1000*((t-tdiff)%1000);
2841 FD_ZERO(&fds);
2842 errno = 0;
2843 sys_select(&fds,&tval);
2845 GetTimeOfDay(&t2);
2846 tdiff = TvalDiff(&t1,&t2);
2850 /****************************************************************************
2851 check if a string is part of a list
2852 ****************************************************************************/
2853 BOOL in_list(char *s,char *list,BOOL casesensitive)
2855 pstring tok;
2856 char *p=list;
2858 if (!list) return(False);
2860 while (next_token(&p,tok,LIST_SEP))
2862 if (casesensitive) {
2863 if (strcmp(tok,s) == 0)
2864 return(True);
2865 } else {
2866 if (StrCaseCmp(tok,s) == 0)
2867 return(True);
2870 return(False);
2873 /* this is used to prevent lots of mallocs of size 1 */
2874 static char *null_string = NULL;
2876 /****************************************************************************
2877 set a string value, allocing the space for the string
2878 ****************************************************************************/
2879 BOOL string_init(char **dest,char *src)
2881 int l;
2882 if (!src)
2883 src = "";
2885 l = strlen(src);
2887 if (l == 0)
2889 if (!null_string)
2890 null_string = (char *)malloc(1);
2892 *null_string = 0;
2893 *dest = null_string;
2895 else
2897 (*dest) = (char *)malloc(l+1);
2898 if ((*dest) == NULL) {
2899 DEBUG(0,("Out of memory in string_init\n"));
2900 return False;
2903 strcpy(*dest,src);
2905 return(True);
2908 /****************************************************************************
2909 free a string value
2910 ****************************************************************************/
2911 void string_free(char **s)
2913 if (!s || !(*s)) return;
2914 if (*s == null_string)
2915 *s = NULL;
2916 if (*s) free(*s);
2917 *s = NULL;
2920 /****************************************************************************
2921 set a string value, allocing the space for the string, and deallocating any
2922 existing space
2923 ****************************************************************************/
2924 BOOL string_set(char **dest,char *src)
2926 string_free(dest);
2928 return(string_init(dest,src));
2931 /****************************************************************************
2932 substitute a string for a pattern in another string. Make sure there is
2933 enough room!
2935 This routine looks for pattern in s and replaces it with
2936 insert. It may do multiple replacements.
2938 return True if a substitution was done.
2939 ****************************************************************************/
2940 BOOL string_sub(char *s,char *pattern,char *insert)
2942 BOOL ret = False;
2943 char *p;
2944 int ls,lp,li;
2946 if (!insert || !pattern || !s) return(False);
2948 ls = strlen(s);
2949 lp = strlen(pattern);
2950 li = strlen(insert);
2952 if (!*pattern) return(False);
2954 while (lp <= ls && (p = strstr(s,pattern)))
2956 ret = True;
2957 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2958 memcpy(p,insert,li);
2959 s = p + li;
2960 ls = strlen(s);
2962 return(ret);
2967 /*********************************************************
2968 * Recursive routine that is called by mask_match.
2969 * Does the actual matching.
2970 *********************************************************/
2971 BOOL do_match(char *str, char *regexp, int case_sig)
2973 char *p;
2975 for( p = regexp; *p && *str; ) {
2976 switch(*p) {
2977 case '?':
2978 str++; p++;
2979 break;
2981 case '*':
2982 /* Look for a character matching
2983 the one after the '*' */
2984 p++;
2985 if(!*p)
2986 return True; /* Automatic match */
2987 while(*str) {
2988 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2989 str++;
2990 if(do_match(str,p,case_sig))
2991 return True;
2992 if(!*str)
2993 return False;
2994 else
2995 str++;
2997 return False;
2999 default:
3000 if(case_sig) {
3001 if(*str != *p)
3002 return False;
3003 } else {
3004 if(toupper(*str) != toupper(*p))
3005 return False;
3007 str++, p++;
3008 break;
3011 if(!*p && !*str)
3012 return True;
3014 if (!*p && str[0] == '.' && str[1] == 0)
3015 return(True);
3017 if (!*str && *p == '?')
3019 while (*p == '?') p++;
3020 return(!*p);
3023 if(!*str && (*p == '*' && p[1] == '\0'))
3024 return True;
3025 return False;
3029 /*********************************************************
3030 * Routine to match a given string with a regexp - uses
3031 * simplified regexp that takes * and ? only. Case can be
3032 * significant or not.
3033 *********************************************************/
3034 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3036 char *p;
3037 pstring p1, p2;
3038 fstring ebase,eext,sbase,sext;
3040 BOOL matched;
3042 /* Make local copies of str and regexp */
3043 StrnCpy(p1,regexp,sizeof(pstring)-1);
3044 StrnCpy(p2,str,sizeof(pstring)-1);
3046 if (!strchr(p2,'.')) {
3047 strcat(p2,".");
3051 if (!strchr(p1,'.')) {
3052 strcat(p1,".");
3056 #if 0
3057 if (strchr(p1,'.'))
3059 string_sub(p1,"*.*","*");
3060 string_sub(p1,".*","*");
3062 #endif
3064 /* Remove any *? and ** as they are meaningless */
3065 for(p = p1; *p; p++)
3066 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3067 (void)strcpy( &p[1], &p[2]);
3069 if (strequal(p1,"*")) return(True);
3071 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3073 if (trans2) {
3074 fstrcpy(ebase,p1);
3075 fstrcpy(sbase,p2);
3076 } else {
3077 if ((p=strrchr(p1,'.'))) {
3078 *p = 0;
3079 fstrcpy(ebase,p1);
3080 fstrcpy(eext,p+1);
3081 } else {
3082 fstrcpy(ebase,p1);
3083 eext[0] = 0;
3086 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3087 *p = 0;
3088 fstrcpy(sbase,p2);
3089 fstrcpy(sext,p+1);
3090 } else {
3091 fstrcpy(sbase,p2);
3092 fstrcpy(sext,"");
3096 matched = do_match(sbase,ebase,case_sig) &&
3097 (trans2 || do_match(sext,eext,case_sig));
3099 DEBUG(8,("mask_match returning %d\n", matched));
3101 return matched;
3106 /****************************************************************************
3107 become a daemon, discarding the controlling terminal
3108 ****************************************************************************/
3109 void become_daemon(void)
3111 #ifndef NO_FORK_DEBUG
3112 if (fork())
3113 _exit(0);
3115 /* detach from the terminal */
3116 #ifdef USE_SETSID
3117 setsid();
3118 #else /* USE_SETSID */
3119 #ifdef TIOCNOTTY
3121 int i = open("/dev/tty", O_RDWR);
3122 if (i >= 0)
3124 ioctl(i, (int) TIOCNOTTY, (char *)0);
3125 close(i);
3128 #endif /* TIOCNOTTY */
3129 #endif /* USE_SETSID */
3130 /* Close fd's 0,1,2. Needed if started by rsh */
3131 close_low_fds();
3132 #endif /* NO_FORK_DEBUG */
3136 /****************************************************************************
3137 put up a yes/no prompt
3138 ****************************************************************************/
3139 BOOL yesno(char *p)
3141 pstring ans;
3142 printf("%s",p);
3144 if (!fgets(ans,sizeof(ans)-1,stdin))
3145 return(False);
3147 if (*ans == 'y' || *ans == 'Y')
3148 return(True);
3150 return(False);
3153 /****************************************************************************
3154 read a line from a file with possible \ continuation chars.
3155 Blanks at the start or end of a line are stripped.
3156 The string will be allocated if s2 is NULL
3157 ****************************************************************************/
3158 char *fgets_slash(char *s2,int maxlen,FILE *f)
3160 char *s=s2;
3161 int len = 0;
3162 int c;
3163 BOOL start_of_line = True;
3165 if (feof(f))
3166 return(NULL);
3168 if (!s2)
3170 maxlen = MIN(maxlen,8);
3171 s = (char *)Realloc(s,maxlen);
3174 if (!s || maxlen < 2) return(NULL);
3176 *s = 0;
3178 while (len < maxlen-1)
3180 c = getc(f);
3181 switch (c)
3183 case '\r':
3184 break;
3185 case '\n':
3186 while (len > 0 && s[len-1] == ' ')
3188 s[--len] = 0;
3190 if (len > 0 && s[len-1] == '\\')
3192 s[--len] = 0;
3193 start_of_line = True;
3194 break;
3196 return(s);
3197 case EOF:
3198 if (len <= 0 && !s2)
3199 free(s);
3200 return(len>0?s:NULL);
3201 case ' ':
3202 if (start_of_line)
3203 break;
3204 default:
3205 start_of_line = False;
3206 s[len++] = c;
3207 s[len] = 0;
3209 if (!s2 && len > maxlen-3)
3211 maxlen *= 2;
3212 s = (char *)Realloc(s,maxlen);
3213 if (!s) return(NULL);
3216 return(s);
3221 /****************************************************************************
3222 set the length of a file from a filedescriptor.
3223 Returns 0 on success, -1 on failure.
3224 ****************************************************************************/
3225 int set_filelen(int fd, long len)
3227 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3228 extend a file with ftruncate. Provide alternate implementation
3229 for this */
3231 #if FTRUNCATE_CAN_EXTEND
3232 return ftruncate(fd, len);
3233 #else
3234 struct stat st;
3235 char c = 0;
3236 long currpos = lseek(fd, 0L, SEEK_CUR);
3238 if(currpos < 0)
3239 return -1;
3240 /* Do an fstat to see if the file is longer than
3241 the requested size (call ftruncate),
3242 or shorter, in which case seek to len - 1 and write 1
3243 byte of zero */
3244 if(fstat(fd, &st)<0)
3245 return -1;
3247 #ifdef S_ISFIFO
3248 if (S_ISFIFO(st.st_mode)) return 0;
3249 #endif
3251 if(st.st_size == len)
3252 return 0;
3253 if(st.st_size > len)
3254 return ftruncate(fd, len);
3256 if(lseek(fd, len-1, SEEK_SET) != len -1)
3257 return -1;
3258 if(write(fd, &c, 1)!=1)
3259 return -1;
3260 /* Seek to where we were */
3261 lseek(fd, currpos, SEEK_SET);
3262 return 0;
3263 #endif
3267 /****************************************************************************
3268 return the byte checksum of some data
3269 ****************************************************************************/
3270 int byte_checksum(char *buf,int len)
3272 unsigned char *p = (unsigned char *)buf;
3273 int ret = 0;
3274 while (len--)
3275 ret += *p++;
3276 return(ret);
3281 #ifdef HPUX
3282 /****************************************************************************
3283 this is a version of setbuffer() for those machines that only have setvbuf
3284 ****************************************************************************/
3285 void setbuffer(FILE *f,char *buf,int bufsize)
3287 setvbuf(f,buf,_IOFBF,bufsize);
3289 #endif
3292 /****************************************************************************
3293 parse out a directory name from a path name. Assumes dos style filenames.
3294 ****************************************************************************/
3295 char *dirname_dos(char *path,char *buf)
3297 char *p = strrchr(path,'\\');
3299 if (!p)
3300 strcpy(buf,path);
3301 else
3303 *p = 0;
3304 strcpy(buf,path);
3305 *p = '\\';
3308 return(buf);
3312 /****************************************************************************
3313 parse out a filename from a path name. Assumes dos style filenames.
3314 ****************************************************************************/
3315 static char *filename_dos(char *path,char *buf)
3317 char *p = strrchr(path,'\\');
3319 if (!p)
3320 strcpy(buf,path);
3321 else
3322 strcpy(buf,p+1);
3324 return(buf);
3329 /****************************************************************************
3330 expand a pointer to be a particular size
3331 ****************************************************************************/
3332 void *Realloc(void *p,int size)
3334 void *ret=NULL;
3336 if (size == 0) {
3337 if (p) free(p);
3338 DEBUG(5,("Realloc asked for 0 bytes\n"));
3339 return NULL;
3342 if (!p)
3343 ret = (void *)malloc(size);
3344 else
3345 ret = (void *)realloc(p,size);
3347 if (!ret)
3348 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3350 return(ret);
3353 #ifdef NOSTRDUP
3354 /****************************************************************************
3355 duplicate a string
3356 ****************************************************************************/
3357 char *strdup(char *s)
3359 char *ret = NULL;
3360 if (!s) return(NULL);
3361 ret = (char *)malloc(strlen(s)+1);
3362 if (!ret) return(NULL);
3363 strcpy(ret,s);
3364 return(ret);
3366 #endif
3369 /****************************************************************************
3370 Signal handler for SIGPIPE (write on a disconnected socket)
3371 ****************************************************************************/
3372 void Abort(void )
3374 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3375 exit(2);
3378 /****************************************************************************
3379 get my own name and IP
3380 ****************************************************************************/
3381 BOOL get_myname(char *my_name,struct in_addr *ip)
3383 struct hostent *hp;
3384 pstring hostname;
3386 *hostname = 0;
3388 /* get my host name */
3389 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3391 DEBUG(0,("gethostname failed\n"));
3392 return False;
3395 /* get host info */
3396 if ((hp = Get_Hostbyname(hostname)) == 0)
3398 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3399 return False;
3402 if (my_name)
3404 /* split off any parts after an initial . */
3405 char *p = strchr(hostname,'.');
3406 if (p) *p = 0;
3408 fstrcpy(my_name,hostname);
3411 if (ip)
3412 putip((char *)ip,(char *)hp->h_addr);
3414 return(True);
3418 /****************************************************************************
3419 true if two IP addresses are equal
3420 ****************************************************************************/
3421 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3423 uint32 a1,a2;
3424 a1 = ntohl(ip1.s_addr);
3425 a2 = ntohl(ip2.s_addr);
3426 return(a1 == a2);
3430 /****************************************************************************
3431 open a socket of the specified type, port and address for incoming data
3432 ****************************************************************************/
3433 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3435 struct hostent *hp;
3436 struct sockaddr_in sock;
3437 pstring host_name;
3438 int res;
3440 /* get my host name */
3441 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3442 { DEBUG(0,("gethostname failed\n")); return -1; }
3444 /* get host info */
3445 if ((hp = Get_Hostbyname(host_name)) == 0)
3447 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3448 return -1;
3451 bzero((char *)&sock,sizeof(sock));
3452 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3453 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3454 sock.sin_len = sizeof(sock);
3455 #endif
3456 sock.sin_port = htons( port );
3457 sock.sin_family = hp->h_addrtype;
3458 sock.sin_addr.s_addr = socket_addr;
3459 res = socket(hp->h_addrtype, type, 0);
3460 if (res == -1)
3461 { DEBUG(0,("socket failed\n")); return -1; }
3464 int one=1;
3465 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3468 /* now we've got a socket - we need to bind it */
3469 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3471 if (port) {
3472 if (port == SMB_PORT || port == NMB_PORT)
3473 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3474 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3475 close(res);
3477 if (dlevel > 0 && port < 1000)
3478 port = 7999;
3480 if (port >= 1000 && port < 9000)
3481 return(open_socket_in(type,port+1,dlevel,socket_addr));
3484 return(-1);
3486 DEBUG(3,("bind succeeded on port %d\n",port));
3488 return res;
3492 /****************************************************************************
3493 create an outgoing socket
3494 **************************************************************************/
3495 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3497 struct sockaddr_in sock_out;
3498 int res,ret;
3499 int connect_loop = 250; /* 250 milliseconds */
3500 int loops = (timeout * 1000) / connect_loop;
3502 /* create a socket to write to */
3503 res = socket(PF_INET, type, 0);
3504 if (res == -1)
3505 { DEBUG(0,("socket error\n")); return -1; }
3507 if (type != SOCK_STREAM) return(res);
3509 bzero((char *)&sock_out,sizeof(sock_out));
3510 putip((char *)&sock_out.sin_addr,(char *)addr);
3512 sock_out.sin_port = htons( port );
3513 sock_out.sin_family = PF_INET;
3515 /* set it non-blocking */
3516 set_blocking(res,False);
3518 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3520 /* and connect it to the destination */
3521 connect_again:
3522 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3524 /* Some systems return EAGAIN when they mean EINPROGRESS */
3525 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3526 errno == EAGAIN) && loops--) {
3527 msleep(connect_loop);
3528 goto connect_again;
3531 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3532 errno == EAGAIN)) {
3533 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3534 close(res);
3535 return -1;
3538 #ifdef EISCONN
3539 if (ret < 0 && errno == EISCONN) {
3540 errno = 0;
3541 ret = 0;
3543 #endif
3545 if (ret < 0) {
3546 DEBUG(1,("error connecting to %s:%d (%s)\n",
3547 inet_ntoa(*addr),port,strerror(errno)));
3548 return -1;
3551 /* set it blocking again */
3552 set_blocking(res,True);
3554 return res;
3558 /****************************************************************************
3559 interpret a protocol description string, with a default
3560 ****************************************************************************/
3561 int interpret_protocol(char *str,int def)
3563 if (strequal(str,"NT1"))
3564 return(PROTOCOL_NT1);
3565 if (strequal(str,"LANMAN2"))
3566 return(PROTOCOL_LANMAN2);
3567 if (strequal(str,"LANMAN1"))
3568 return(PROTOCOL_LANMAN1);
3569 if (strequal(str,"CORE"))
3570 return(PROTOCOL_CORE);
3571 if (strequal(str,"COREPLUS"))
3572 return(PROTOCOL_COREPLUS);
3573 if (strequal(str,"CORE+"))
3574 return(PROTOCOL_COREPLUS);
3576 DEBUG(0,("Unrecognised protocol level %s\n",str));
3578 return(def);
3581 /****************************************************************************
3582 interpret a security level
3583 ****************************************************************************/
3584 int interpret_security(char *str,int def)
3586 if (strequal(str,"SERVER"))
3587 return(SEC_SERVER);
3588 if (strequal(str,"USER"))
3589 return(SEC_USER);
3590 if (strequal(str,"SHARE"))
3591 return(SEC_SHARE);
3593 DEBUG(0,("Unrecognised security level %s\n",str));
3595 return(def);
3599 /****************************************************************************
3600 interpret an internet address or name into an IP address in 4 byte form
3601 ****************************************************************************/
3602 uint32 interpret_addr(char *str)
3604 struct hostent *hp;
3605 uint32 res;
3606 int i;
3607 BOOL pure_address = True;
3609 if (strcmp(str,"0.0.0.0") == 0) return(0);
3610 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3612 for (i=0; pure_address && str[i]; i++)
3613 if (!(isdigit(str[i]) || str[i] == '.'))
3614 pure_address = False;
3616 /* if it's in the form of an IP address then get the lib to interpret it */
3617 if (pure_address) {
3618 res = inet_addr(str);
3619 } else {
3620 /* otherwise assume it's a network name of some sort and use
3621 Get_Hostbyname */
3622 if ((hp = Get_Hostbyname(str)) == 0) {
3623 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3624 return 0;
3626 if(hp->h_addr == NULL) {
3627 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3628 return 0;
3630 putip((char *)&res,(char *)hp->h_addr);
3633 if (res == (uint32)-1) return(0);
3635 return(res);
3638 /*******************************************************************
3639 a convenient addition to interpret_addr()
3640 ******************************************************************/
3641 struct in_addr *interpret_addr2(char *str)
3643 static struct in_addr ret;
3644 uint32 a = interpret_addr(str);
3645 ret.s_addr = a;
3646 return(&ret);
3649 /*******************************************************************
3650 check if an IP is the 0.0.0.0
3651 ******************************************************************/
3652 BOOL zero_ip(struct in_addr ip)
3654 uint32 a;
3655 putip((char *)&a,(char *)&ip);
3656 return(a == 0);
3660 /*******************************************************************
3661 matchname - determine if host name matches IP address
3662 ******************************************************************/
3663 static BOOL matchname(char *remotehost,struct in_addr addr)
3665 struct hostent *hp;
3666 int i;
3668 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3669 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3670 return False;
3674 * Make sure that gethostbyname() returns the "correct" host name.
3675 * Unfortunately, gethostbyname("localhost") sometimes yields
3676 * "localhost.domain". Since the latter host name comes from the
3677 * local DNS, we just have to trust it (all bets are off if the local
3678 * DNS is perverted). We always check the address list, though.
3681 if (strcasecmp(remotehost, hp->h_name)
3682 && strcasecmp(remotehost, "localhost")) {
3683 DEBUG(0,("host name/name mismatch: %s != %s",
3684 remotehost, hp->h_name));
3685 return False;
3688 /* Look up the host address in the address list we just got. */
3689 for (i = 0; hp->h_addr_list[i]; i++) {
3690 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3691 return True;
3695 * The host name does not map to the original host address. Perhaps
3696 * someone has compromised a name server. More likely someone botched
3697 * it, but that could be dangerous, too.
3700 DEBUG(0,("host name/address mismatch: %s != %s",
3701 inet_ntoa(addr), hp->h_name));
3702 return False;
3705 /*******************************************************************
3706 Reset the 'done' variables so after a client process is created
3707 from a fork call these calls will be re-done. This should be
3708 expanded if more variables need reseting.
3709 ******************************************************************/
3711 static BOOL global_client_name_done = False;
3712 static BOOL global_client_addr_done = False;
3714 void reset_globals_after_fork()
3716 global_client_name_done = False;
3717 global_client_addr_done = False;
3720 /*******************************************************************
3721 return the DNS name of the client
3722 ******************************************************************/
3723 char *client_name(int fd)
3725 struct sockaddr sa;
3726 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3727 int length = sizeof(sa);
3728 static pstring name_buf;
3729 struct hostent *hp;
3730 static int last_fd=-1;
3732 if (global_client_name_done && last_fd == fd)
3733 return name_buf;
3735 last_fd = fd;
3736 global_client_name_done = False;
3738 strcpy(name_buf,"UNKNOWN");
3740 if (fd == -1) {
3741 return name_buf;
3744 if (getpeername(fd, &sa, &length) < 0) {
3745 DEBUG(0,("getpeername failed\n"));
3746 return name_buf;
3749 /* Look up the remote host name. */
3750 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3751 sizeof(sockin->sin_addr),
3752 AF_INET)) == 0) {
3753 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3754 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3755 } else {
3756 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3757 if (!matchname(name_buf, sockin->sin_addr)) {
3758 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3759 strcpy(name_buf,"UNKNOWN");
3762 global_client_name_done = True;
3763 return name_buf;
3766 /*******************************************************************
3767 return the IP addr of the client as a string
3768 ******************************************************************/
3769 char *client_addr(int fd)
3771 struct sockaddr sa;
3772 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3773 int length = sizeof(sa);
3774 static fstring addr_buf;
3775 static int last_fd = -1;
3777 if (global_client_addr_done && fd == last_fd)
3778 return addr_buf;
3780 last_fd = fd;
3781 global_client_addr_done = False;
3783 strcpy(addr_buf,"0.0.0.0");
3785 if (fd == -1) {
3786 return addr_buf;
3789 if (getpeername(fd, &sa, &length) < 0) {
3790 DEBUG(0,("getpeername failed\n"));
3791 return addr_buf;
3794 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3796 global_client_addr_done = True;
3797 return addr_buf;
3800 /*******************************************************************
3801 Patch from jkf@soton.ac.uk
3802 Split Luke's automount_server into YP lookup and string splitter
3803 so can easily implement automount_path().
3804 As we may end up doing both, cache the last YP result.
3805 *******************************************************************/
3807 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3808 static char *automount_lookup(char *user_name)
3810 static fstring last_key = "";
3811 static pstring last_value = "";
3813 int nis_error; /* returned by yp all functions */
3814 char *nis_result; /* yp_match inits this */
3815 int nis_result_len; /* and set this */
3816 char *nis_domain; /* yp_get_default_domain inits this */
3817 char *nis_map = (char *)lp_nis_home_map_name();
3819 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3821 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3822 return last_value;
3825 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3827 if (!strcmp(user_name, last_key))
3829 nis_result = last_value;
3830 nis_result_len = strlen(last_value);
3831 nis_error = 0;
3833 else
3835 if ((nis_error = yp_match(nis_domain, nis_map,
3836 user_name, strlen(user_name),
3837 &nis_result, &nis_result_len)) != 0)
3839 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3840 yperr_string(nis_error), user_name, nis_map));
3842 if (!nis_error && nis_result_len >= sizeof(pstring))
3844 nis_result_len = sizeof(pstring)-1;
3846 fstrcpy(last_key, user_name);
3847 strncpy(last_value, nis_result, nis_result_len);
3848 last_value[nis_result_len] = '\0';
3851 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3852 return last_value;
3854 #endif
3856 /*******************************************************************
3857 Patch from jkf@soton.ac.uk
3858 This is Luke's original function with the NIS lookup code
3859 moved out to a separate function.
3860 *******************************************************************/
3862 char *automount_server(char *user_name)
3864 static pstring server_name;
3865 int home_server_len;
3867 /* use the local machine name as the default */
3868 /* this will be the default if AUTOMOUNT is not used or fails */
3869 pstrcpy(server_name, local_machine);
3871 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3873 if (lp_nis_home_map())
3875 char *automount_value = automount_lookup(user_name);
3876 home_server_len = strcspn(automount_value,":");
3877 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3878 if (home_server_len > sizeof(pstring))
3880 home_server_len = sizeof(pstring);
3882 strncpy(server_name, automount_value, home_server_len);
3883 server_name[home_server_len] = '\0';
3885 #endif
3887 DEBUG(4,("Home server: %s\n", server_name));
3889 return server_name;
3892 /*******************************************************************
3893 Patch from jkf@soton.ac.uk
3894 Added this to implement %p (NIS auto-map version of %H)
3895 *******************************************************************/
3897 char *automount_path(char *user_name)
3899 static pstring server_path;
3900 char *home_path_start;
3902 /* use the passwd entry as the default */
3903 /* this will be the default if AUTOMOUNT is not used or fails */
3904 /* pstrcpy() copes with get_home_dir() returning NULL */
3905 pstrcpy(server_path, get_home_dir(user_name));
3907 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3909 if (lp_nis_home_map())
3911 char *automount_value = automount_lookup(user_name);
3912 home_path_start = strchr(automount_value,':');
3913 if (home_path_start != NULL)
3915 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3916 home_path_start?(home_path_start+1):""));
3917 strcpy(server_path, home_path_start+1);
3920 #endif
3922 DEBUG(4,("Home server path: %s\n", server_path));
3924 return server_path;
3928 /*******************************************************************
3929 sub strings with useful parameters
3930 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3931 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3932 ********************************************************************/
3933 void standard_sub_basic(char *str)
3935 char *s, *p;
3936 char pidstr[10];
3937 struct passwd *pass;
3938 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3940 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3942 switch (*(p+1))
3944 case 'G' :
3946 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3948 string_sub(p,"%G",gidtoname(pass->pw_gid));
3950 else
3952 p += 2;
3954 break;
3956 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3957 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3958 case 'L' : string_sub(p,"%L", local_machine); break;
3959 case 'M' : string_sub(p,"%M", client_name(Client)); break;
3960 case 'R' : string_sub(p,"%R", remote_proto); break;
3961 case 'T' : string_sub(p,"%T", timestring()); break;
3962 case 'U' : string_sub(p,"%U", username); break;
3963 case 'a' : string_sub(p,"%a", remote_arch); break;
3964 case 'd' :
3966 sprintf(pidstr,"%d",(int)getpid());
3967 string_sub(p,"%d", pidstr);
3968 break;
3970 case 'h' : string_sub(p,"%h", myhostname); break;
3971 case 'm' : string_sub(p,"%m", remote_machine); break;
3972 case 'v' : string_sub(p,"%v", VERSION); break;
3973 case '$' : /* Expand environment variables */
3975 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3976 fstring envname;
3977 char *envval;
3978 char *q, *r;
3979 int copylen;
3981 if (*(p+2) != '(') { p+=2; break; }
3982 if ((q = strchr(p,')')) == NULL)
3984 DEBUG(0,("standard_sub_basic: Unterminated environment \
3985 variable [%s]\n", p));
3986 p+=2; break;
3989 r = p+3;
3990 copylen = MIN((q-r),(sizeof(envname)-1));
3991 strncpy(envname,r,copylen);
3992 envname[copylen] = '\0';
3993 if ((envval = getenv(envname)) == NULL)
3995 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3996 envname));
3997 p+=2; break;
3999 copylen = MIN((q+1-p),(sizeof(envname)-1));
4000 strncpy(envname,p,copylen);
4001 envname[copylen] = '\0';
4002 string_sub(p,envname,envval);
4003 break;
4005 case '\0': p++; break; /* don't run off end if last character is % */
4006 default : p+=2; break;
4009 return;
4012 /*******************************************************************
4013 are two IPs on the same subnet?
4014 ********************************************************************/
4015 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4017 uint32 net1,net2,nmask;
4019 nmask = ntohl(mask.s_addr);
4020 net1 = ntohl(ip1.s_addr);
4021 net2 = ntohl(ip2.s_addr);
4023 return((net1 & nmask) == (net2 & nmask));
4027 /*******************************************************************
4028 write a string in unicoode format
4029 ********************************************************************/
4030 int PutUniCode(char *dst,char *src)
4032 int ret = 0;
4033 while (*src) {
4034 dst[ret++] = src[0];
4035 dst[ret++] = 0;
4036 src++;
4038 dst[ret++]=0;
4039 dst[ret++]=0;
4040 return(ret);
4043 /****************************************************************************
4044 a wrapper for gethostbyname() that tries with all lower and all upper case
4045 if the initial name fails
4046 ****************************************************************************/
4047 struct hostent *Get_Hostbyname(char *name)
4049 char *name2 = strdup(name);
4050 struct hostent *ret;
4052 if (!name2)
4054 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4055 exit(0);
4060 * This next test is redundent and causes some systems (with
4061 * broken isalnum() calls) problems.
4062 * JRA.
4065 #if 0
4066 if (!isalnum(*name2))
4068 free(name2);
4069 return(NULL);
4071 #endif /* 0 */
4073 ret = sys_gethostbyname(name2);
4074 if (ret != NULL)
4076 free(name2);
4077 return(ret);
4080 /* try with all lowercase */
4081 strlower(name2);
4082 ret = sys_gethostbyname(name2);
4083 if (ret != NULL)
4085 free(name2);
4086 return(ret);
4089 /* try with all uppercase */
4090 strupper(name2);
4091 ret = sys_gethostbyname(name2);
4092 if (ret != NULL)
4094 free(name2);
4095 return(ret);
4098 /* nothing works :-( */
4099 free(name2);
4100 return(NULL);
4104 /****************************************************************************
4105 check if a process exists. Does this work on all unixes?
4106 ****************************************************************************/
4107 BOOL process_exists(int pid)
4109 return(kill(pid,0) == 0 || errno != ESRCH);
4113 /*******************************************************************
4114 turn a uid into a user name
4115 ********************************************************************/
4116 char *uidtoname(int uid)
4118 static char name[40];
4119 struct passwd *pass = getpwuid(uid);
4120 if (pass) return(pass->pw_name);
4121 sprintf(name,"%d",uid);
4122 return(name);
4125 /*******************************************************************
4126 turn a gid into a group name
4127 ********************************************************************/
4128 char *gidtoname(int gid)
4130 static char name[40];
4131 struct group *grp = getgrgid(gid);
4132 if (grp) return(grp->gr_name);
4133 sprintf(name,"%d",gid);
4134 return(name);
4137 /*******************************************************************
4138 block sigs
4139 ********************************************************************/
4140 void BlockSignals(BOOL block,int signum)
4142 #ifdef USE_SIGBLOCK
4143 int block_mask = sigmask(signum);
4144 static int oldmask = 0;
4145 if (block)
4146 oldmask = sigblock(block_mask);
4147 else
4148 sigsetmask(oldmask);
4149 #elif defined(USE_SIGPROCMASK)
4150 sigset_t set;
4151 sigemptyset(&set);
4152 sigaddset(&set,signum);
4153 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4154 #endif
4157 #if AJT
4158 /*******************************************************************
4159 my own panic function - not suitable for general use
4160 ********************************************************************/
4161 void ajt_panic(void)
4163 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4165 #endif
4167 #ifdef USE_DIRECT
4168 #define DIRECT direct
4169 #else
4170 #define DIRECT dirent
4171 #endif
4173 /*******************************************************************
4174 a readdir wrapper which just returns the file name
4175 also return the inode number if requested
4176 ********************************************************************/
4177 char *readdirname(void *p)
4179 struct DIRECT *ptr;
4180 char *dname;
4182 if (!p) return(NULL);
4184 ptr = (struct DIRECT *)readdir(p);
4185 if (!ptr) return(NULL);
4187 dname = ptr->d_name;
4189 #ifdef NEXT2
4190 if (telldir(p) < 0) return(NULL);
4191 #endif
4193 #ifdef SUNOS5
4194 /* this handles a broken compiler setup, causing a mixture
4195 of BSD and SYSV headers and libraries */
4197 static BOOL broken_readdir = False;
4198 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4200 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4201 broken_readdir = True;
4203 if (broken_readdir)
4204 dname = dname - 2;
4206 #endif
4209 static pstring buf;
4210 pstrcpy(buf, dname);
4211 unix_to_dos(buf, True);
4212 dname = buf;
4215 return(dname);
4218 /*******************************************************************
4219 Utility function used to decide if the last component
4220 of a path matches a (possibly wildcarded) entry in a namelist.
4221 ********************************************************************/
4223 BOOL is_in_path(char *name, name_compare_entry *namelist)
4225 pstring last_component;
4226 char *p;
4228 DEBUG(8, ("is_in_path: %s\n", name));
4230 /* if we have no list it's obviously not in the path */
4231 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4233 DEBUG(8,("is_in_path: no name list.\n"));
4234 return False;
4237 /* Get the last component of the unix name. */
4238 p = strrchr(name, '/');
4239 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
4240 last_component[sizeof(last_component)-1] = '\0';
4242 for(; namelist->name != NULL; namelist++)
4244 if(namelist->is_wild)
4246 /* look for a wildcard match. */
4247 if (mask_match(last_component, namelist->name, case_sensitive, False))
4249 DEBUG(8,("is_in_path: mask match succeeded\n"));
4250 return True;
4253 else
4255 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4256 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4258 DEBUG(8,("is_in_path: match succeeded\n"));
4259 return True;
4263 DEBUG(8,("is_in_path: match not found\n"));
4265 return False;
4268 /*******************************************************************
4269 Strip a '/' separated list into an array of
4270 name_compare_enties structures suitable for
4271 passing to is_in_path(). We do this for
4272 speed so we can pre-parse all the names in the list
4273 and don't do it for each call to is_in_path().
4274 namelist is modified here and is assumed to be
4275 a copy owned by the caller.
4276 We also check if the entry contains a wildcard to
4277 remove a potentially expensive call to mask_match
4278 if possible.
4279 ********************************************************************/
4281 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4283 char *name_end;
4284 char *nameptr = namelist;
4285 int num_entries = 0;
4286 int i;
4288 (*ppname_array) = NULL;
4290 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4291 return;
4293 /* We need to make two passes over the string. The
4294 first to count the number of elements, the second
4295 to split it.
4297 while(*nameptr)
4299 if ( *nameptr == '/' )
4301 /* cope with multiple (useless) /s) */
4302 nameptr++;
4303 continue;
4305 /* find the next / */
4306 name_end = strchr(nameptr, '/');
4308 /* oops - the last check for a / didn't find one. */
4309 if (name_end == NULL)
4310 break;
4312 /* next segment please */
4313 nameptr = name_end + 1;
4314 num_entries++;
4317 if(num_entries == 0)
4318 return;
4320 if(( (*ppname_array) = (name_compare_entry *)malloc(
4321 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4323 DEBUG(0,("set_namearray: malloc fail\n"));
4324 return;
4327 /* Now copy out the names */
4328 nameptr = namelist;
4329 i = 0;
4330 while(*nameptr)
4332 if ( *nameptr == '/' )
4334 /* cope with multiple (useless) /s) */
4335 nameptr++;
4336 continue;
4338 /* find the next / */
4339 if ((name_end = strchr(nameptr, '/')) != NULL)
4341 *name_end = 0;
4344 /* oops - the last check for a / didn't find one. */
4345 if(name_end == NULL)
4346 break;
4348 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4349 (strchr( nameptr, '*')!=NULL));
4350 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4352 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4353 return;
4356 /* next segment please */
4357 nameptr = name_end + 1;
4358 i++;
4361 (*ppname_array)[i].name = NULL;
4363 return;
4366 /****************************************************************************
4367 routine to free a namearray.
4368 ****************************************************************************/
4370 void free_namearray(name_compare_entry *name_array)
4372 if(name_array == 0)
4373 return;
4375 if(name_array->name != NULL)
4376 free(name_array->name);
4378 free((char *)name_array);
4381 /****************************************************************************
4382 routine to do file locking
4383 ****************************************************************************/
4384 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4386 #if HAVE_FCNTL_LOCK
4387 struct flock lock;
4388 int ret;
4390 #if 1
4391 uint32 mask = 0xC0000000;
4393 /* make sure the count is reasonable, we might kill the lockd otherwise */
4394 count &= ~mask;
4396 /* the offset is often strange - remove 2 of its bits if either of
4397 the top two bits are set. Shift the top ones by two bits. This
4398 still allows OLE2 apps to operate, but should stop lockd from
4399 dieing */
4400 if ((offset & mask) != 0)
4401 offset = (offset & ~mask) | ((offset & mask) >> 2);
4402 #else
4403 uint32 mask = ((unsigned)1<<31);
4405 /* interpret negative counts as large numbers */
4406 if (count < 0)
4407 count &= ~mask;
4409 /* no negative offsets */
4410 offset &= ~mask;
4412 /* count + offset must be in range */
4413 while ((offset < 0 || (offset + count < 0)) && mask)
4415 offset &= ~mask;
4416 mask = mask >> 1;
4418 #endif
4421 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4423 lock.l_type = type;
4424 lock.l_whence = SEEK_SET;
4425 lock.l_start = (int)offset;
4426 lock.l_len = (int)count;
4427 lock.l_pid = 0;
4429 errno = 0;
4431 ret = fcntl(fd,op,&lock);
4433 if (errno != 0)
4434 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4436 /* a lock query */
4437 if (op == F_GETLK)
4439 if ((ret != -1) &&
4440 (lock.l_type != F_UNLCK) &&
4441 (lock.l_pid != 0) &&
4442 (lock.l_pid != getpid()))
4444 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4445 return(True);
4448 /* it must be not locked or locked by me */
4449 return(False);
4452 /* a lock set or unset */
4453 if (ret == -1)
4455 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4456 offset,count,op,type,strerror(errno)));
4458 /* perhaps it doesn't support this sort of locking?? */
4459 if (errno == EINVAL)
4461 DEBUG(3,("locking not supported? returning True\n"));
4462 return(True);
4465 return(False);
4468 /* everything went OK */
4469 DEBUG(8,("Lock call successful\n"));
4471 return(True);
4472 #else
4473 return(False);
4474 #endif
4477 /*******************************************************************
4478 lock a file - returning a open file descriptor or -1 on failure
4479 The timeout is in seconds. 0 means no timeout
4480 ********************************************************************/
4481 int file_lock(char *name,int timeout)
4483 int fd = open(name,O_RDWR|O_CREAT,0666);
4484 time_t t=0;
4485 if (fd < 0) return(-1);
4487 #if HAVE_FCNTL_LOCK
4488 if (timeout) t = time(NULL);
4489 while (!timeout || (time(NULL)-t < timeout)) {
4490 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4491 msleep(LOCK_RETRY_TIMEOUT);
4493 return(-1);
4494 #else
4495 return(fd);
4496 #endif
4499 /*******************************************************************
4500 unlock a file locked by file_lock
4501 ********************************************************************/
4502 void file_unlock(int fd)
4504 if (fd<0) return;
4505 #if HAVE_FCNTL_LOCK
4506 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4507 #endif
4508 close(fd);
4511 /*******************************************************************
4512 is the name specified one of my netbios names
4513 returns true is it is equal, false otherwise
4514 ********************************************************************/
4515 BOOL is_myname(char *s)
4517 int n;
4518 BOOL ret = False;
4520 for (n=0; my_netbios_names[n]; n++) {
4521 if (strequal(my_netbios_names[n], s))
4522 ret=True;
4524 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4525 return(ret);
4528 /*******************************************************************
4529 set the horrid remote_arch string based on an enum.
4530 ********************************************************************/
4531 void set_remote_arch(enum remote_arch_types type)
4533 ra_type = type;
4534 switch( type )
4536 case RA_WFWG:
4537 strcpy(remote_arch, "WfWg");
4538 return;
4539 case RA_OS2:
4540 strcpy(remote_arch, "OS2");
4541 return;
4542 case RA_WIN95:
4543 strcpy(remote_arch, "Win95");
4544 return;
4545 case RA_WINNT:
4546 strcpy(remote_arch, "WinNT");
4547 return;
4548 case RA_SAMBA:
4549 strcpy(remote_arch,"Samba");
4550 return;
4551 default:
4552 ra_type = RA_UNKNOWN;
4553 strcpy(remote_arch, "UNKNOWN");
4554 break;
4558 /*******************************************************************
4559 Get the remote_arch type.
4560 ********************************************************************/
4561 enum remote_arch_types get_remote_arch()
4563 return ra_type;
4567 /*******************************************************************
4568 skip past some unicode strings in a buffer
4569 ********************************************************************/
4570 char *skip_unicode_string(char *buf,int n)
4572 while (n--)
4574 while (*buf)
4575 buf += 2;
4576 buf += 2;
4578 return(buf);
4581 /*******************************************************************
4582 Return a ascii version of a unicode string
4583 Hack alert: uses fixed buffer(s) and only handles ascii strings
4584 ********************************************************************/
4585 #define MAXUNI 1024
4586 char *unistrn2(uint16 *buf, int len)
4588 static char lbufs[8][MAXUNI];
4589 static int nexti;
4590 char *lbuf = lbufs[nexti];
4591 char *p;
4593 nexti = (nexti+1)%8;
4595 DEBUG(10, ("unistrn2: "));
4597 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4599 DEBUG(10, ("%4x ", *buf));
4600 *p = *buf;
4603 DEBUG(10,("\n"));
4605 *p = 0;
4606 return lbuf;
4609 /*******************************************************************
4610 Return a ascii version of a unicode string
4611 Hack alert: uses fixed buffer(s) and only handles ascii strings
4612 ********************************************************************/
4613 #define MAXUNI 1024
4614 char *unistr2(uint16 *buf)
4616 static char lbufs[8][MAXUNI];
4617 static int nexti;
4618 char *lbuf = lbufs[nexti];
4619 char *p;
4621 nexti = (nexti+1)%8;
4623 DEBUG(10, ("unistr2: "));
4625 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4627 DEBUG(10, ("%4x ", *buf));
4628 *p = *buf;
4631 DEBUG(10,("\n"));
4633 *p = 0;
4634 return lbuf;
4637 /*******************************************************************
4638 create a null-terminated unicode string from a null-terminated ascii string.
4639 return number of unicode chars copied, excluding the null character.
4641 only handles ascii strings
4642 ********************************************************************/
4643 #define MAXUNI 1024
4644 int struni2(uint16 *p, char *buf)
4646 int len = 0;
4648 if (p == NULL) return 0;
4650 DEBUG(10, ("struni2: "));
4652 if (buf != NULL)
4654 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4656 DEBUG(10, ("%2x ", *buf));
4657 *p = *buf;
4660 DEBUG(10,("\n"));
4663 *p = 0;
4665 return len;
4668 /*******************************************************************
4669 Return a ascii version of a unicode string
4670 Hack alert: uses fixed buffer(s) and only handles ascii strings
4671 ********************************************************************/
4672 #define MAXUNI 1024
4673 char *unistr(char *buf)
4675 static char lbufs[8][MAXUNI];
4676 static int nexti;
4677 char *lbuf = lbufs[nexti];
4678 char *p;
4680 nexti = (nexti+1)%8;
4682 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4684 *p = *buf;
4686 *p = 0;
4687 return lbuf;
4690 /*******************************************************************
4691 strncpy for unicode strings
4692 ********************************************************************/
4693 int unistrncpy(char *dst, char *src, int len)
4695 int num_wchars = 0;
4697 while (*src && len > 0)
4699 *dst++ = *src++;
4700 *dst++ = *src++;
4701 len--;
4702 num_wchars++;
4704 *dst++ = 0;
4705 *dst++ = 0;
4707 return num_wchars;
4711 /*******************************************************************
4712 strcpy for unicode strings. returns length (in num of wide chars)
4713 ********************************************************************/
4714 int unistrcpy(char *dst, char *src)
4716 int num_wchars = 0;
4718 while (*src)
4720 *dst++ = *src++;
4721 *dst++ = *src++;
4722 num_wchars++;
4724 *dst++ = 0;
4725 *dst++ = 0;
4727 return num_wchars;
4731 /*******************************************************************
4732 safe string copy into a fstring
4733 ********************************************************************/
4734 void fstrcpy(char *dest, char *src)
4736 int maxlength = sizeof(fstring) - 1;
4737 if (!dest) {
4738 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4739 return;
4742 if (!src) {
4743 *dest = 0;
4744 return;
4747 while (maxlength-- && *src)
4748 *dest++ = *src++;
4749 *dest = 0;
4750 if (*src) {
4751 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4752 strlen(src)));
4756 /*******************************************************************
4757 safe string copy into a pstring
4758 ********************************************************************/
4759 void pstrcpy(char *dest, char *src)
4761 int maxlength = sizeof(pstring) - 1;
4762 if (!dest) {
4763 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4764 return;
4767 if (!src) {
4768 *dest = 0;
4769 return;
4772 while (maxlength-- && *src)
4773 *dest++ = *src++;
4774 *dest = 0;
4775 if (*src) {
4776 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4777 strlen(src)));
4782 /*******************************************************************
4783 align a pointer to a multiple of 4 bytes
4784 ********************************************************************/
4785 char *align4(char *q, char *base)
4787 if ((q - base) & 3)
4789 q += 4 - ((q - base) & 3);
4791 return q;
4794 /*******************************************************************
4795 align a pointer to a multiple of 2 bytes
4796 ********************************************************************/
4797 char *align2(char *q, char *base)
4799 if ((q - base) & 1)
4801 q++;
4803 return q;
4806 /*******************************************************************
4807 align a pointer to a multiple of align_offset bytes. looks like it
4808 will work for offsets of 0, 2 and 4...
4809 ********************************************************************/
4810 char *align_offset(char *q, char *base, int align_offset_len)
4812 int mod = ((q - base) & (align_offset_len-1));
4813 if (align_offset_len != 0 && mod != 0)
4815 q += align_offset_len - mod;
4817 return q;
4820 void print_asc(int level, unsigned char *buf,int len)
4822 int i;
4823 for (i=0;i<len;i++)
4824 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4827 void dump_data(int level,char *buf1,int len)
4829 unsigned char *buf = (unsigned char *)buf1;
4830 int i=0;
4831 if (len<=0) return;
4833 DEBUG(level,("[%03X] ",i));
4834 for (i=0;i<len;) {
4835 DEBUG(level,("%02X ",(int)buf[i]));
4836 i++;
4837 if (i%8 == 0) DEBUG(level,(" "));
4838 if (i%16 == 0) {
4839 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4840 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4841 if (i<len) DEBUG(level,("[%03X] ",i));
4844 if (i%16) {
4845 int n;
4847 n = 16 - (i%16);
4848 DEBUG(level,(" "));
4849 if (n>8) DEBUG(level,(" "));
4850 while (n--) DEBUG(level,(" "));
4852 n = MIN(8,i%16);
4853 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4854 n = (i%16) - n;
4855 if (n>0) print_asc(level,&buf[i-n],n);
4856 DEBUG(level,("\n"));
4860 char *tab_depth(int depth)
4862 static pstring spaces;
4863 memset(spaces, ' ', depth * 4);
4864 spaces[depth * 4] = 0;
4865 return spaces;
4868 /*****************************************************************
4869 Convert a domain SID to an ascii string. (non-reentrant).
4870 *****************************************************************/
4872 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4873 char *dom_sid_to_string(DOM_SID *sid)
4875 static pstring sidstr;
4876 char subauth[16];
4877 int i;
4878 uint32 ia = (sid->id_auth[5]) +
4879 (sid->id_auth[4] << 8 ) +
4880 (sid->id_auth[3] << 16) +
4881 (sid->id_auth[2] << 24);
4883 sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
4885 for (i = 0; i < sid->num_auths; i++)
4887 sprintf(subauth, "-%d", sid->sub_auths[i]);
4888 strcat(sidstr, subauth);
4891 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));
4892 return sidstr;