diff options
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/access.c | 289 | ||||
-rw-r--r-- | source/lib/charcnv.c | 164 | ||||
-rw-r--r-- | source/lib/charset.c | 383 | ||||
-rw-r--r-- | source/lib/fault.c | 82 | ||||
-rw-r--r-- | source/lib/getsmbpass.c | 165 | ||||
-rw-r--r-- | source/lib/interface.c | 457 | ||||
-rw-r--r-- | source/lib/kanji.c | 868 | ||||
-rw-r--r-- | source/lib/md4.c | 171 | ||||
-rw-r--r-- | source/lib/replace.c | 325 | ||||
-rw-r--r-- | source/lib/system.c | 413 | ||||
-rw-r--r-- | source/lib/time.c | 495 | ||||
-rw-r--r-- | source/lib/ufc.c | 782 | ||||
-rw-r--r-- | source/lib/username.c | 324 | ||||
-rw-r--r-- | source/lib/util.c | 4392 |
14 files changed, 0 insertions, 9310 deletions
diff --git a/source/lib/access.c b/source/lib/access.c deleted file mode 100644 index c338517ed67..00000000000 --- a/source/lib/access.c +++ /dev/null @@ -1,289 +0,0 @@ -/* -This module is an adaption of code from the tcpd-1.4 package written -by Wietse Venema, Eindhoven University of Technology, The Netherlands. - -The code is used here with permission. - -The code has been considerably changed from the original. Bug reports -should be sent to samba-bugs@samba.anu.edu.au -*/ - -#include "includes.h" - -#define ALLOW_PURE_ADDRESSES - -extern int DEBUGLEVEL; - -#ifndef INADDR_NONE -#define INADDR_NONE ((uint32)~0) -#endif - - -#define Good True -#define Bad False - -#define CLIENT_MATCH client_match - -/* Delimiters for lists of daemons or clients. */ - -static char sep[] = ", \t"; - -/* Constants to be used in assignments only, not in comparisons... */ - -#define YES 1 -#define NO 0 -#define FAIL (-1) - -/* Forward declarations. */ -static int list_match(char *list,char *item, int (*match_fn)()); -static int client_match(char *tok,char *item); -static int string_match(char *tok,char *s); -static int masked_match(char *tok, char *slash, char *s); - -/* Size of logical line buffer. */ -#define BUFLEN 2048 - -/* return true if access should be allowed to a service*/ -BOOL check_access(int snum) -{ - char *denyl,*allowl; - BOOL ret = False; - - denyl = lp_hostsdeny(snum); - if (denyl) denyl = strdup(denyl); - - allowl = lp_hostsallow(snum); - if (allowl) allowl = strdup(allowl); - - if ((!denyl || *denyl==0) && (!allowl || *allowl==0)) - ret = True; - - if (!ret) - { - if (allow_access(denyl,allowl,client_name(),client_addr())) - { - if (snum >= 0) - DEBUG(2,("Allowed connection from %s (%s) to %s\n", - client_name(),client_addr(), - lp_servicename(snum))); - ret = True; - } - else - if (snum >= 0) - DEBUG(0,("%s Denied connection from %s (%s) to %s\n", - timestring(), client_name(),client_addr(), - lp_servicename(snum))); - } - - if (denyl) free(denyl); - if (allowl) free(allowl); - return(ret); -} - - -/* return true if access should be allowed */ -BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr) -{ - char *client[2]; - - client[0] = cname; - client[1] = caddr; - - /* if theres no deny list and no allow list then allow access */ - if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0)) - return(True); - - /* if there is an allow list but no deny list then allow only hosts - on the allow list */ - if (!deny_list || *deny_list == 0) - return(list_match(allow_list,(char *)client,CLIENT_MATCH)); - - /* if theres a deny list but no allow list then allow - all hosts not on the deny list */ - if (!allow_list || *allow_list == 0) - return(!list_match(deny_list,(char *)client,CLIENT_MATCH)); - - /* if there are both type of list then allow all hosts on the allow list */ - if (list_match(allow_list,(char *)client,CLIENT_MATCH)) - return (True); - - /* if there are both type of list and it's not on the allow then - allow it if its not on the deny */ - if (list_match(deny_list,(char *)client,CLIENT_MATCH)) - return (False); - - return (True); -} - -/* list_match - match an item against a list of tokens with exceptions */ -/* (All modifications are marked with the initials "jkf") */ -static int list_match(char *list,char *item, int (*match_fn)()) -{ - char *tok; - char *listcopy; /* jkf */ - int match = NO; - - /* - * jkf@soton.ac.uk -- 31 August 1994 -- Stop list_match() - * overwriting the list given as its first parameter. - */ - - /* jkf -- can get called recursively with NULL list */ - listcopy = (list == 0) ? (char *)0 : strdup(list); - - /* - * Process tokens one at a time. We have exhausted all possible matches - * when we reach an "EXCEPT" token or the end of the list. If we do find - * a match, look for an "EXCEPT" list and recurse to determine whether - * the match is affected by any exceptions. - */ - - for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) { - if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ - break; - if ((match = (*match_fn) (tok, item))) /* YES or FAIL */ - break; - } - /* Process exceptions to YES or FAIL matches. */ - - if (match != NO) { - while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT")) - /* VOID */ ; - if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) { - if (listcopy != 0) free(listcopy); /* jkf */ - return (match); - } - } - - if (listcopy != 0) free(listcopy); /* jkf */ - return (NO); -} - - -/* client_match - match host name and address against token */ -static int client_match(char *tok,char *item) -{ - char **client = (char **)item; - int match; - - /* - * Try to match the address first. If that fails, try to match the host - * name if available. - */ - - if ((match = string_match(tok, client[1])) == 0) - if (client[0][0] != 0) - match = string_match(tok, client[0]); - return (match); -} - -/* string_match - match string against token */ -static int string_match(char *tok,char *s) -{ - int tok_len; - int str_len; - char *cut; - - /* - * Return YES if a token has the magic value "ALL". Return FAIL if the - * token is "FAIL". If the token starts with a "." (domain name), return - * YES if it matches the last fields of the string. If the token has the - * magic value "LOCAL", return YES if the string does not contain a "." - * character. If the token ends on a "." (network number), return YES if - * it matches the first fields of the string. If the token begins with a - * "@" (netgroup name), return YES if the string is a (host) member of - * the netgroup. Return YES if the token fully matches the string. If the - * token is a netnumber/netmask pair, return YES if the address is a - * member of the specified subnet. - */ - - if (tok[0] == '.') { /* domain: match last fields */ - if ((str_len = strlen(s)) > (tok_len = strlen(tok)) - && strcasecmp(tok, s + str_len - tok_len) == 0) - return (YES); - } else if (tok[0] == '@') { /* netgroup: look it up */ -#ifdef NETGROUP - static char *mydomain = NULL; - char *hostname = NULL; - BOOL netgroup_ok = False; - - if (!mydomain) yp_get_default_domain(&mydomain); - - if (!mydomain) { - DEBUG(0,("Unable to get default yp domain.\n")); - return NO; - } - if (!(hostname = strdup(s))) { - DEBUG(1,("out of memory for strdup!\n")); - return NO; - } - - netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain); - - DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n", - hostname, - mydomain, - tok+1, - BOOLSTR(netgroup_ok))); - -#ifdef NETGROUP_INSECURE - /* if you really want netgroups that match non qualified names - then define NETGROUP_INSECURE. It can, however, be a big - security hole */ - { - char *clnt_domain; - if (!netgroup_ok && (clnt_domain=strchr(hostname,'.'))) { - *clnt_domain++ = '\0'; - netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain); - } - } -#endif - - free(hostname); - - if (netgroup_ok) return(YES); -#else - DEBUG(0,("access: netgroup support is not configured\n")); - return (NO); -#endif - } else if (strcasecmp(tok, "ALL") == 0) { /* all: match any */ - return (YES); - } else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */ - return (FAIL); - } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ - if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0) - return (YES); - } else if (!strcasecmp(tok, s)) { /* match host name or address */ - return (YES); - } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */ - if (strncmp(tok, s, tok_len) == 0) - return (YES); - } else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */ - if (isdigit(s[0]) && masked_match(tok, cut, s)) - return (YES); - } - return (NO); -} - -/* masked_match - match address against netnumber/netmask */ -static int masked_match(char *tok, char *slash, char *s) -{ - uint32 net; - uint32 mask; - uint32 addr; - - if ((addr = interpret_addr(s)) == INADDR_NONE) - return (NO); - *slash = 0; - net = interpret_addr(tok); - *slash = '/'; - if (net == INADDR_NONE || (mask = interpret_addr(slash + 1)) == INADDR_NONE) { - DEBUG(0,("access: bad net/mask access control: %s", tok)); - return (NO); - } - return ((addr & mask) == net); -} - - - - diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c deleted file mode 100644 index a7dff4224be..00000000000 --- a/source/lib/charcnv.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Character set conversion Extensions - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#include "includes.h" -#define CTRLZ 26 -extern int DEBUGLEVEL; - -static char cvtbuf[1024]; - -static BOOL mapsinited = 0; - -static char unix2dos[256]; -static char dos2unix[256]; - -static void initmaps() { - int k; - - for (k = 0; k < 256; k++) unix2dos[k] = k; - for (k = 0; k < 256; k++) dos2unix[k] = k; - - mapsinited = True; -} - -static void update_map(char * str) { - char *p; - - for (p = str; *p; p++) { - if (p[1]) { - unix2dos[(unsigned char)*p] = p[1]; - dos2unix[(unsigned char)p[1]] = *p; - p++; - } - } -} - -static void init_iso8859_1() { - - int i; - if (!mapsinited) initmaps(); - - /* Do not map undefined characters to some accidental code */ - for (i = 128; i < 256; i++) - { - unix2dos[i] = CTRLZ; - dos2unix[i] = CTRLZ; - } - -/* MSDOS Code Page 850 -> ISO-8859 */ -update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365"); -update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356"); -update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372"); -update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250"); -update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200"); -update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330"); -update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236"); -update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341"); -update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207"); -update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213"); -update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366"); -update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230"); - -} - -/* Init for eastern european languages. May need more work ? */ - -static void init_iso8859_2() { - - int i; - if (!mapsinited) initmaps(); - - /* Do not map undefined characters to some accidental code */ - for (i = 128; i < 256; i++) - { - unix2dos[i] = CTRLZ; - dos2unix[i] = CTRLZ; - } - -update_map("\241\244\306\217\312\250\243\235\321\343\323\340\246\227\254\215"); -update_map("\257\275\261\245\346\206\352\251\263\210\361\344\363\242\266\230"); -update_map("\274\253\277\276"); -} - -/* - * Convert unix to dos - */ -char *unix2dos_format(char *str,BOOL overwrite) -{ - char *p; - char *dp; - - if (!mapsinited) initmaps(); - - if(lp_client_code_page() == KANJI_CODEPAGE) - return (*_unix_to_dos)(str, overwrite); - else { - if (overwrite) { - for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } - } -} - -/* - * Convert dos to unix - */ -char *dos2unix_format(char *str, BOOL overwrite) -{ - char *p; - char *dp; - - if (!mapsinited) initmaps(); - - if(lp_client_code_page() == KANJI_CODEPAGE) - return (*_dos_to_unix)(str, overwrite); - else { - if (overwrite) { - for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } - } -} - - -/* - * Interpret character set. - */ -int interpret_character_set(char *str, int def) -{ - - if (strequal (str, "iso8859-1")) { - init_iso8859_1(); - } else if (strequal (str, "iso8859-2")) { - init_iso8859_2(); - } else { - DEBUG(0,("unrecognized character set\n")); - } - return def; -} diff --git a/source/lib/charset.c b/source/lib/charset.c deleted file mode 100644 index 4869e09fecf..00000000000 --- a/source/lib/charset.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Character set handling - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define CHARSET_C -#include "includes.h" - -extern int DEBUGLEVEL; - -/* - * Codepage definitions. - */ - -#if !defined(KANJI) -/* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */ -unsigned char cp_850[][4] = { -/* dec col/row oct hex description */ -/* 133 08/05 205 85 a grave */ -/* 183 11/07 267 B7 A grave */ {0x85,0xB7,1,1}, -/* 160 10/00 240 A0 a acute */ -/* 181 11/05 265 B5 A acute */ {0xA0,0xB5,1,1}, -/* 131 08/03 203 83 a circumflex */ -/* 182 11/06 266 B6 A circumflex */ {0x83,0xB6,1,1}, -/* 198 12/06 306 C6 a tilde */ -/* 199 12/07 307 C7 A tilde */ {0xC6,0xC7,1,1}, -/* 132 08/04 204 84 a diaeresis */ -/* 142 08/14 216 8E A diaeresis */ {0x84,0x8E,1,1}, -/* 134 08/06 206 86 a ring */ -/* 143 08/15 217 8F A ring */ {0x86,0x8F,1,1}, -/* 145 09/01 221 91 ae diphthong */ -/* 146 09/02 222 92 AE diphthong */ {0x91,0x92,1,1}, -/* 135 08/07 207 87 c cedilla */ -/* 128 08/00 200 80 C cedilla */ {0x87,0x80,1,1}, -/* 138 08/10 212 8A e grave */ -/* 212 13/04 324 D4 E grave */ {0x8A,0xD4,1,1}, -/* 130 08/02 202 82 e acute */ -/* 144 09/00 220 90 E acute */ {0x82,0x90,1,1}, -/* 136 08/08 210 88 e circumflex */ -/* 210 13/02 322 D2 E circumflex */ {0x88,0xD2,1,1}, -/* 137 08/09 211 89 e diaeresis */ -/* 211 13/03 323 D3 E diaeresis */ {0x89,0xD3,1,1}, -/* 141 08/13 215 8D i grave */ -/* 222 13/14 336 DE I grave */ {0x8D,0xDE,1,1}, -/* 161 10/01 241 A1 i acute */ -/* 214 13/06 326 D6 I acute */ {0xA1,0xD6,1,1}, -/* 140 08/12 214 8C i circumflex */ -/* 215 13/07 327 D7 I circumflex */ {0x8C,0xD7,1,1}, -/* 139 08/11 213 8B i diaeresis */ -/* 216 13/08 330 D8 I diaeresis */ {0x8B,0xD8,1,1}, -/* 208 13/00 320 D0 Icelandic eth */ -/* 209 13/01 321 D1 Icelandic Eth */ {0xD0,0xD1,1,1}, -/* 164 10/04 244 A4 n tilde */ -/* 165 10/05 245 A5 N tilde */ {0xA4,0xA5,1,1}, -/* 149 09/05 225 95 o grave */ -/* 227 14/03 343 E3 O grave */ {0x95,0xE3,1,1}, -/* 162 10/02 242 A2 o acute */ -/* 224 14/00 340 E0 O acute */ {0xA2,0xE0,1,1}, -/* 147 09/03 223 93 o circumflex */ -/* 226 14/02 342 E2 O circumflex */ {0x93,0xE2,1,1}, -/* 228 14/04 344 E4 o tilde */ -/* 229 14/05 345 E5 O tilde */ {0xE4,0xE5,1,1}, -/* 148 09/04 224 94 o diaeresis */ -/* 153 09/09 231 99 O diaeresis */ {0x94,0x99,1,1}, -/* 155 09/11 233 9B o slash */ -/* 157 09/13 235 9D O slash */ {0x9B,0x9D,1,1}, -/* 151 09/07 227 97 u grave */ -/* 235 14/11 353 EB U grave */ {0x97,0xEB,1,1}, -/* 163 10/03 243 A3 u acute */ -/* 233 14/09 351 E9 U acute */ {0xA3,0xE9,1,1}, -/* 150 09/06 226 96 u circumflex */ -/* 234 14/10 352 EA U circumflex */ {0x96,0xEA,1,1}, -/* 129 08/01 201 81 u diaeresis */ -/* 154 09/10 232 9A U diaeresis */ {0x81,0x9A,1,1}, -/* 236 14/12 354 EC y acute */ -/* 237 14/13 355 ED Y acute */ {0xEC,0xED,1,1}, -/* 231 14/07 347 E7 Icelandic thorn */ -/* 232 14/08 350 E8 Icelandic Thorn */ {0xE7,0xE8,1,1}, - - {0x9C,0,0,0}, /* Pound */ - {0,0,0,0} -}; -#else /* KANJI */ -/* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */ -unsigned char cp_932[][4] = { - {0,0,0,0} -}; -#endif /* KANJI */ - -char xx_dos_char_map[256]; -char xx_upper_char_map[256]; -char xx_lower_char_map[256]; - -char *dos_char_map = xx_dos_char_map; -char *upper_char_map = xx_upper_char_map; -char *lower_char_map = xx_lower_char_map; - -/* - * This code has been extended to deal with ascynchronous mappings - * like MS-DOS Latin US (Code page 437) where things like : - * a acute are capitalized to 'A', but the reverse mapping - * must not hold true. This allows the filename case insensitive - * matching in do_match() to work, as the DOS/Win95/NT client - * uses 'A' as a mask to match against characters like a acute. - * This is the meaning behind the parameters that allow a - * mapping from lower to upper, but not upper to lower. - */ - -static void add_dos_char(int lower, BOOL map_lower_to_upper, - int upper, BOOL map_upper_to_lower) -{ - lower &= 0xff; - upper &= 0xff; - DEBUG(6,("Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n",lower,upper, - map_lower_to_upper ? "True" : "False", - map_upper_to_lower ? "True" : "False")); - if (lower) dos_char_map[lower] = 1; - if (upper) dos_char_map[upper] = 1; - if (lower && upper) { - if(map_upper_to_lower) - lower_char_map[upper] = (char)lower; - if(map_lower_to_upper) - upper_char_map[lower] = (char)upper; - } -} - -/**************************************************************************** -initialise the charset arrays -****************************************************************************/ -void charset_initialise() -{ - int i; - -#ifdef LC_ALL - /* include <locale.h> in includes.h if available for OS */ - /* we take only standard 7-bit ASCII definitions from ctype */ - setlocale(LC_ALL,"C"); -#endif - - for (i= 0;i<=255;i++) { - dos_char_map[i] = 0; - } - - for (i=0;i<=127;i++) { - if (isalnum((char)i) || strchr("._^$~!#%&-{}()@'`",(char)i)) - add_dos_char(i,False,0,False); - } - - for (i=0; i<=255; i++) { - char c = (char)i; - upper_char_map[i] = lower_char_map[i] = c; - if (isupper(c)) lower_char_map[i] = tolower(c); - if (islower(c)) upper_char_map[i] = toupper(c); - } -} - -/**************************************************************************** -load the client codepage. -****************************************************************************/ - -typedef unsigned char (*codepage_p)[4]; - -static codepage_p load_client_codepage( int client_codepage ) -{ - pstring codepage_file_name; - unsigned char buf[8]; - FILE *fp = NULL; - unsigned int size; - codepage_p cp_p = NULL; - struct stat st; - - DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage)); - - if(strlen(CODEPAGEDIR) + 14 > sizeof(codepage_file_name)) - { - DEBUG(0,("load_client_codepage: filename too long to load\n")); - return NULL; - } - - strcpy(codepage_file_name, CODEPAGEDIR); - strcat(codepage_file_name, "/"); - strcat(codepage_file_name, "codepage."); - sprintf( &codepage_file_name[strlen(codepage_file_name)], "%03d", - client_codepage); - - if(!file_exist(codepage_file_name,&st)) - { - DEBUG(0,("load_client_codepage: filename %s does not exist.\n", - codepage_file_name)); - return NULL; - } - - /* Check if it is at least big enough to hold the required - data. Should be 2 byte version, 2 byte codepage, 4 byte length, - plus zero or more bytes of data. Note that the data cannot be more - than 512 bytes - giving a max size of 520. - */ - size = (unsigned int)st.st_size; - - if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256)) - { - DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \ -code page file.\n", codepage_file_name)); - return NULL; - } - - /* Read the first 8 bytes of the codepage file - check - the version number and code page number. All the data - is held in little endian format. - */ - - if((fp = fopen( codepage_file_name, "r")) == NULL) - { - DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n", - codepage_file_name, strerror(errno))); - return NULL; - } - - if(fread( buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE) - { - DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n", - codepage_file_name, strerror(errno))); - goto clean_and_exit; - } - - /* Check the version value */ - if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID, - SVAL(buf,CODEPAGE_VERSION_OFFSET))); - goto clean_and_exit; - } - - /* Check the codepage matches */ - if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)client_codepage, - SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET))); - goto clean_and_exit; - } - - /* Check the length is correct. */ - if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != - (unsigned int)(size - CODEPAGE_HEADER_SIZE)) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \ -Needed %u, got %u.\n", codepage_file_name, size - CODEPAGE_HEADER_SIZE, - IVAL(buf,CODEPAGE_LENGTH_OFFSET))); - goto clean_and_exit; - } - - size -= CODEPAGE_HEADER_SIZE; /* Remove header */ - - /* Make sure the size is a multiple of 4. */ - if((size % 4 ) != 0) - { - DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \ -multiple of 4.\n", codepage_file_name)); - goto clean_and_exit; - } - - /* Allocate space for the code page file and read it all in. */ - if((cp_p = (codepage_p)malloc( size + 4 )) == NULL) - { - DEBUG(0,("load_client_codepage: malloc fail.\n")); - goto clean_and_exit; - } - - if(fread( (char *)cp_p, 1, size, fp)!=size) - { - DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n", - codepage_file_name, strerror(errno))); - goto clean_and_exit; - } - - /* Ensure array is correctly terminated. */ - memset(((char *)cp_p) + size, '\0', 4); - - fclose(fp); - return cp_p; - -clean_and_exit: - - /* pseudo destructor :-) */ - - if(fp != NULL) - fclose(fp); - if(cp_p) - free((char *)cp_p); - return NULL; -} - -/**************************************************************************** -initialise the client codepage. -****************************************************************************/ -void codepage_initialise(int client_codepage) -{ - int i; - codepage_p cp = NULL; - static BOOL done = False; - - if(done == True) - { - DEBUG(6, - ("codepage_initialise: called twice - ignoring second client code page = %d\n", - client_codepage)); - return; - } - - DEBUG(6,("codepage_initialise: client code page = %d\n", client_codepage)); - - /* - * Known client codepages - these can be added to. - */ - cp = load_client_codepage( client_codepage ); - - if(cp == NULL) - { -#ifdef KANJI - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 932\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_932; -#else /* KANJI */ - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 850\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_850; -#endif /* KANJI */ - } - - if(cp) - { - for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++) - add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]); - } - - done = True; -} - -/******************************************************************* -add characters depending on a string passed by the user -********************************************************************/ -void add_char_string(char *s) -{ - char *extra_chars = (char *)strdup(s); - char *t; - if (!extra_chars) return; - - for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) { - char c1=0,c2=0; - int i1=0,i2=0; - if (isdigit((unsigned char)*t) || (*t)=='-') { - sscanf(t,"%i:%i",&i1,&i2); - add_dos_char(i1,True,i2,True); - } else { - sscanf(t,"%c:%c",&c1,&c2); - add_dos_char((unsigned char)c1,True,(unsigned char)c2, True); - } - } - - free(extra_chars); -} diff --git a/source/lib/fault.c b/source/lib/fault.c deleted file mode 100644 index 61715a4f225..00000000000 --- a/source/lib/fault.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Critical Fault handling - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -extern int DEBUGLEVEL; - - -static void (*cont_fn)(); - - -/******************************************************************* -report a fault -********************************************************************/ -static void fault_report(int sig) -{ - DEBUG(0,("===============================================================\n")); - DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION)); - DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n")); - DEBUG(0,("===============================================================\n")); - -#if AJT - ajt_panic(); -#endif - - if (cont_fn) - { - fault_setup(cont_fn); - cont_fn(NULL); -#ifdef SIGSEGV - signal(SIGSEGV,SIGNAL_CAST SIG_DFL); -#endif -#ifdef SIGBUS - signal(SIGBUS,SIGNAL_CAST SIG_DFL); -#endif - return; /* this should cause a core dump */ - } - exit(1); -} - -/**************************************************************************** -catch serious errors -****************************************************************************/ -static void sig_fault(int sig) -{ - fault_report(sig); -} - -/******************************************************************* -setup our fault handlers -********************************************************************/ -void fault_setup(void (*fn)()) -{ - cont_fn = fn; - -#ifdef SIGSEGV - signal(SIGSEGV,SIGNAL_CAST sig_fault); -#endif -#ifdef SIGBUS - signal(SIGBUS,SIGNAL_CAST sig_fault); -#endif -} - - - diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c deleted file mode 100644 index e8cb683d0b1..00000000000 --- a/source/lib/getsmbpass.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (C) 1992-1997 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ - -#include "includes.h" - -#ifdef REPLACE_GETPASS - -#ifdef SYSV_TERMIO - -/* SYSTEM V TERMIO HANDLING */ - -static struct termio t; - -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -#ifndef TCSAFLUSH -#define TCSAFLUSH 1 -#endif - -#ifndef TCSANOW -#define TCSANOW 0 -#endif - - int tcgetattr(int fd, struct termio *t) -{ - return ioctl(fd, TCGETA, t); -} - - int tcsetattr(int fd, int flags, struct termio *t) -{ - if(flags & TCSAFLUSH) - ioctl(fd, TCFLSH, TCIOFLUSH); - return ioctl(fd, TCSETS, t); -} - -#else /* SYSV_TERMIO */ -#ifdef BSD_TERMIO - -/* BSD TERMIO HANDLING */ - -static struct sgttyb t; - -#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) -#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) - -#ifndef TCSAFLUSH -#define TCSAFLUSH 1 -#endif - -#ifndef TCSANOW -#define TCSANOW 0 -#endif - - int tcgetattr(int fd, struct sgttyb *t) -{ - return ioctl(fd, TIOCGETP, (char *)t); -} - - int tcsetattr(int fd, int flags, struct sgttyb *t) -{ - return ioctl(fd, TIOCSETP, (char *)t); -} - -#else /* BSD_TERMIO */ - -/* POSIX TERMIO HANDLING */ -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -static struct termios t; -#endif /* BSD_TERMIO */ -#endif /* SYSV_TERMIO */ - -char *getsmbpass(char *prompt) -{ - FILE *in, *out; - int echo_off; - static char buf[256]; - static size_t bufsize = sizeof(buf); - size_t nread; - - /* Catch problematic signals */ - signal(SIGINT, SIGNAL_CAST SIG_IGN); - - /* Try to write to and read from the terminal if we can. - If we can't open the terminal, use stderr and stdin. */ - - in = fopen ("/dev/tty", "w+"); - if (in == NULL) - { - in = stdin; - out = stderr; - } - else - out = in; - - setvbuf(in, NULL, _IONBF, 0); - - /* Turn echoing off if it is on now. */ - - if (tcgetattr (fileno (in), &t) == 0) - { - if (ECHO_IS_ON(t)) - { - TURN_ECHO_OFF(t); - echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; - TURN_ECHO_ON(t); - } - else - echo_off = 0; - } - else - echo_off = 0; - - /* Write the prompt. */ - fputs (prompt, out); - fflush (out); - - /* Read the password. */ - buf[0] = 0; - fgets(buf, bufsize, in); - nread = strlen(buf); - if (buf[nread - 1] == '\n') - buf[nread - 1] = '\0'; - - /* Restore echoing. */ - if (echo_off) - (void) tcsetattr (fileno (in), TCSANOW, &t); - - if (in != stdin) - /* We opened the terminal; now close it. */ - fclose (in); - - /* Catch problematic signals */ - signal(SIGINT, SIGNAL_CAST SIG_DFL); - - printf("\n"); - return buf; -} - -#else - - void getsmbpasswd_dummy() {;} -#endif diff --git a/source/lib/interface.c b/source/lib/interface.c deleted file mode 100644 index 147425d0fc1..00000000000 --- a/source/lib/interface.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - multiple interface handling - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -extern int DEBUGLEVEL; - -struct in_addr ipzero; -struct in_addr wins_ip; -static struct in_addr default_ip; -static struct in_addr default_bcast; -static struct in_addr default_nmask; -static BOOL got_ip=False; -static BOOL got_bcast=False; -static BOOL got_nmask=False; - -struct interface *local_interfaces = NULL; - -struct interface *last_iface; - -/**************************************************************************** -calculate the default netmask for an address -****************************************************************************/ -static void default_netmask(struct in_addr *inm, struct in_addr *iad) -{ - uint32 ad = ntohl(iad->s_addr); - uint32 nm; - /* - ** Guess a netmask based on the class of the IP address given. - */ - if ( (ad & 0x80000000) == 0 ) { - /* class A address */ - nm = 0xFF000000; - } else if ( (ad & 0xC0000000) == 0x80000000 ) { - /* class B address */ - nm = 0xFFFF0000; - } else if ( (ad & 0xE0000000) == 0xC0000000 ) { - /* class C address */ - nm = 0xFFFFFF00; - } else { - /* class D or E; netmask doesn't make much sense - guess 4 bits */ - nm = 0xFFFFFFF0; - } - inm->s_addr = htonl(nm); -} - - -/**************************************************************************** - get the broadcast address for our address -(troyer@saifr00.ateng.az.honeywell.com) -****************************************************************************/ -static void get_broadcast(struct in_addr *if_ipaddr, - struct in_addr *if_bcast, - struct in_addr *if_nmask) -{ - BOOL found = False; -#ifndef NO_GET_BROADCAST - int sock = -1; /* AF_INET raw socket desc */ - char buff[1024]; - struct ifreq *ifr=NULL; - int i; - -#if defined(EVEREST) - int n_interfaces; - struct ifconf ifc; - struct ifreq *ifreqs; -#elif defined(USE_IFREQ) - struct ifreq ifreq; - struct strioctl strioctl; - struct ifconf *ifc; -#else - struct ifconf ifc; -#endif -#endif - - /* get a default netmask and broadcast */ - default_netmask(if_nmask, if_ipaddr); - -#ifndef NO_GET_BROADCAST - /* Create a socket to the INET kernel. */ -#if USE_SOCKRAW - if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0) -#else - if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0) -#endif - { - DEBUG(0,( "Unable to open socket to get broadcast address\n")); - return; - } - - /* Get a list of the configured interfaces */ -#ifdef EVEREST - /* This is part of SCO Openserver 5: The ioctls are no longer part - if the lower level STREAMS interface glue. They are now real - ioctl calls */ - - if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) { - DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno))); - } else { - DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces)); - - ifc.ifc_len = sizeof(struct ifreq) * n_interfaces; - ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len); - - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) - DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno))); - else { - ifr = ifc.ifc_req; - - for (i = 0; i < n_interfaces; ++i) { - if (if_ipaddr->s_addr == - ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) { - found = True; - break; - } - } - } - } -#elif defined(USE_IFREQ) - ifc = (struct ifconf *)buff; - ifc->ifc_len = BUFSIZ - sizeof(struct ifconf); - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = (char *)ifc; - strioctl.ic_len = sizeof(buff); - if (ioctl(sock, I_STR, &strioctl) < 0) { - DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = (struct ifreq *)ifc->ifc_req; - - /* Loop through interfaces, looking for given IP address */ - for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - } - } -#elif defined(__FreeBSD__) || defined(NETBSD) || defined(AMIGA) || defined(_AIX41) - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { - DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = ifc.ifc_req; - /* Loop through interfaces, looking for given IP address */ - i = ifc.ifc_len; - while (i > 0) { - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - i -= ifr->ifr_addr.sa_len + IFNAMSIZ; - ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ); - } - } -#else - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { - DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = ifc.ifc_req; - - /* Loop through interfaces, looking for given IP address */ - for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { -#ifdef BSDI - if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break; -#endif - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - } - } -#endif - - if (!found) { - DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr))); - } else { - /* Get the netmask address from the kernel */ -#ifdef USE_IFREQ - ifreq = *ifr; - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(sock, I_STR, &strioctl) < 0) - DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno))); - else - *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr; -#else - if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0) - DEBUG(0,("SIOCGIFNETMASK failed\n")); - else - *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; -#endif - - DEBUG(4,("Netmask for %s = %s\n", ifr->ifr_name, - inet_ntoa(*if_nmask))); - } - - /* Close up shop */ - (void) close(sock); - -#endif - - /* sanity check on the netmask */ - { - uint32 nm = ntohl(if_nmask->s_addr); - if ((nm >> 24) != 0xFF) { - DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask))); - default_netmask(if_nmask, if_ipaddr); - } - } - - /* derive the broadcast assuming a 1's broadcast, as this is what - all MS operating systems do, we have to comply even if the unix - box is setup differently */ - { - uint32 ad = ntohl(if_ipaddr->s_addr); - uint32 nm = ntohl(if_nmask->s_addr); - uint32 bc = (ad & nm) | (0xffffffff & ~nm); - if_bcast->s_addr = htonl(bc); - } - - DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast))); -} /* get_broadcast */ - - - -/**************************************************************************** -load a list of network interfaces -****************************************************************************/ -static void interpret_interfaces(char *s, struct interface **interfaces, - char *description) -{ - char *ptr = s; - fstring token; - struct interface *iface; - struct in_addr ip; - - ipzero = *interpret_addr2("0.0.0.0"); - wins_ip = *interpret_addr2("255.255.255.255"); - - while (next_token(&ptr,token,NULL)) { - /* parse it into an IP address/netmasklength pair */ - char *p = strchr(token,'/'); - if (p) *p = 0; - - ip = *interpret_addr2(token); - - /* maybe we already have it listed */ - { - struct interface *i; - for (i=(*interfaces);i;i=i->next) - if (ip_equal(ip,i->ip)) break; - if (i) continue; - } - - iface = (struct interface *)malloc(sizeof(*iface)); - if (!iface) return; - - iface->ip = ip; - - if (p) { - if (strlen(p+1)>2) - iface->nmask = *interpret_addr2(p+1); - else - iface->nmask.s_addr = htonl(~((1<<(32-atoi(p+1)))-1)); - } else { - default_netmask(&iface->nmask,&iface->ip); - } - iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr; - iface->next = NULL; - - if (!(*interfaces)) { - (*interfaces) = iface; - } else { - last_iface->next = iface; - } - last_iface = iface; - DEBUG(1,("Added %s ip=%s ",description,inet_ntoa(iface->ip))); - DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask))); - } - - if (*interfaces) return; - - /* setup a default interface */ - iface = (struct interface *)malloc(sizeof(*iface)); - if (!iface) return; - - iface->next = NULL; - - if (got_ip) { - iface->ip = default_ip; - } else { - get_myname(NULL,&iface->ip); - } - - if (got_bcast) { - iface->bcast = default_bcast; - } else { - get_broadcast(&iface->ip,&iface->bcast,&iface->nmask); - } - - if (got_nmask) { - iface->nmask = default_nmask; - iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr; - } - - if (iface->bcast.s_addr != (iface->ip.s_addr | ~iface->nmask.s_addr)) { - DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip))); - } - - iface->next = NULL; - (*interfaces) = last_iface = iface; - - DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip))); - DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask))); -} - - -/**************************************************************************** -load the remote and local interfaces -****************************************************************************/ -void load_interfaces(void) -{ - /* add the machine's interfaces to local interface structure*/ - interpret_interfaces(lp_interfaces(), &local_interfaces,"interface"); -} - - -/**************************************************************************** - override the defaults - **************************************************************************/ -void iface_set_default(char *ip,char *bcast,char *nmask) -{ - if (ip) { - got_ip = True; - default_ip = *interpret_addr2(ip); - } - - if (bcast) { - got_bcast = True; - default_bcast = *interpret_addr2(bcast); - } - - if (nmask) { - got_nmask = True; - default_nmask = *interpret_addr2(nmask); - } -} - - -/**************************************************************************** - check if an IP is one of mine - **************************************************************************/ -BOOL ismyip(struct in_addr ip) -{ - struct interface *i; - for (i=local_interfaces;i;i=i->next) - if (ip_equal(i->ip,ip)) return True; - return False; -} - -/**************************************************************************** - check if a bcast is one of mine - **************************************************************************/ -BOOL ismybcast(struct in_addr bcast) -{ - struct interface *i; - for (i=local_interfaces;i;i=i->next) - if (ip_equal(i->bcast,bcast)) return True; - return False; -} - -/**************************************************************************** - how many interfaces do we have - **************************************************************************/ -int iface_count(void) -{ - int ret = 0; - struct interface *i; - - for (i=local_interfaces;i;i=i->next) - ret++; - return ret; -} - -/**************************************************************************** - return IP of the Nth interface - **************************************************************************/ -struct in_addr *iface_n_ip(int n) -{ - struct interface *i; - - for (i=local_interfaces;i && n;i=i->next) - n--; - - if (i) return &i->ip; - return NULL; -} - -static struct interface *iface_find(struct in_addr ip) -{ - struct interface *i; - if (zero_ip(ip)) return local_interfaces; - - for (i=local_interfaces;i;i=i->next) - if (same_net(i->ip,ip,i->nmask)) return i; - - return local_interfaces; -} - -/* these 3 functions return the ip/bcast/nmask for the interface - most appropriate for the given ip address */ - -struct in_addr *iface_bcast(struct in_addr ip) -{ - return(&iface_find(ip)->bcast); -} - -struct in_addr *iface_nmask(struct in_addr ip) -{ - return(&iface_find(ip)->nmask); -} - -struct in_addr *iface_ip(struct in_addr ip) -{ - return(&iface_find(ip)->ip); -} - - - diff --git a/source/lib/kanji.c b/source/lib/kanji.c deleted file mode 100644 index 5d7de87248d..00000000000 --- a/source/lib/kanji.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Kanji Extensions - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5 - and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11 - and add all jis codes sequence type at 1995.8.16 - Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp> -*/ - -#define _KANJI_C_ -#include "includes.h" - -/* coding system keep in */ -int coding_system = SJIS_CODE; - -/* jis si/so sequence */ -char jis_kso = JIS_KSO; -char jis_ksi = JIS_KSI; -char hex_tag = HEXTAG; - -/******************************************************************* - SHIFT JIS functions -********************************************************************/ -/******************************************************************* - search token from S1 separated any char of S2 - S1 contain SHIFT JIS chars. -********************************************************************/ -char *sj_strtok(char *s1, char *s2) -{ - static char *s = NULL; - char *q; - if (!s1) { - if (!s) { - return NULL; - } - s1 = s; - } - for (q = s1; *s1; ) { - if (is_shift_jis (*s1)) { - s1 += 2; - } else if (is_kana (*s1)) { - s1++; - } else { - char *p = strchr (s2, *s1); - if (p) { - if (s1 != q) { - s = s1 + 1; - *s1 = '\0'; - return q; - } - q = s1 + 1; - } - s1++; - } - } - s = NULL; - if (*q) { - return q; - } - return NULL; -} - -/******************************************************************* - search string S2 from S1 - S1 contain SHIFT JIS chars. -********************************************************************/ -char *sj_strstr(char *s1, char *s2) -{ - int len = strlen ((char *) s2); - if (!*s2) - return (char *) s1; - for (;*s1;) { - if (*s1 == *s2) { - if (strncmp (s1, s2, len) == 0) - return (char *) s1; - } - if (is_shift_jis (*s1)) { - s1 += 2; - } else { - s1++; - } - } - return 0; -} - -/******************************************************************* - Search char C from beginning of S. - S contain SHIFT JIS chars. -********************************************************************/ -char *sj_strchr (char *s, int c) -{ - for (; *s; ) { - if (*s == c) - return (char *) s; - if (is_shift_jis (*s)) { - s += 2; - } else { - s++; - } - } - return 0; -} - -/******************************************************************* - Search char C end of S. - S contain SHIFT JIS chars. -********************************************************************/ -char *sj_strrchr(char *s, int c) -{ - char *q; - - for (q = 0; *s; ) { - if (*s == c) { - q = (char *) s; - } - if (is_shift_jis (*s)) { - s += 2; - } else { - s++; - } - } - return q; -} - -/******************************************************************* - Code conversion -********************************************************************/ -/* convesion buffer */ -static char cvtbuf[1024]; - -/******************************************************************* - EUC <-> SJIS -********************************************************************/ -static int euc2sjis (int hi, int lo) -{ - if (hi & 1) - return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) | - (lo - (lo >= 0xe0 ? 0x60 : 0x61)); - else - return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2); -} - -static int sjis2euc (int hi, int lo) -{ - if (lo >= 0x9f) - return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2); - else - return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) | - (lo + (lo >= 0x7f ? 0x60 : 0x61)); -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to EUC codes - return converted buffer -********************************************************************/ -static char *sj_to_euc(char *from, BOOL overwrite) -{ - char *out; - char *save; - - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_shift_jis (*from)) { - int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (*from)) { - *out++ = euc_kana; - *out++ = *from++; - } else { - *out++ = *from++; - } - } - *out = 0; - if (overwrite) { - strcpy((char *) save, (char *) cvtbuf); - return (char *) save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain EUC codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *euc_to_sj(char *from, BOOL overwrite) -{ - char *out; - char *save; - - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_euc (*from)) { - int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_euc_kana (*from)) { - *out++ = from[1]; - from += 2; - } else { - *out++ = *from++; - } - } - *out = 0; - if (overwrite) { - strcpy(save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - JIS7,JIS8,JUNET <-> SJIS -********************************************************************/ -static int sjis2jis(int hi, int lo) -{ - if (lo >= 0x9f) - return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e); - else - return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) | - (lo - (lo >= 0x7f ? 0x20 : 0x1f)); -} - -static int jis2sjis(int hi, int lo) -{ - if (hi & 1) - return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) | - (lo + (lo >= 0x60 ? 0x20 : 0x1f)); - else - return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e); -} - -/******************************************************************* - Convert FROM contain JIS codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *jis8_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - } - } - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to JIS codes - return converted buffer -********************************************************************/ -static char *sj_to_jis8(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_kso; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN/KANA */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANJI: /* to ROMAN/KANA */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain 7 bits JIS codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *jis7_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else if (is_so (*from)) { - shifted = _KJ_KANA; /* to KANA */ - from++; - } else if (is_si (*from)) { - shifted = _KJ_ROMAN; /* to ROMAN */ - from++; - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - case _KJ_KANA: - *out++ = ((int) from[0]) + 0x80; - break; - } - } - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to 7 bits JIS codes - return converted buffer -********************************************************************/ -static char *sj_to_jis7(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN and through down */ - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_kso; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (from[0])) { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - case _KJ_ROMAN: /* to KANA */ - *out++ = jis_so; - shifted = _KJ_KANA; - break; - } - *out++ = ((int) *from++) - 0x80; - } else { - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN */ - shifted = _KJ_ROMAN; - break; - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN */ - break; - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - break; - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *junet_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else if (is_juk1(from[1]) && is_juk2 (from[2])) { - shifted = _KJ_KANA; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - case _KJ_KANA: - *out++ = ((int) from[0]) + 0x80; - break; - } - } - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes - return converted buffer -********************************************************************/ -static char *sj_to_junet(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_KANA: - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_so2; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (from[0])) { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN */ - case _KJ_ROMAN: /* to KANA */ - *out++ = jis_esc; - *out++ = junet_kana1; - *out++ = junet_kana2; - shifted = _KJ_KANA; - break; - } - *out++ = ((int) *from++) - 0x80; - } else { - switch (shifted) { - case _KJ_KANA: - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_si2; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANA: - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_si2; - break; - } - *out = 0; - if (overwrite) { - strcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - HEX <-> SJIS -********************************************************************/ -/* ":xx" -> a byte */ -static char *hex_to_sj(char *from, BOOL overwrite) -{ - char *sp, *dp; - - sp = (char *) from; - dp = cvtbuf; - while (*sp) { - if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) { - *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2])); - sp += 3; - } else - *dp++ = *sp++; - } - *dp = '\0'; - if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - kanji/kana -> ":xx" -********************************************************************/ -static char *sj_to_hex(char *from, BOOL overwrite) -{ - unsigned char *sp, *dp; - - sp = (unsigned char*) from; - dp = (unsigned char*) cvtbuf; - while (*sp) { - if (is_kana(*sp)) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else - *dp++ = *sp++; - } - *dp = '\0'; - if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - kanji/kana -> ":xx" -********************************************************************/ -static char *sj_to_cap(char *from, BOOL overwrite) -{ - unsigned char *sp, *dp; - - sp = (unsigned char*) from; - dp = (unsigned char*) cvtbuf; - while (*sp) { - if (*sp >= 0x80) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else { - *dp++ = *sp++; - } - } - *dp = '\0'; - if (overwrite) { - strcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - sj to sj -********************************************************************/ -static char *sj_to_sj(char *from, BOOL overwrite) -{ - if (!overwrite) { - strcpy (cvtbuf, (char *) from); - return cvtbuf; - } else { - return (char *) from; - } -} - -/************************************************************************ - conversion: - _dos_to_unix _unix_to_dos -************************************************************************/ - -char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj; -char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj; - -static int setup_string_function(int codes) -{ - switch (codes) { - default: - case SJIS_CODE: - _dos_to_unix = sj_to_sj; - _unix_to_dos = sj_to_sj; - - break; - - case EUC_CODE: - _dos_to_unix = sj_to_euc; - _unix_to_dos = euc_to_sj; - break; - - case JIS7_CODE: - _dos_to_unix = sj_to_jis7; - _unix_to_dos = jis7_to_sj; - break; - - case JIS8_CODE: - _dos_to_unix = sj_to_jis8; - _unix_to_dos = jis8_to_sj; - break; - - case JUNET_CODE: - _dos_to_unix = sj_to_junet; - _unix_to_dos = junet_to_sj; - break; - - case HEX_CODE: - _dos_to_unix = sj_to_hex; - _unix_to_dos = hex_to_sj; - break; - - case CAP_CODE: - _dos_to_unix = sj_to_cap; - _unix_to_dos = hex_to_sj; - break; - } - return codes; -} - -/* - * Interpret coding system. - */ -int interpret_coding_system(char *str, int def) -{ - int codes = def; - - if (strequal (str, "sjis")) { - codes = SJIS_CODE; - } else if (strequal (str, "euc")) { - codes = EUC_CODE; - } else if (strequal (str, "cap")) { - codes = CAP_CODE; - hex_tag = HEXTAG; - } else if (strequal (str, "hex")) { - codes = HEX_CODE; - hex_tag = HEXTAG; - } else if (strncasecmp (str, "hex", 3)) { - codes = HEX_CODE; - hex_tag = (str[3] ? str[3] : HEXTAG); - } else if (strequal (str, "j8bb")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "j8bj") || strequal (str, "jis8")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "j8bh")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "j8@b")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "j8@j")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "j8@h")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } else if (strequal (str, "j7bb")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "j7bj") || strequal (str, "jis7")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "j7bh")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "j7@b")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "j7@j")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "j7@h")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } else if (strequal (str, "jubb")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "jubj") || strequal (str, "junet")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "jubh")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "ju@b")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "ju@j")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "ju@h")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } - return setup_string_function (codes); -} diff --git a/source/lib/md4.c b/source/lib/md4.c deleted file mode 100644 index 1c9c2e6ecd5..00000000000 --- a/source/lib/md4.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - a implementation of MD4 designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -/* NOTE: This code makes no attempt to be fast! - - It assumes that a int is at least 32 bits long -*/ - -typedef unsigned int uint32; - -static uint32 A, B, C, D; - -static uint32 F(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | ((~X)&Z); -} - -static uint32 G(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | (X&Z) | (Y&Z); -} - -static uint32 H(uint32 X, uint32 Y, uint32 Z) -{ - return X^Y^Z; -} - -static uint32 lshift(uint32 x, int s) -{ - x &= 0xFFFFFFFF; - return ((x<<s)&0xFFFFFFFF) | (x>>(32-s)); -} - -#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) - -/* this applies md4 to 64 byte chunks */ -static void mdfour64(uint32 *M) -{ - int j; - uint32 AA, BB, CC, DD; - uint32 X[16]; - - for (j=0;j<16;j++) - X[j] = M[j]; - - AA = A; BB = B; CC = C; DD = D; - - ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); - ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); - ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); - ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); - ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); - ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); - ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); - ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); - - ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); - ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); - ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); - ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); - ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); - ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); - ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); - ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); - - ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); - ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); - ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); - ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); - ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); - ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); - ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); - ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); - - A += AA; B += BB; C += CC; D += DD; - - A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; - - for (j=0;j<16;j++) - X[j] = 0; -} - -static void copy64(uint32 *M, unsigned char *in) -{ - int i; - - for (i=0;i<16;i++) - M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | - (in[i*4+1]<<8) | (in[i*4+0]<<0); -} - -static void copy4(unsigned char *out,uint32 x) -{ - out[0] = x&0xFF; - out[1] = (x>>8)&0xFF; - out[2] = (x>>16)&0xFF; - out[3] = (x>>24)&0xFF; -} - -/* produce a md4 message digest from data of length n bytes */ -void mdfour(unsigned char *out, unsigned char *in, int n) -{ - unsigned char buf[128]; - uint32 M[16]; - uint32 b = n * 8; - int i; - - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - - while (n > 64) { - copy64(M, in); - mdfour64(M); - in += 64; - n -= 64; - } - - for (i=0;i<128;i++) - buf[i] = 0; - memcpy(buf, in, n); - buf[n] = 0x80; - - if (n <= 55) { - copy4(buf+56, b); - copy64(M, buf); - mdfour64(M); - } else { - copy4(buf+120, b); - copy64(M, buf); - mdfour64(M); - copy64(M, buf+64); - mdfour64(M); - } - - for (i=0;i<128;i++) - buf[i] = 0; - copy64(M, buf); - - copy4(out, A); - copy4(out+4, B); - copy4(out+8, C); - copy4(out+12, D); - - A = B = C = D = 0; -} - - diff --git a/source/lib/replace.c b/source/lib/replace.c deleted file mode 100644 index 67c18a15237..00000000000 --- a/source/lib/replace.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - replacement routines for broken systems - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -extern int DEBUGLEVEL; - - - void replace_dummy(void) -{} - -#ifdef REPLACE_STRLEN -/**************************************************************************** -a replacement strlen() that returns int for solaris -****************************************************************************/ - int Strlen(char *s) -{ - int ret=0; - if (!s) return(0); - while (*s++) ret++; - return(ret); -} -#endif - -#ifdef NO_FTRUNCATE - /******************************************************************* -ftruncate for operating systems that don't have it -********************************************************************/ - int ftruncate(int f,long l) -{ - struct flock fl; - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = l; - fl.l_type = F_WRLCK; - return fcntl(f, F_FREESP, &fl); -} -#endif - - -#ifdef REPLACE_STRSTR -/**************************************************************************** -Mips version of strstr doesn't seem to work correctly. -There is a #define in includes.h to redirect calls to this function. -****************************************************************************/ -char *Strstr(char *s, char *p) -{ - int len = strlen(p); - - while ( *s != '\0' ) { - if ( strncmp(s, p, len) == 0 ) - return s; - s++; - } - - return NULL; -} -#endif /* REPLACE_STRSTR */ - - -#ifdef REPLACE_MKTIME -/******************************************************************* -a mktime() replacement for those who don't have it - contributed by -C.A. Lademann <cal@zls.com> -********************************************************************/ -#define MINUTE 60 -#define HOUR 60*MINUTE -#define DAY 24*HOUR -#define YEAR 365*DAY -time_t Mktime(struct tm *t) -{ - struct tm *u; - time_t epoch = 0; - int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - y, m, i; - - if(t->tm_year < 70) - return((time_t)-1); - - epoch = (t->tm_year - 70) * YEAR + - (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY; - - y = t->tm_year; - m = 0; - - for(i = 0; i < t->tm_mon; i++) { - epoch += mon [m] * DAY; - if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) - epoch += DAY; - - if(++m > 11) { - m = 0; - y++; - } - } - - epoch += (t->tm_mday - 1) * DAY; - epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; - - if((u = localtime(&epoch)) != NULL) { - t->tm_sec = u->tm_sec; - t->tm_min = u->tm_min; - t->tm_hour = u->tm_hour; - t->tm_mday = u->tm_mday; - t->tm_mon = u->tm_mon; - t->tm_year = u->tm_year; - t->tm_wday = u->tm_wday; - t->tm_yday = u->tm_yday; - t->tm_isdst = u->tm_isdst; -#ifndef NO_TM_NAME - memcpy(t->tm_name, u->tm_name, LTZNMAX); -#endif - } - - return(epoch); -} -#endif /* REPLACE_MKTIME */ - - - -#ifdef REPLACE_RENAME -/* Rename a file. (from libiberty in GNU binutils) */ - int rename (zfrom, zto) - const char *zfrom; - const char *zto; -{ - if (link (zfrom, zto) < 0) - { - if (errno != EEXIST) - return -1; - if (unlink (zto) < 0 - || link (zfrom, zto) < 0) - return -1; - } - return unlink (zfrom); -} -#endif - - -#ifdef REPLACE_INNETGR -/* - * Search for a match in a netgroup. This replaces it on broken systems. - */ -int InNetGr(char *group,char *host,char *user,char *dom) -{ - char *hst, *usr, *dm; - - setnetgrent(group); - while (getnetgrent(&hst, &usr, &dm)) - if (((host == 0) || (hst == 0) || !strcmp(host, hst)) && - ((user == 0) || (usr == 0) || !strcmp(user, usr)) && - ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) { - endnetgrent(); - return (1); - } - endnetgrent(); - return (0); -} -#endif - - - -#ifdef NO_INITGROUPS -#include <sys/types.h> -#include <limits.h> -#include <grp.h> - -#ifndef NULL -#define NULL (void *)0 -#endif - -/**************************************************************************** - some systems don't have an initgroups call -****************************************************************************/ - int initgroups(char *name,gid_t id) -{ -#ifdef NO_SETGROUPS - /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ - return(0); -#else - gid_t grouplst[NGROUPS_MAX]; - int i,j; - struct group *g; - char *gr; - - grouplst[0] = id; - i = 1; - while (i < NGROUPS_MAX && - ((g = (struct group *)getgrent()) != (struct group *)NULL)) - { - if (g->gr_gid == id) - continue; - j = 0; - gr = g->gr_mem[0]; - while (gr && (*gr != (char)NULL)) { - if (strcmp(name,gr) == 0) { - grouplst[i] = g->gr_gid; - i++; - gr = (char *)NULL; - break; - } - gr = g->gr_mem[++j]; - } - } - endgrent(); - return(setgroups(i,grouplst)); -#endif -} -#endif - - -#if (defined(SecureWare) && defined(SCO)) -/* This is needed due to needing the nap() function but we don't want - to include the Xenix libraries since that will break other things... - BTW: system call # 0x0c28 is the same as calling nap() */ -long nap(long milliseconds) { - return syscall(0x0c28, milliseconds); -} -#endif - - - -#if WRAP_MALLOC - -/* undo the wrapping temporarily */ -#undef malloc -#undef realloc -#undef free - -/**************************************************************************** -wrapper for malloc() to catch memory errors -****************************************************************************/ -void *malloc_wrapped(int size,char *file,int line) -{ -#ifdef xx_old_malloc - void *res = xx_old_malloc(size); -#else - void *res = malloc(size); -#endif - DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", - file,line, - size,(unsigned int)res)); - return(res); -} - -/**************************************************************************** -wrapper for realloc() to catch memory errors -****************************************************************************/ -void *realloc_wrapped(void *ptr,int size,char *file,int line) -{ -#ifdef xx_old_realloc - void *res = xx_old_realloc(ptr,size); -#else - void *res = realloc(ptr,size); -#endif - DEBUG(3,("Realloc\n")); - DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", - file,line, - (unsigned int)ptr)); - DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", - file,line, - size,(unsigned int)res)); - return(res); -} - -/**************************************************************************** -wrapper for free() to catch memory errors -****************************************************************************/ -void free_wrapped(void *ptr,char *file,int line) -{ -#ifdef xx_old_free - xx_old_free(ptr); -#else - free(ptr); -#endif - DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", - file,line,(unsigned int)ptr)); - return; -} - -/* and re-do the define for spots lower in this file */ -#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__) -#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__) -#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__) - -#endif - - -#if WRAP_MEMCPY -#undef memcpy -/******************************************************************* -a wrapper around memcpy for diagnostic purposes -********************************************************************/ -void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line) -{ - if (l>64 && (((int)d)%4) != (((int)s)%4)) - DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line)); -#ifdef xx_old_memcpy - return(xx_old_memcpy(d,s,l)); -#else - return(memcpy(d,s,l)); -#endif -} -#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__) -#endif - diff --git a/source/lib/system.c b/source/lib/system.c deleted file mode 100644 index fe8e8004d04..00000000000 --- a/source/lib/system.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Samba system utilities - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -extern int DEBUGLEVEL; - -/* - The idea is that this file will eventually have wrappers around all - important system calls in samba. The aims are: - - - to enable easier porting by putting OS dependent stuff in here - - - to allow for hooks into other "pseudo-filesystems" - - - to allow easier integration of things like the japanese extensions - - - to support the philosophy of Samba to expose the features of - the OS within the SMB model. In general whatever file/printer/variable - expansions/etc make sense to the OS should be acceptable to Samba. -*/ - - -/******************************************************************* -this replaces the normal select() system call -return if some data has arrived on one of the file descriptors -return -1 means error -********************************************************************/ -#ifdef NO_SELECT -static int pollfd(int fd) -{ - int r=0; - -#ifdef HAS_RDCHK - r = rdchk(fd); -#elif defined(TCRDCHK) - (void)ioctl(fd, TCRDCHK, &r); -#else - (void)ioctl(fd, FIONREAD, &r); -#endif - - return(r); -} - -int sys_select(fd_set *fds,struct timeval *tval) -{ - fd_set fds2; - int counter=0; - int found=0; - - FD_ZERO(&fds2); - - while (1) - { - int i; - for (i=0;i<255;i++) { - if (FD_ISSET(i,fds) && pollfd(i)>0) { - found++; - FD_SET(i,&fds2); - } - } - - if (found) { - memcpy((void *)fds,(void *)&fds2,sizeof(fds2)); - return(found); - } - - if (tval && tval->tv_sec < counter) return(0); - sleep(1); - counter++; - } -} - -#else -int sys_select(fd_set *fds,struct timeval *tval) -{ - struct timeval t2; - int selrtn; - - do { - if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2)); - errno = 0; - selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL); - } while (selrtn<0 && errno == EINTR); - - return(selrtn); -} -#endif - - -/******************************************************************* -just a unlink wrapper -********************************************************************/ -int sys_unlink(char *fname) -{ - return(unlink(dos_to_unix(fname,False))); -} - - -/******************************************************************* -a simple open() wrapper -********************************************************************/ -int sys_open(char *fname,int flags,int mode) -{ - return(open(dos_to_unix(fname,False),flags,mode)); -} - - -/******************************************************************* -a simple opendir() wrapper -********************************************************************/ -DIR *sys_opendir(char *dname) -{ - return(opendir(dos_to_unix(dname,False))); -} - - -/******************************************************************* -and a stat() wrapper -********************************************************************/ -int sys_stat(char *fname,struct stat *sbuf) -{ - return(stat(dos_to_unix(fname,False),sbuf)); -} - -/******************************************************************* -The wait() calls vary between systems -********************************************************************/ -int sys_waitpid(pid_t pid,int *status,int options) -{ -#ifdef USE_WAITPID - return waitpid(pid,status,options); -#else /* USE_WAITPID */ - return wait4(pid, status, options, NULL); -#endif /* USE_WAITPID */ -} - -/******************************************************************* -don't forget lstat() -********************************************************************/ -int sys_lstat(char *fname,struct stat *sbuf) -{ - return(lstat(dos_to_unix(fname,False),sbuf)); -} - - -/******************************************************************* -mkdir() gets a wrapper -********************************************************************/ -int sys_mkdir(char *dname,int mode) -{ - return(mkdir(dos_to_unix(dname,False),mode)); -} - - -/******************************************************************* -do does rmdir() -********************************************************************/ -int sys_rmdir(char *dname) -{ - return(rmdir(dos_to_unix(dname,False))); -} - - -/******************************************************************* -I almost forgot chdir() -********************************************************************/ -int sys_chdir(char *dname) -{ - return(chdir(dos_to_unix(dname,False))); -} - - -/******************************************************************* -now for utime() -********************************************************************/ -int sys_utime(char *fname,struct utimbuf *times) -{ - return(utime(dos_to_unix(fname,False),times)); -} - -/********************************************************* -for rename across filesystems Patch from Warren Birnbaum -<warrenb@hpcvscdp.cv.hp.com> -**********************************************************/ - -static int copy_reg(char *source, const char *dest) -{ - struct stat source_stats; - int ifd; - int full_write(); - int safe_read(); - int ofd; - char *buf; - int len; /* Number of bytes read into `buf'. */ - - lstat (source, &source_stats); - if (!S_ISREG (source_stats.st_mode)) - { - return 1; - } - - if (unlink (dest) && errno != ENOENT) - { - return 1; - } - - if((ifd = open (source, O_RDONLY, 0)) < 0) - { - return 1; - } - if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) - { - close (ifd); - return 1; - } - - if((buf = malloc( COPYBUF_SIZE )) == NULL) - { - close (ifd); - close (ofd); - unlink (dest); - return 1; - } - - while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0) - { - if (write_data(ofd, buf, len) < 0) - { - close (ifd); - close (ofd); - unlink (dest); - free(buf); - return 1; - } - } - free(buf); - if (len < 0) - { - close (ifd); - close (ofd); - unlink (dest); - return 1; - } - - if (close (ifd) < 0) - { - close (ofd); - return 1; - } - if (close (ofd) < 0) - { - return 1; - } - - /* chown turns off set[ug]id bits for non-root, - so do the chmod last. */ - - /* Try to copy the old file's modtime and access time. */ - { - struct utimbuf tv; - - tv.actime = source_stats.st_atime; - tv.modtime = source_stats.st_mtime; - if (utime (dest, &tv)) - { - return 1; - } - } - - /* Try to preserve ownership. For non-root it might fail, but that's ok. - But root probably wants to know, e.g. if NFS disallows it. */ - if (chown (dest, source_stats.st_uid, source_stats.st_gid) - && (errno != EPERM)) - { - return 1; - } - - if (chmod (dest, source_stats.st_mode & 07777)) - { - return 1; - } - unlink (source); - return 0; -} - -/******************************************************************* -for rename() -********************************************************************/ -int sys_rename(char *from, char *to) -{ - int rcode; - pstring zfrom, zto; - - pstrcpy (zfrom, dos_to_unix (from, False)); - pstrcpy (zto, dos_to_unix (to, False)); - rcode = rename (zfrom, zto); - - if (errno == EXDEV) - { - /* Rename across filesystems needed. */ - rcode = copy_reg (zfrom, zto); - } - return rcode; -} - -/******************************************************************* -for chmod -********************************************************************/ -int sys_chmod(char *fname,int mode) -{ - return(chmod(dos_to_unix(fname,False),mode)); -} - -/******************************************************************* -for getwd -********************************************************************/ -char *sys_getwd(char *s) -{ - char *wd; -#ifdef USE_GETCWD - wd = (char *) getcwd (s, sizeof (pstring)); -#else - wd = (char *) getwd (s); -#endif - if (wd) - unix_to_dos (wd, True); - return wd; -} - -/******************************************************************* -chown isn't used much but OS/2 doesn't have it -********************************************************************/ -int sys_chown(char *fname,int uid,int gid) -{ -#ifdef NO_CHOWN - DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid)); -#else - return(chown(fname,uid,gid)); -#endif -} - -/******************************************************************* -os/2 also doesn't have chroot -********************************************************************/ -int sys_chroot(char *dname) -{ -#ifdef NO_CHROOT - DEBUG(1,("Warning - chroot(%s) not done\n",dname)); -#else - return(chroot(dname)); -#endif -} - -/************************************************************************** -A wrapper for gethostbyname() that tries avoids looking up hostnames -in the root domain, which can cause dial-on-demand links to come up for no -apparent reason. -****************************************************************************/ -struct hostent *sys_gethostbyname(char *name) -{ -#ifdef REDUCE_ROOT_DNS_LOOKUPS - char query[256], hostname[256]; - char *domain; - - /* Does this name have any dots in it? If so, make no change */ - - if (strchr(name, '.')) - return(gethostbyname(name)); - - /* Get my hostname, which should have domain name - attached. If not, just do the gethostname on the - original string. - */ - - gethostname(hostname, sizeof(hostname) - 1); - hostname[sizeof(hostname) - 1] = 0; - if ((domain = strchr(hostname, '.')) == NULL) - return(gethostbyname(name)); - - /* Attach domain name to query and do modified query. - If names too large, just do gethostname on the - original string. - */ - - if((strlen(name) + strlen(domain)) >= sizeof(query)) - return(gethostbyname(name)); - - sprintf(query, "%s%s", name, domain); - return(gethostbyname(query)); -#else /* REDUCE_ROOT_DNS_LOOKUPS */ - return(gethostbyname(name)); -#endif /* REDUCE_ROOT_DNS_LOOKUPS */ -} - diff --git a/source/lib/time.c b/source/lib/time.c deleted file mode 100644 index 4f688d2214a..00000000000 --- a/source/lib/time.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - time handling functions - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* - This stuff was largely rewritten by Paul Eggert <eggert@twinsun.com> - in May 1996 - */ - - -int serverzone=0; -int extra_time_offset = 0; - -extern int DEBUGLEVEL; - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef TIME_T_MIN -#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \ - : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) -#endif -#ifndef TIME_T_MAX -#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) -#endif - - - -/******************************************************************* -a gettimeofday wrapper -********************************************************************/ -void GetTimeOfDay(struct timeval *tval) -{ -#ifdef GETTIMEOFDAY1 - gettimeofday(tval); -#else - gettimeofday(tval,NULL); -#endif -} - -#define TM_YEAR_BASE 1900 - -/******************************************************************* -yield the difference between *A and *B, in seconds, ignoring leap seconds -********************************************************************/ -static int tm_diff(struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (TM_YEAR_BASE - 1); - int by = b->tm_year + (TM_YEAR_BASE - 1); - int intervening_leap_days = - (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400); - int years = ay - by; - int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday); - int hours = 24*days + (a->tm_hour - b->tm_hour); - int minutes = 60*hours + (a->tm_min - b->tm_min); - int seconds = 60*minutes + (a->tm_sec - b->tm_sec); - return seconds; -} - -/******************************************************************* - return the UTC offset in seconds west of UTC - ******************************************************************/ -static int TimeZone(time_t t) -{ - struct tm tm_utc = *(gmtime(&t)); - return tm_diff(&tm_utc,localtime(&t)); -} - - -/******************************************************************* -init the time differences -********************************************************************/ -void TimeInit(void) -{ - serverzone = TimeZone(time(NULL)); - DEBUG(4,("Serverzone is %d\n",serverzone)); -} - - -/******************************************************************* -return the same value as TimeZone, but it should be more efficient. - -We keep a table of DST offsets to prevent calling localtime() on each -call of this function. This saves a LOT of time on many unixes. - -Updated by Paul Eggert <eggert@twinsun.com> -********************************************************************/ -static int TimeZoneFaster(time_t t) -{ - static struct dst_table {time_t start,end; int zone;} *dst_table = NULL; - static int table_size = 0; - int i; - int zone = 0; - - if (t == 0) t = time(NULL); - - /* Tunis has a 8 day DST region, we need to be careful ... */ -#define MAX_DST_WIDTH (365*24*60*60) -#define MAX_DST_SKIP (7*24*60*60) - - for (i=0;i<table_size;i++) - if (t >= dst_table[i].start && t <= dst_table[i].end) break; - - if (i<table_size) { - zone = dst_table[i].zone; - } else { - time_t low,high; - - zone = TimeZone(t); - dst_table = (struct dst_table *)Realloc(dst_table, - sizeof(dst_table[0])*(i+1)); - if (!dst_table) { - table_size = 0; - } else { - table_size++; - - dst_table[i].zone = zone; - dst_table[i].start = dst_table[i].end = t; - - /* no entry will cover more than 6 months */ - low = t - MAX_DST_WIDTH/2; - if (t < low) - low = TIME_T_MIN; - - high = t + MAX_DST_WIDTH/2; - if (high < t) - high = TIME_T_MAX; - - /* widen the new entry using two bisection searches */ - while (low+60*60 < dst_table[i].start) { - if (dst_table[i].start - low > MAX_DST_SKIP*2) - t = dst_table[i].start - MAX_DST_SKIP; - else - t = low + (dst_table[i].start-low)/2; - if (TimeZone(t) == zone) - dst_table[i].start = t; - else - low = t; - } - - while (high-60*60 > dst_table[i].end) { - if (high - dst_table[i].end > MAX_DST_SKIP*2) - t = dst_table[i].end + MAX_DST_SKIP; - else - t = high - (high-dst_table[i].end)/2; - if (TimeZone(t) == zone) - dst_table[i].end = t; - else - high = t; - } -#if 0 - DEBUG(1,("Added DST entry from %s ", - asctime(localtime(&dst_table[i].start)))); - DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)), - dst_table[i].zone)); -#endif - } - } - return zone; -} - -/**************************************************************************** - return the UTC offset in seconds west of UTC, adjusted for extra time offset - **************************************************************************/ -int TimeDiff(time_t t) -{ - return TimeZoneFaster(t) + 60*extra_time_offset; -} - - -/**************************************************************************** - return the UTC offset in seconds west of UTC, adjusted for extra time - offset, for a local time value. If ut = lt + LocTimeDiff(lt), then - lt = ut - TimeDiff(ut), but the converse does not necessarily hold near - daylight savings transitions because some local times are ambiguous. - LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions. - +**************************************************************************/ -static int LocTimeDiff(time_t lte) -{ - time_t lt = lte - 60*extra_time_offset; - int d = TimeZoneFaster(lt); - time_t t = lt + d; - - /* if overflow occurred, ignore all the adjustments so far */ - if (((lte < lt) ^ (extra_time_offset < 0)) | ((t < lt) ^ (d < 0))) - t = lte; - - /* now t should be close enough to the true UTC to yield the right answer */ - return TimeDiff(t); -} - - -/**************************************************************************** -try to optimise the localtime call, it can be quite expenive on some machines -****************************************************************************/ -struct tm *LocalTime(time_t *t) -{ - time_t t2 = *t; - - t2 -= TimeDiff(t2); - - return(gmtime(&t2)); -} - - -#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60)) - -/**************************************************************************** -interpret an 8 byte "filetime" structure to a time_t -It's originally in "100ns units since jan 1st 1601" - -It appears to be kludge-GMT (at least for file listings). This means -its the GMT you get by taking a localtime and adding the -serverzone. This is NOT the same as GMT in some cases. This routine -converts this to real GMT. -****************************************************************************/ -time_t interpret_long_date(char *p) -{ - double d; - time_t ret; - uint32 tlow,thigh; - tlow = IVAL(p,0); - thigh = IVAL(p,4); - - if (thigh == 0) return(0); - - d = ((double)thigh)*4.0*(double)(1<<30); - d += (tlow&0xFFF00000); - d *= 1.0e-7; - - /* now adjust by 369 years to make the secs since 1970 */ - d -= TIME_FIXUP_CONSTANT; - - if (!(TIME_T_MIN <= d && d <= TIME_T_MAX)) - return(0); - - ret = (time_t)(d+0.5); - - /* this takes us from kludge-GMT to real GMT */ - ret -= serverzone; - ret += LocTimeDiff(ret); - - return(ret); -} - - -/**************************************************************************** -put a 8 byte filetime from a time_t -This takes real GMT as input and converts to kludge-GMT -****************************************************************************/ -void put_long_date(char *p,time_t t) -{ - uint32 tlow,thigh; - double d; - - if (t==0) { - SIVAL(p,0,0); SIVAL(p,4,0); - return; - } - - /* this converts GMT to kludge-GMT */ - t -= TimeDiff(t) - serverzone; - - d = (double) (t); - - d += TIME_FIXUP_CONSTANT; - - d *= 1.0e7; - - thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); - tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30)); - - SIVAL(p,0,tlow); - SIVAL(p,4,thigh); -} - - -/**************************************************************************** -check if it's a null mtime -****************************************************************************/ -static BOOL null_mtime(time_t mtime) -{ - if (mtime == 0 || mtime == 0xFFFFFFFF || mtime == (time_t)-1) - return(True); - return(False); -} - -/******************************************************************* - create a 16 bit dos packed date -********************************************************************/ -static uint16 make_dos_date1(time_t unixdate,struct tm *t) -{ - uint16 ret=0; - ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); - ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); - return(ret); -} - -/******************************************************************* - create a 16 bit dos packed time -********************************************************************/ -static uint16 make_dos_time1(time_t unixdate,struct tm *t) -{ - uint16 ret=0; - ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3)); - ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); - return(ret); -} - -/******************************************************************* - create a 32 bit dos packed date/time from some parameters - This takes a GMT time and returns a packed localtime structure -********************************************************************/ -static uint32 make_dos_date(time_t unixdate) -{ - struct tm *t; - uint32 ret=0; - - t = LocalTime(&unixdate); - - ret = make_dos_date1(unixdate,t); - ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t); - - return(ret); -} - -/******************************************************************* -put a dos date into a buffer (time/date format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void put_dos_date(char *buf,int offset,time_t unixdate) -{ - uint32 x = make_dos_date(unixdate); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos date into a buffer (date/time format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void put_dos_date2(char *buf,int offset,time_t unixdate) -{ - uint32 x = make_dos_date(unixdate); - x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos 32 bit "unix like" date into a buffer. This routine takes -GMT and converts it to LOCAL time before putting it (most SMBs assume -localtime for this sort of date) -********************************************************************/ -void put_dos_date3(char *buf,int offset,time_t unixdate) -{ - if (!null_mtime(unixdate)) - unixdate -= TimeDiff(unixdate); - SIVAL(buf,offset,unixdate); -} - -/******************************************************************* - interpret a 32 bit dos packed date/time to some parameters -********************************************************************/ -static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second) -{ - uint32 p0,p1,p2,p3; - - p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; - p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; - - *second = 2*(p0 & 0x1F); - *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); - *hour = (p1>>3)&0xFF; - *day = (p2&0x1F); - *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; - *year = ((p3>>1)&0xFF) + 80; -} - -/******************************************************************* - create a unix date (int GMT) from a dos date (which is actually in - localtime) -********************************************************************/ -time_t make_unix_date(void *date_ptr) -{ - uint32 dos_date=0; - struct tm t; - time_t ret; - - dos_date = IVAL(date_ptr,0); - - if (dos_date == 0) return(0); - - interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, - &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); - t.tm_isdst = -1; - - /* mktime() also does the local to GMT time conversion for us */ - ret = mktime(&t); - - return(ret); -} - -/******************************************************************* -like make_unix_date() but the words are reversed -********************************************************************/ -time_t make_unix_date2(void *date_ptr) -{ - uint32 x,x2; - - x = IVAL(date_ptr,0); - x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(&x,0,x2); - - return(make_unix_date((void *)&x)); -} - -/******************************************************************* - create a unix GMT date from a dos date in 32 bit "unix like" format - these generally arrive as localtimes, with corresponding DST - ******************************************************************/ -time_t make_unix_date3(void *date_ptr) -{ - time_t t = IVAL(date_ptr,0); - if (!null_mtime(t)) - t += LocTimeDiff(t); - return(t); -} - -/**************************************************************************** -set the time on a file -****************************************************************************/ -BOOL set_filetime(char *fname,time_t mtime) -{ - struct utimbuf times; - - if (null_mtime(mtime)) return(True); - - times.modtime = times.actime = mtime; - - if (sys_utime(fname,×)) { - DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); - } - - return(True); -} - - -/**************************************************************************** - return the date and time as a string -****************************************************************************/ -char *timestring(void ) -{ - static fstring TimeBuf; - time_t t = time(NULL); - struct tm *tm = LocalTime(&t); - -#ifdef NO_STRFTIME - fstrcpy(TimeBuf, asctime(tm)); -#elif defined(CLIX) || defined(CONVEX) - strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",tm); -#elif defined(AMPM) - strftime(TimeBuf,100,"%D %r",tm); -#elif defined(TZ_TIME) - { - int zone = TimeDiff(t); - int absZoneMinutes = (zone<0 ? -zone : zone) / 60; - size_t len = strftime(TimeBuf,sizeof(TimeBuf)-6,"%D %T",tm); - sprintf(TimeBuf+len," %c%02d%02d", - zone<0?'+':'-',absZoneMinutes/60,absZoneMinutes%60); - } -#else - strftime(TimeBuf,100,"%D %T",tm); -#endif - return(TimeBuf); -} - diff --git a/source/lib/ufc.c b/source/lib/ufc.c deleted file mode 100644 index 0fa5cfd3a0f..00000000000 --- a/source/lib/ufc.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - This bit of code was derived from the UFC-crypt package which - carries the following copyright - - Modified for use by Samba by Andrew Tridgell, October 1994 - - Note that this routine is only faster on some machines. Under Linux 1.1.51 - libc 4.5.26 I actually found this routine to be slightly slower. - - Under SunOS I found a huge speedup by using these routines - (a factor of 20 or so) - - Warning: I've had a report from Steve Kennedy <steve@gbnet.org> - that this crypt routine may sometimes get the wrong answer. Only - use UFC_CRYT if you really need it. - -*/ - -#ifdef UFC_CRYPT - -/* - * UFC-crypt: ultra fast crypt(3) implementation - * - * Copyright (C) 1991-1997, Free Software Foundation, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * @(#)crypt_util.c 2.31 02/08/92 - * - * Support routines - * - */ -#include "includes.h" - - -#ifndef long32 -#define long32 int32 -#endif - -#ifndef long64 -#define long64 int64 -#endif - -#ifndef ufc_long -#define ufc_long unsigned -#endif - -#ifndef _UFC_64_ -#define _UFC_32_ -#endif - -/* - * Permutation done once on the 56 bit - * key derived from the original 8 byte ASCII key. - */ -static int pc1[56] = { - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 -}; - -/* - * How much to rotate each 28 bit half of the pc1 permutated - * 56 bit key before using pc2 to give the i' key - */ -static int rots[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -/* - * Permutation giving the key - * of the i' DES round - */ -static int pc2[48] = { - 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 -}; - -/* - * The E expansion table which selects - * bits from the 32 bit intermediate result. - */ -static int esel[48] = { - 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 -}; -static int e_inverse[64]; - -/* - * Permutation done on the - * result of sbox lookups - */ -static int perm32[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 -}; - -/* - * The sboxes - */ -static int sbox[8][4][16]= { - { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, - { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, - { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, - { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } - }, - - { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, - { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, - { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, - { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } - }, - - { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, - { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, - { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, - { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } - }, - - { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, - { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, - { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, - { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } - }, - - { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, - { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, - { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, - { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } - }, - - { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, - { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, - { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, - { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } - }, - - { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, - { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, - { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, - { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } - }, - - { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, - { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, - { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, - { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } - } -}; - -/* - * This is the final - * permutation matrix - */ -static int final_perm[64] = { - 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 -}; - -/* - * The 16 DES keys in BITMASK format - */ -#ifdef _UFC_32_ -long32 _ufc_keytab[16][2]; -#endif - -#ifdef _UFC_64_ -long64 _ufc_keytab[16]; -#endif - - -#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') -#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') - -/* Macro to set a bit (0..23) */ -#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) ) - -/* - * sb arrays: - * - * Workhorses of the inner loop of the DES implementation. - * They do sbox lookup, shifting of this value, 32 bit - * permutation and E permutation for the next round. - * - * Kept in 'BITMASK' format. - */ - -#ifdef _UFC_32_ -long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; -static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; -#endif - -#ifdef _UFC_64_ -long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; -static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; -#endif - -/* - * eperm32tab: do 32 bit permutation and E selection - * - * The first index is the byte number in the 32 bit value to be permuted - * - second - is the value of this byte - * - third - selects the two 32 bit values - * - * The table is used and generated internally in init_des to speed it up - */ -static ufc_long eperm32tab[4][256][2]; - -/* - * do_pc1: permform pc1 permutation in the key schedule generation. - * - * The first index is the byte number in the 8 byte ASCII key - * - second - - the two 28 bits halfs of the result - * - third - selects the 7 bits actually used of each byte - * - * The result is kept with 28 bit per 32 bit with the 4 most significant - * bits zero. - */ -static ufc_long do_pc1[8][2][128]; - -/* - * do_pc2: permform pc2 permutation in the key schedule generation. - * - * The first index is the septet number in the two 28 bit intermediate values - * - second - - - septet values - * - * Knowledge of the structure of the pc2 permutation is used. - * - * The result is kept with 28 bit per 32 bit with the 4 most significant - * bits zero. - */ -static ufc_long do_pc2[8][128]; - -/* - * efp: undo an extra e selection and do final - * permutation giving the DES result. - * - * Invoked 6 bit a time on two 48 bit values - * giving two 32 bit longs. - */ -static ufc_long efp[16][64][2]; - -static unsigned char bytemask[8] = { - 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 -}; - -static ufc_long longmask[32] = { - 0x80000000, 0x40000000, 0x20000000, 0x10000000, - 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, - 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, - 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, - 0x00000008, 0x00000004, 0x00000002, 0x00000001 -}; - - -/* - * Silly rewrite of 'bzero'. I do so - * because some machines don't have - * bzero and some don't have memset. - */ - -static void clearmem(start, cnt) - char *start; - int cnt; - { while(cnt--) - *start++ = '\0'; - } - -static int initialized = 0; - -/* lookup a 6 bit value in sbox */ - -#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; - -/* - * Initialize unit - may be invoked directly - * by fcrypt users. - */ - -static void ufc_init_des() - { int comes_from_bit; - int bit, sg; - ufc_long j; - ufc_long mask1, mask2; - - /* - * Create the do_pc1 table used - * to affect pc1 permutation - * when generating keys - */ - for(bit = 0; bit < 56; bit++) { - comes_from_bit = pc1[bit] - 1; - mask1 = bytemask[comes_from_bit % 8 + 1]; - mask2 = longmask[bit % 28 + 4]; - for(j = 0; j < 128; j++) { - if(j & mask1) - do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; - } - } - - /* - * Create the do_pc2 table used - * to affect pc2 permutation when - * generating keys - */ - for(bit = 0; bit < 48; bit++) { - comes_from_bit = pc2[bit] - 1; - mask1 = bytemask[comes_from_bit % 7 + 1]; - mask2 = BITMASK(bit % 24); - for(j = 0; j < 128; j++) { - if(j & mask1) - do_pc2[comes_from_bit / 7][j] |= mask2; - } - } - - /* - * Now generate the table used to do combined - * 32 bit permutation and e expansion - * - * We use it because we have to permute 16384 32 bit - * longs into 48 bit in order to initialize sb. - * - * Looping 48 rounds per permutation becomes - * just too slow... - * - */ - - clearmem((char*)eperm32tab, sizeof(eperm32tab)); - - for(bit = 0; bit < 48; bit++) { - ufc_long mask1,comes_from; - - comes_from = perm32[esel[bit]-1]-1; - mask1 = bytemask[comes_from % 8]; - - for(j = 256; j--;) { - if(j & mask1) - eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); - } - } - - /* - * Create the sb tables: - * - * For each 12 bit segment of an 48 bit intermediate - * result, the sb table precomputes the two 4 bit - * values of the sbox lookups done with the two 6 - * bit halves, shifts them to their proper place, - * sends them through perm32 and finally E expands - * them so that they are ready for the next - * DES round. - * - */ - for(sg = 0; sg < 4; sg++) { - int j1, j2; - int s1, s2; - - for(j1 = 0; j1 < 64; j1++) { - s1 = s_lookup(2 * sg, j1); - for(j2 = 0; j2 < 64; j2++) { - ufc_long to_permute, inx; - - s2 = s_lookup(2 * sg + 1, j2); - to_permute = ((s1 << 4) | s2) << (24 - 8 * sg); - -#ifdef _UFC_32_ - inx = ((j1 << 6) | j2) << 1; - sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; - sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; -#endif -#ifdef _UFC_64_ - inx = ((j1 << 6) | j2); - sb[sg][inx] = - ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | - (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | - (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | - (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | - (long64)eperm32tab[3][(to_permute) & 0xff][1]; -#endif - } - } - } - - /* - * Create an inverse matrix for esel telling - * where to plug out bits if undoing it - */ - for(bit=48; bit--;) { - e_inverse[esel[bit] - 1 ] = bit; - e_inverse[esel[bit] - 1 + 32] = bit + 48; - } - - /* - * create efp: the matrix used to - * undo the E expansion and effect final permutation - */ - clearmem((char*)efp, sizeof efp); - for(bit = 0; bit < 64; bit++) { - int o_bit, o_long; - ufc_long word_value, mask1, mask2; - int comes_from_f_bit, comes_from_e_bit; - int comes_from_word, bit_within_word; - - /* See where bit i belongs in the two 32 bit long's */ - o_long = bit / 32; /* 0..1 */ - o_bit = bit % 32; /* 0..31 */ - - /* - * And find a bit in the e permutated value setting this bit. - * - * Note: the e selection may have selected the same bit several - * times. By the initialization of e_inverse, we only look - * for one specific instance. - */ - comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ - comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ - comes_from_word = comes_from_e_bit / 6; /* 0..15 */ - bit_within_word = comes_from_e_bit % 6; /* 0..5 */ - - mask1 = longmask[bit_within_word + 26]; - mask2 = longmask[o_bit]; - - for(word_value = 64; word_value--;) { - if(word_value & mask1) - efp[comes_from_word][word_value][o_long] |= mask2; - } - } - initialized++; - } - -/* - * Process the elements of the sb table permuting the - * bits swapped in the expansion by the current salt. - */ - -#ifdef _UFC_32_ -static void shuffle_sb(k, saltbits) - long32 *k; - ufc_long saltbits; - { ufc_long j; - long32 x; - for(j=4096; j--;) { - x = (k[0] ^ k[1]) & (long32)saltbits; - *k++ ^= x; - *k++ ^= x; - } - } -#endif - -#ifdef _UFC_64_ -static void shuffle_sb(k, saltbits) - long64 *k; - ufc_long saltbits; - { ufc_long j; - long64 x; - for(j=4096; j--;) { - x = ((*k >> 32) ^ *k) & (long64)saltbits; - *k++ ^= (x << 32) | x; - } - } -#endif - -/* - * Setup the unit for a new salt - * Hopefully we'll not see a new salt in each crypt call. - */ - -static unsigned char current_salt[3] = "&&"; /* invalid value */ -static ufc_long current_saltbits = 0; -static int direction = 0; - -static void setup_salt(char *s1) - { ufc_long i, j, saltbits; - unsigned char *s2 = (unsigned char *)s1; - - if(!initialized) - ufc_init_des(); - - if(s2[0] == current_salt[0] && s2[1] == current_salt[1]) - return; - current_salt[0] = s2[0]; current_salt[1] = s2[1]; - - /* - * This is the only crypt change to DES: - * entries are swapped in the expansion table - * according to the bits set in the salt. - */ - saltbits = 0; - for(i = 0; i < 2; i++) { - long c=ascii_to_bin(s2[i]); - if(c < 0 || c > 63) - c = 0; - for(j = 0; j < 6; j++) { - if((c >> j) & 0x1) - saltbits |= BITMASK(6 * i + j); - } - } - - /* - * Permute the sb table values - * to reflect the changed e - * selection table - */ - shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); - - current_saltbits = saltbits; - } - -static void ufc_mk_keytab(key) - char *key; - { ufc_long v1, v2, *k1; - int i; -#ifdef _UFC_32_ - long32 v, *k2 = &_ufc_keytab[0][0]; -#endif -#ifdef _UFC_64_ - long64 v, *k2 = &_ufc_keytab[0]; -#endif - - v1 = v2 = 0; k1 = &do_pc1[0][0][0]; - for(i = 8; i--;) { - v1 |= k1[*key & 0x7f]; k1 += 128; - v2 |= k1[*key++ & 0x7f]; k1 += 128; - } - - for(i = 0; i < 16; i++) { - k1 = &do_pc2[0][0]; - - v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); - v = k1[(v1 >> 21) & 0x7f]; k1 += 128; - v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; - v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; - v |= k1[(v1 ) & 0x7f]; k1 += 128; - -#ifdef _UFC_32_ - *k2++ = v; - v = 0; -#endif -#ifdef _UFC_64_ - v <<= 32; -#endif - - v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); - v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; - v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; - v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; - v |= k1[(v2 ) & 0x7f]; - - *k2++ = v; - } - - direction = 0; - } - -/* - * Undo an extra E selection and do final permutations - */ - -ufc_long *_ufc_dofinalperm(l1, l2, r1, r2) - ufc_long l1,l2,r1,r2; - { ufc_long v1, v2, x; - static ufc_long ary[2]; - - x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; - x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; - - v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; - - v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; - v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; - v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; - v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; - - v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; - v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; - v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; - v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; - - v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; - v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; - v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; - v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; - - v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; - v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; - v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; - v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; - - ary[0] = v1; ary[1] = v2; - return ary; - } - -/* - * crypt only: convert from 64 bit to 11 bit ASCII - * prefixing with the salt - */ - -static char *output_conversion(v1, v2, salt) - ufc_long v1, v2; - char *salt; - { static char outbuf[14]; - int i, s; - - outbuf[0] = salt[0]; - outbuf[1] = salt[1] ? salt[1] : salt[0]; - - for(i = 0; i < 5; i++) - outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f); - - s = (v2 & 0xf) << 2; - v2 = (v2 >> 2) | ((v1 & 0x3) << 30); - - for(i = 5; i < 10; i++) - outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f); - - outbuf[12] = bin_to_ascii(s); - outbuf[13] = 0; - - return outbuf; - } - -/* - * UNIX crypt function - */ - -ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); - -char *ufc_crypt(char *key,char *salt) - { ufc_long *s; - char ktab[9]; - - /* - * Hack DES tables according to salt - */ - setup_salt(salt); - - /* - * Setup key schedule - */ - clearmem(ktab, sizeof ktab); - StrnCpy(ktab, key, 8); - ufc_mk_keytab(ktab); - - /* - * Go for the 25 DES encryptions - */ - s = _ufc_doit((ufc_long)0, (ufc_long)0, - (ufc_long)0, (ufc_long)0, (ufc_long)25); - - /* - * And convert back to 6 bit ASCII - */ - return output_conversion(s[0], s[1], salt); - } - - -#ifdef _UFC_32_ - -/* - * 32 bit version - */ - -extern long32 _ufc_keytab[16][2]; -extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; - -#define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) - -static ufc_long *_ufc_doit(l1, l2, r1, r2, itr) - ufc_long l1, l2, r1, r2, itr; - { int i; - long32 s, *k; - - while(itr--) { - k = &_ufc_keytab[0][0]; - for(i=8; i--; ) { - s = *k++ ^ r1; - l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); - l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4); - s = *k++ ^ r2; - l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); - l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4); - - s = *k++ ^ l1; - r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); - r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4); - s = *k++ ^ l2; - r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); - r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4); - } - s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; - } - return _ufc_dofinalperm(l1, l2, r1, r2); - } - -#endif - -#ifdef _UFC_64_ - -/* - * 64 bit version - */ - -extern long64 _ufc_keytab[16]; -extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; - -#define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) - -static ufc_long *_ufc_doit(l1, l2, r1, r2, itr) - ufc_long l1, l2, r1, r2, itr; - { int i; - long64 l, r, s, *k; - - l = (((long64)l1) << 32) | ((long64)l2); - r = (((long64)r1) << 32) | ((long64)r2); - - while(itr--) { - k = &_ufc_keytab[0]; - for(i=8; i--; ) { - s = *k++ ^ r; - l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); - l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); - l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); - l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); - - s = *k++ ^ l; - r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); - r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); - r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); - r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); - } - s=l; l=r; r=s; - } - - l1 = l >> 32; l2 = l & 0xffffffff; - r1 = r >> 32; r2 = r & 0xffffffff; - return _ufc_dofinalperm(l1, l2, r1, r2); - } - -#endif - - -#else - int ufc_dummy_procedure(void) -{return 0;} -#endif diff --git a/source/lib/username.c b/source/lib/username.c deleted file mode 100644 index a9f64259916..00000000000 --- a/source/lib/username.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Username handling - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -extern int DEBUGLEVEL; - -/* internal functions - modified versions of the ones in password.c */ -static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (), int N); -static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (), int N); - -/**************************************************************************** -get a users home directory. tries as-is then lower case -****************************************************************************/ -char *get_home_dir(char *user) -{ - static struct passwd *pass; - - pass = Get_Pwnam(user,False); - - if (!pass) return(NULL); - return(pass->pw_dir); -} - - -/******************************************************************* -map a username from a dos name to a unix name by looking in the username -map -********************************************************************/ -void map_username(char *user) -{ - static int depth=0; - static BOOL initialised=False; - static fstring last_from,last_to; - FILE *f; - char *s; - char *mapfile = lp_username_map(); - if (!*mapfile || depth) return; - - if (!*user) return; - - if (!initialised) { - *last_from = *last_to = 0; - initialised = True; - } - - if (strequal(user,last_to)) return; - - if (strequal(user,last_from)) { - DEBUG(3,("Mapped user %s to %s\n",user,last_to)); - fstrcpy(user,last_to); - return; - } - - f = fopen(mapfile,"r"); - if (!f) { - DEBUG(0,("can't open username map %s\n",mapfile)); - return; - } - - DEBUG(4,("Scanning username map %s\n",mapfile)); - - depth++; - - for (; (s=fgets_slash(NULL,80,f)); free(s)) { - char *unixname = s; - char *dosname = strchr(unixname,'='); - - if (!dosname) continue; - *dosname++ = 0; - - while (isspace(*unixname)) unixname++; - if (!*unixname || strchr("#;",*unixname)) continue; - - { - int l = strlen(unixname); - while (l && isspace(unixname[l-1])) { - unixname[l-1] = 0; - l--; - } - } - - if (strchr(dosname,'*') || user_in_list(user,dosname)) { - DEBUG(3,("Mapped user %s to %s\n",user,unixname)); - StrnCpy(last_from,user,sizeof(last_from)-1); - sscanf(unixname,"%s",user); - StrnCpy(last_to,user,sizeof(last_to)-1); - } - } - - fclose(f); - - depth--; -} - -/**************************************************************************** -internals of Get_Pwnam wrapper -****************************************************************************/ -static struct passwd *_Get_Pwnam(char *s) -{ - struct passwd *ret; - - ret = getpwnam(s); - if (ret) - { -#ifdef GETPWANAM - struct passwd_adjunct *pwret; - pwret = getpwanam(s); - if (pwret) - { - free(ret->pw_passwd); - ret->pw_passwd = pwret->pwa_passwd; - } -#endif - - } - - return(ret); -} - - -/**************************************************************************** -a wrapper for getpwnam() that tries with all lower and all upper case -if the initial name fails. Also tried with first letter capitalised -Note that this changes user! -****************************************************************************/ -struct passwd *Get_Pwnam(char *user,BOOL allow_change) -{ - fstring user2; - int last_char; - int usernamelevel = lp_usernamelevel(); - - struct passwd *ret; - - if (!user || !(*user)) - return(NULL); - - StrnCpy(user2,user,sizeof(user2)-1); - - if (!allow_change) { - user = &user2[0]; - } - - map_username(user); - - ret = _Get_Pwnam(user); - if (ret) return(ret); - - strlower(user); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - strupper(user); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try with first letter capitalised */ - if (strlen(user) > 1) - strlower(user+1); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try with last letter capitalised */ - strlower(user); - last_char = strlen(user)-1; - user[last_char] = toupper(user[last_char]); - DEBUG(3, ("Trying username %s\n", user)); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try all combinations up to usernamelevel */ - strlower(user); - ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel); - if (ret) return(ret); - - if (allow_change) - fstrcpy(user,user2); - - return(NULL); -} - - -/**************************************************************************** -check if a user is in a user list -****************************************************************************/ -BOOL user_in_list(char *user,char *list) -{ - pstring tok; - char *p=list; - - while (next_token(&p,tok,LIST_SEP)) - { - if (strequal(user,tok)) - return(True); - -#ifdef NETGROUP - if (*tok == '@') - { - static char *mydomain = NULL; - if (mydomain == 0) - yp_get_default_domain(&mydomain); - - if(mydomain == 0) - { - DEBUG(5,("Unable to get default yp domain\n")); - } - else - { - - DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - user, mydomain, &tok[1])); - DEBUG(5,("innetgr is %s\n", - innetgr(&tok[1], (char *) 0, user, mydomain) - ? "TRUE" : "FALSE")); - - if (innetgr(&tok[1], (char *)0, user, mydomain)) - return (True); - } - } -#endif - - -#if HAVE_GETGRNAM - if (*tok == '@') - { - struct group *gptr; - char **member; - struct passwd *pass = Get_Pwnam(user,False); - - if (pass) { - gptr = getgrgid(pass->pw_gid); - if (gptr && strequal(gptr->gr_name,&tok[1])) - return(True); - } - - gptr = (struct group *)getgrnam(&tok[1]); - - if (gptr) - { - member = gptr->gr_mem; - while (member && *member) - { - if (strequal(*member,user)) - return(True); - member++; - } - } - } -#endif - } - return(False); -} - -/* The functions below have been taken from password.c and slightly modified */ -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(),int N) -{ - int len = strlen(s); - int i; - struct passwd *ret; - -#ifdef PASSWORD_LENGTH - len = MIN(len,PASSWORD_LENGTH); -#endif - - if (N <= 0 || offset >= len) - return(fn(s)); - - - for (i=offset;i<(len-(N-1));i++) - - { - char c = s[i]; - if (!islower(c)) continue; - s[i] = toupper(c); - ret = uname_string_combinations2(s,i+1,fn,N-1); - if(ret) return(ret); - s[i] = c; - } - return(NULL); -} - -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with up to N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(),int N) -{ - int n; - struct passwd *ret; - - for (n=1;n<=N;n++) - { - ret = uname_string_combinations2(s,0,fn,n); - if(ret) return(ret); - } - return(NULL); -} diff --git a/source/lib/util.c b/source/lib/util.c deleted file mode 100644 index 4e6bfb7054a..00000000000 --- a/source/lib/util.c +++ /dev/null @@ -1,4392 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Samba utility functions - Copyright (C) Andrew Tridgell 1992-1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -pstring scope = ""; - -int DEBUGLEVEL = 1; - -BOOL passive = False; - -int Protocol = PROTOCOL_COREPLUS; - -/* a default finfo structure to ensure all fields are sensible */ -file_info def_finfo = {-1,0,0,0,0,0,0,""}; - -/* these are some file handles where debug info will be stored */ -FILE *dbf = NULL; - -/* the client file descriptor */ -int Client = -1; - -/* the last IP received from */ -struct in_addr lastip; - -/* the last port received from */ -int lastport=0; - -/* this is used by the chaining code */ -int chain_size = 0; - -int trans_num = 0; - -/* - case handling on filenames -*/ -int case_default = CASE_LOWER; - -pstring debugf = ""; -int syslog_level; - -/* the following control case operations - they are put here so the - client can link easily */ -BOOL case_sensitive; -BOOL case_preserve; -BOOL use_mangled_map = False; -BOOL short_case_preserve; -BOOL case_mangle; - -fstring remote_machine=""; -fstring local_machine=""; -fstring remote_arch="UNKNOWN"; -static enum remote_arch_types ra_type = RA_UNKNOWN; -fstring remote_proto="UNKNOWN"; -pstring myhostname=""; -pstring user_socket_options=""; -pstring sesssetup_user=""; -pstring myname = ""; -fstring myworkgroup = ""; -char **my_netbios_names; - -int smb_read_error = 0; - -static BOOL stdout_logging = False; - -static char *filename_dos(char *path,char *buf); - -/******************************************************************* - get ready for syslog stuff - ******************************************************************/ -void setup_logging(char *pname,BOOL interactive) -{ -#ifdef SYSLOG - if (!interactive) { - char *p = strrchr(pname,'/'); - if (p) pname = p+1; -#ifdef LOG_DAEMON - openlog(pname, LOG_PID, LOG_DAEMON); -#else /* LOG_DAEMON - for old systems that have no facility codes. */ - openlog(pname, LOG_PID); -#endif /* LOG_DAEMON */ - } -#endif - if (interactive) { - stdout_logging = True; - dbf = stdout; - } -} - - -BOOL append_log=False; - - -/**************************************************************************** -reopen the log files -****************************************************************************/ -void reopen_logs(void) -{ - extern FILE *dbf; - pstring fname; - - if (DEBUGLEVEL > 0) - { - strcpy(fname,debugf); - if (lp_loaded() && (*lp_logfile())) - strcpy(fname,lp_logfile()); - - if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) - { - int oldumask = umask(022); - strcpy(debugf,fname); - if (dbf) fclose(dbf); - if (append_log) - dbf = fopen(debugf,"a"); - else - dbf = fopen(debugf,"w"); - if (dbf) setbuf(dbf,NULL); - umask(oldumask); - } - } - else - { - if (dbf) - { - fclose(dbf); - dbf = NULL; - } - } -} - - -/******************************************************************* -check if the log has grown too big -********************************************************************/ -static void check_log_size(void) -{ - static int debug_count=0; - int maxlog; - struct stat st; - - if (debug_count++ < 100 || getuid() != 0) return; - - maxlog = lp_max_log_size() * 1024; - if (!dbf || maxlog <= 0) return; - - if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) { - fclose(dbf); dbf = NULL; - reopen_logs(); - if (dbf && file_size(debugf) > maxlog) { - pstring name; - fclose(dbf); dbf = NULL; - sprintf(name,"%s.old",debugf); - sys_rename(debugf,name); - reopen_logs(); - } - } - debug_count=0; -} - - -/******************************************************************* -write an debug message on the debugfile. This is called by the DEBUG -macro -********************************************************************/ -#ifdef __STDC__ - int Debug1(char *format_str, ...) -{ -#else - int Debug1(va_alist) -va_dcl -{ - char *format_str; -#endif - va_list ap; - int old_errno = errno; - - if (stdout_logging) { -#ifdef __STDC__ - va_start(ap, format_str); -#else - va_start(ap); - format_str = va_arg(ap,char *); -#endif - vfprintf(dbf,format_str,ap); - va_end(ap); - errno = old_errno; - return(0); - } - -#ifdef SYSLOG - if (!lp_syslog_only()) -#endif - { - if (!dbf) { - int oldumask = umask(022); - dbf = fopen(debugf,"w"); - umask(oldumask); - if (dbf) { - setbuf(dbf,NULL); - } else { - errno = old_errno; - return(0); - } - } - } - -#ifdef SYSLOG - if (syslog_level < lp_syslog()) - { - /* - * map debug levels to syslog() priorities - * note that not all DEBUG(0, ...) calls are - * necessarily errors - */ - static int priority_map[] = { - LOG_ERR, /* 0 */ - LOG_WARNING, /* 1 */ - LOG_NOTICE, /* 2 */ - LOG_INFO, /* 3 */ - }; - int priority; - pstring msgbuf; - - if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) || - syslog_level < 0) - priority = LOG_DEBUG; - else - priority = priority_map[syslog_level]; - -#ifdef __STDC__ - va_start(ap, format_str); -#else - va_start(ap); - format_str = va_arg(ap,char *); -#endif - vsprintf(msgbuf, format_str, ap); - va_end(ap); - - msgbuf[255] = '\0'; - syslog(priority, "%s", msgbuf); - } -#endif - -#ifdef SYSLOG - if (!lp_syslog_only()) -#endif - { -#ifdef __STDC__ - va_start(ap, format_str); -#else - va_start(ap); - format_str = va_arg(ap,char *); -#endif - vfprintf(dbf,format_str,ap); - va_end(ap); - fflush(dbf); - } - - check_log_size(); - - errno = old_errno; - - return(0); -} - -/**************************************************************************** - find a suitable temporary directory. The result should be copied immediately - as it may be overwritten by a subsequent call - ****************************************************************************/ -char *tmpdir(void) -{ - char *p; - if ((p = getenv("TMPDIR"))) { - return p; - } - return "/tmp"; -} - - - -/**************************************************************************** -determine if a file descriptor is in fact a socket -****************************************************************************/ -BOOL is_a_socket(int fd) -{ - int v,l; - l = sizeof(int); - return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); -} - - -static char *last_ptr=NULL; - -/**************************************************************************** - Get the next token from a string, return False if none found - handles double-quotes. -Based on a routine by GJC@VILLAGE.COM. -Extensively modified by Andrew.Tridgell@anu.edu.au -****************************************************************************/ -BOOL next_token(char **ptr,char *buff,char *sep) -{ - char *s; - BOOL quoted; - - if (!ptr) ptr = &last_ptr; - if (!ptr) return(False); - - s = *ptr; - - /* default to simple separators */ - if (!sep) sep = " \t\n\r"; - - /* find the first non sep char */ - while(*s && strchr(sep,*s)) s++; - - /* nothing left? */ - if (! *s) return(False); - - /* copy over the token */ - for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++) - { - if (*s == '\"') - quoted = !quoted; - else - *buff++ = *s; - } - - *ptr = (*s) ? s+1 : s; - *buff = 0; - last_ptr = *ptr; - - return(True); -} - -/**************************************************************************** -Convert list of tokens to array; dependent on above routine. -Uses last_ptr from above - bit of a hack. -****************************************************************************/ -char **toktocliplist(int *ctok, char *sep) -{ - char *s=last_ptr; - int ictok=0; - char **ret, **iret; - - if (!sep) sep = " \t\n\r"; - - while(*s && strchr(sep,*s)) s++; - - /* nothing left? */ - if (!*s) return(NULL); - - do { - ictok++; - while(*s && (!strchr(sep,*s))) s++; - while(*s && strchr(sep,*s)) *s++=0; - } while(*s); - - *ctok=ictok; - s=last_ptr; - - if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL; - - while(ictok--) { - *iret++=s; - while(*s++); - while(!*s) s++; - } - - return ret; -} - -#ifndef HAVE_MEMMOVE -/******************************************************************* -safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have it's own memmove(). -this is not the fastest algorithm in town, but it will do for our -needs. -********************************************************************/ -void *MemMove(void *dest,void *src,int size) -{ - unsigned long d,s; - int i; - if (dest==src || !size) return(dest); - - d = (unsigned long)dest; - s = (unsigned long)src; - - if ((d >= (s+size)) || (s >= (d+size))) { - /* no overlap */ - memcpy(dest,src,size); - return(dest); - } - - if (d < s) - { - /* we can forward copy */ - if (s-d >= sizeof(int) && - !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=0;i<size;i++) idest[i] = isrc[i]; - } else { - /* simplest */ - char *cdest = (char *)dest; - char *csrc = (char *)src; - for (i=0;i<size;i++) cdest[i] = csrc[i]; - } - } - else - { - /* must backward copy */ - if (d-s >= sizeof(int) && - !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=size-1;i>=0;i--) idest[i] = isrc[i]; - } else { - /* simplest */ - char *cdest = (char *)dest; - char *csrc = (char *)src; - for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; - } - } - return(dest); -} -#endif - - -/**************************************************************************** -prompte a dptr (to make it recently used) -****************************************************************************/ -void array_promote(char *array,int elsize,int element) -{ - char *p; - if (element == 0) - return; - - p = (char *)malloc(elsize); - - if (!p) - { - DEBUG(5,("Ahh! Can't malloc\n")); - return; - } - memcpy(p,array + element * elsize, elsize); - memmove(array + elsize,array,elsize*element); - memcpy(array,p,elsize); - free(p); -} - -enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; - -struct -{ - char *name; - int level; - int option; - int value; - int opttype; -} socket_options[] = { - {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, - {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, - {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, -#ifdef TCP_NODELAY - {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, -#endif -#ifdef IPTOS_LOWDELAY - {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, -#endif -#ifdef IPTOS_THROUGHPUT - {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, -#endif -#ifdef SO_SNDBUF - {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, -#endif -#ifdef SO_RCVBUF - {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, -#endif -#ifdef SO_SNDLOWAT - {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_RCVLOWAT - {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_SNDTIMEO - {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, -#endif -#ifdef SO_RCVTIMEO - {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, -#endif - {NULL,0,0,0,0}}; - - - -/**************************************************************************** -set user socket options -****************************************************************************/ -void set_socket_options(int fd, char *options) -{ - string tok; - - while (next_token(&options,tok," \t,")) - { - int ret=0,i; - int value = 1; - char *p; - BOOL got_value = False; - - if ((p = strchr(tok,'='))) - { - *p = 0; - value = atoi(p+1); - got_value = True; - } - - for (i=0;socket_options[i].name;i++) - if (strequal(socket_options[i].name,tok)) - break; - - if (!socket_options[i].name) - { - DEBUG(0,("Unknown socket option %s\n",tok)); - continue; - } - - switch (socket_options[i].opttype) - { - case OPT_BOOL: - case OPT_INT: - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); - break; - - case OPT_ON: - if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); - - { - int on = socket_options[i].value; - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); - } - break; - } - - if (ret != 0) - DEBUG(0,("Failed to set socket option %s\n",tok)); - } -} - - - -/**************************************************************************** - close the socket communication -****************************************************************************/ -void close_sockets(void ) -{ - close(Client); - Client = 0; -} - -/**************************************************************************** -determine whether we are in the specified group -****************************************************************************/ -BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups) -{ - int i; - - if (group == current_gid) return(True); - - for (i=0;i<ngroups;i++) - if (group == groups[i]) - return(True); - - return(False); -} - -/**************************************************************************** -this is a safer strcpy(), meant to prevent core dumps when nasty things happen -****************************************************************************/ -char *StrCpy(char *dest,char *src) -{ - char *d = dest; - -#if AJT - /* I don't want to get lazy with these ... */ - if (!dest || !src) { - DEBUG(0,("ERROR: NULL StrCpy() called!\n")); - ajt_panic(); - } -#endif - - if (!dest) return(NULL); - if (!src) { - *dest = 0; - return(dest); - } - while ((*d++ = *src++)) ; - return(dest); -} - -/**************************************************************************** -line strncpy but always null terminates. Make sure there is room! -****************************************************************************/ -char *StrnCpy(char *dest,char *src,int n) -{ - char *d = dest; - if (!dest) return(NULL); - if (!src) { - *dest = 0; - return(dest); - } - while (n-- && (*d++ = *src++)) ; - *d = 0; - return(dest); -} - - -/******************************************************************* -copy an IP address from one buffer to another -********************************************************************/ -void putip(void *dest,void *src) -{ - memcpy(dest,src,4); -} - - -/**************************************************************************** -interpret the weird netbios "name". Return the name type -****************************************************************************/ -static int name_interpret(char *in,char *out) -{ - int ret; - int len = (*in++) / 2; - - *out=0; - - if (len > 30 || len<1) return(0); - - while (len--) - { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; - } - *out = 0; - ret = out[-1]; - -#ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) - { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(unsigned char *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } -#endif - return(ret); -} - -/**************************************************************************** -mangle a name into netbios format - - Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum. -****************************************************************************/ -int name_mangle( char *In, char *Out, char name_type ) - { - int i; - int c; - int len; - char buf[20]; - char *p = Out; - - /* Safely copy the input string, In, into buf[]. */ - (void)memset( buf, 0, 20 ); - if( '*' == In[0] ) - buf[0] = '*'; - else - (void)sprintf( buf, "%-15.15s%c", In, name_type ); - - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; - - /* Now convert the name to the rfc1001/1002 format. */ - for( i = 0; i < 16; i++ ) - { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; - } - p += 32; - p[0] = '\0'; - - /* Add the scope string. */ - for( i = 0, len = 0; NULL != scope; i++, len++ ) - { - switch( scope[i] ) - { - case '\0': - p[0] = len; - if( len > 0 ) - p[len+1] = 0; - return( name_len(Out) ); - case '.': - p[0] = len; - p += (len + 1); - len = 0; - break; - default: - p[len+1] = scope[i]; - break; - } - } - - return( name_len(Out) ); - } /* name_mangle */ - -/******************************************************************* - check if a file exists -********************************************************************/ -BOOL file_exist(char *fname,struct stat *sbuf) -{ - struct stat st; - if (!sbuf) sbuf = &st; - - if (sys_stat(fname,sbuf) != 0) - return(False); - - return(S_ISREG(sbuf->st_mode)); -} - -/******************************************************************* -check a files mod time -********************************************************************/ -time_t file_modtime(char *fname) -{ - struct stat st; - - if (sys_stat(fname,&st) != 0) - return(0); - - return(st.st_mtime); -} - -/******************************************************************* - check if a directory exists -********************************************************************/ -BOOL directory_exist(char *dname,struct stat *st) -{ - struct stat st2; - BOOL ret; - - if (!st) st = &st2; - - if (sys_stat(dname,st) != 0) - return(False); - - ret = S_ISDIR(st->st_mode); - if(!ret) - errno = ENOTDIR; - return ret; -} - -/******************************************************************* -returns the size in bytes of the named file -********************************************************************/ -uint32 file_size(char *file_name) -{ - struct stat buf; - buf.st_size = 0; - sys_stat(file_name,&buf); - return(buf.st_size); -} - -/******************************************************************* -return a string representing an attribute for a file -********************************************************************/ -char *attrib_string(int mode) -{ - static char attrstr[10]; - - attrstr[0] = 0; - - if (mode & aVOLID) strcat(attrstr,"V"); - if (mode & aDIR) strcat(attrstr,"D"); - if (mode & aARCH) strcat(attrstr,"A"); - if (mode & aHIDDEN) strcat(attrstr,"H"); - if (mode & aSYSTEM) strcat(attrstr,"S"); - if (mode & aRONLY) strcat(attrstr,"R"); - - return(attrstr); -} - - -/******************************************************************* - case insensitive string compararison -********************************************************************/ -int StrCaseCmp(char *s, char *t) -{ - /* compare until we run out of string, either t or s, or find a difference */ - /* We *must* use toupper rather than tolower here due to the - asynchronous upper to lower mapping. - */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - } - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (*s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - } - - return(toupper(*s) - toupper(*t)); - } -} - -/******************************************************************* - case insensitive string compararison, length limited -********************************************************************/ -int StrnCaseCmp(char *s, char *t, int n) -{ - /* compare until we run out of string, either t or s, or chars */ - /* We *must* use toupper rather than tolower here due to the - asynchronous upper to lower mapping. - */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;n > 0;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - n--; - } - } - return 0; - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (n-- && *s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - } - - /* not run out of chars - strings are different lengths */ - if (n) - return(toupper(*s) - toupper(*t)); - - /* identical up to where we run out of chars, - and strings are same length */ - return(0); - } -} - -/******************************************************************* - compare 2 strings -********************************************************************/ -BOOL strequal(char *s1, char *s2) -{ - if (s1 == s2) return(True); - if (!s1 || !s2) return(False); - - return(StrCaseCmp(s1,s2)==0); -} - -/******************************************************************* - compare 2 strings up to and including the nth char. - ******************************************************************/ -BOOL strnequal(char *s1,char *s2,int n) -{ - if (s1 == s2) return(True); - if (!s1 || !s2 || !n) return(False); - - return(StrnCaseCmp(s1,s2,n)==0); -} - -/******************************************************************* - compare 2 strings (case sensitive) -********************************************************************/ -BOOL strcsequal(char *s1,char *s2) -{ - if (s1 == s2) return(True); - if (!s1 || !s2) return(False); - - return(strcmp(s1,s2)==0); -} - - -/******************************************************************* - convert a string to lower case -********************************************************************/ -void strlower(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - s[1] = sj_tolower2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - } -} - -/******************************************************************* - convert a string to upper case -********************************************************************/ -void strupper(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_lower (s[0], s[1])) - s[1] = sj_toupper2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - *s = toupper(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (islower(*s)) - *s = toupper(*s); - s++; - } - } -} - -/******************************************************************* - convert a string to "normal" form -********************************************************************/ -void strnorm(char *s) -{ - if (case_default == CASE_UPPER) - strupper(s); - else - strlower(s); -} - -/******************************************************************* -check if a string is in "normal" case -********************************************************************/ -BOOL strisnormal(char *s) -{ - if (case_default == CASE_UPPER) - return(!strhaslower(s)); - - return(!strhasupper(s)); -} - - -/**************************************************************************** - string replace -****************************************************************************/ -void string_replace(char *s,char oldc,char newc) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (oldc == *s) - *s = newc; - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (oldc == *s) - *s = newc; - s++; - } - } -} - -/**************************************************************************** - make a file into unix format -****************************************************************************/ -void unix_format(char *fname) -{ - pstring namecopy; - string_replace(fname,'\\','/'); - - if (*fname == '/') - { - pstrcpy(namecopy,fname); - strcpy(fname,"."); - strcat(fname,namecopy); - } -} - -/**************************************************************************** - make a file into dos format -****************************************************************************/ -void dos_format(char *fname) -{ - string_replace(fname,'/','\\'); -} - - -/******************************************************************* - show a smb message structure -********************************************************************/ -void show_msg(char *buf) -{ - int i; - int j; - int bcc=0; - if (DEBUGLEVEL < 5) - return; - - DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", - smb_len(buf), - (int)CVAL(buf,smb_com), - (int)CVAL(buf,smb_rcls), - (int)CVAL(buf,smb_reh), - (int)SVAL(buf,smb_err), - (int)CVAL(buf,smb_flg), - (int)SVAL(buf,smb_flg2))); - DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", - (int)SVAL(buf,smb_tid), - (int)SVAL(buf,smb_pid), - (int)SVAL(buf,smb_uid), - (int)SVAL(buf,smb_mid), - (int)CVAL(buf,smb_wct))); - for (i=0;i<(int)CVAL(buf,smb_wct);i++) - DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, - SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); - bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); - DEBUG(5,("smb_bcc=%d\n",bcc)); - if (DEBUGLEVEL < 10) - return; - for (i = 0; i < MIN(bcc, 256); i += 16) - { - for (j = 0; j < 16 && i+j < MIN(bcc,256); j++) - { - - DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j))); - if (j == 7) DEBUG(10, (" ")); - - } - DEBUG(10,(" ")); - - for (j = 0; j < 16 && i+j < MIN(bcc,256); j++) - { - unsigned char c = CVAL(smb_buf(buf),i+j); - if (c < 32 || c > 128) c = '.'; - DEBUG(10,("%c",c)); - - if (j == 7) DEBUG(10, (" ")); - } - - DEBUG(10,("\n")); -} -} - -/******************************************************************* - return the length of an smb packet -********************************************************************/ -int smb_len(char *buf) -{ - return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) ); -} - -/******************************************************************* - set the length of an smb packet -********************************************************************/ -void _smb_setlen(char *buf,int len) -{ - buf[0] = 0; - buf[1] = (len&0x10000)>>16; - buf[2] = (len&0xFF00)>>8; - buf[3] = len&0xFF; -} - -/******************************************************************* - set the length and marker of an smb packet -********************************************************************/ -void smb_setlen(char *buf,int len) -{ - _smb_setlen(buf,len); - - CVAL(buf,4) = 0xFF; - CVAL(buf,5) = 'S'; - CVAL(buf,6) = 'M'; - CVAL(buf,7) = 'B'; -} - -/******************************************************************* - setup the word count and byte count for a smb message -********************************************************************/ -int set_message(char *buf,int num_words,int num_bytes,BOOL zero) -{ - if (zero) - bzero(buf + smb_size,num_words*2 + num_bytes); - CVAL(buf,smb_wct) = num_words; - SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); - return (smb_size + num_words*2 + num_bytes); -} - -/******************************************************************* -return the number of smb words -********************************************************************/ -int smb_numwords(char *buf) -{ - return (CVAL(buf,smb_wct)); -} - -/******************************************************************* -return the size of the smb_buf region of a message -********************************************************************/ -int smb_buflen(char *buf) -{ - return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2)); -} - -/******************************************************************* - return a pointer to the smb_buf data area -********************************************************************/ -int smb_buf_ofs(char *buf) -{ - return (smb_size + CVAL(buf,smb_wct)*2); -} - -/******************************************************************* - return a pointer to the smb_buf data area -********************************************************************/ -char *smb_buf(char *buf) -{ - return (buf + smb_buf_ofs(buf)); -} - -/******************************************************************* -return the SMB offset into an SMB buffer -********************************************************************/ -int smb_offset(char *p,char *buf) -{ - return(PTR_DIFF(p,buf+4) + chain_size); -} - - -/******************************************************************* -skip past some strings in a buffer -********************************************************************/ -char *skip_string(char *buf,int n) -{ - while (n--) - buf += strlen(buf) + 1; - return(buf); -} - -/******************************************************************* -trim the specified elements off the front and back of a string -********************************************************************/ -BOOL trim_string(char *s,char *front,char *back) -{ - BOOL ret = False; - while (front && *front && strncmp(s,front,strlen(front)) == 0) - { - char *p = s; - ret = True; - while (1) - { - if (!(*p = p[strlen(front)])) - break; - p++; - } - } - while (back && *back && strlen(s) >= strlen(back) && - (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0)) - { - ret = True; - s[strlen(s)-strlen(back)] = 0; - } - return(ret); -} - - -/******************************************************************* -reduce a file name, removing .. elements. -********************************************************************/ -void dos_clean_name(char *s) -{ - char *p=NULL; - - DEBUG(3,("dos_clean_name [%s]\n",s)); - - /* remove any double slashes */ - string_sub(s, "\\\\", "\\"); - - while ((p = strstr(s,"\\..\\")) != NULL) - { - pstring s1; - - *p = 0; - pstrcpy(s1,p+3); - - if ((p=strrchr(s,'\\')) != NULL) - *p = 0; - else - *s = 0; - strcat(s,s1); - } - - trim_string(s,NULL,"\\.."); - - string_sub(s, "\\.\\", "\\"); -} - -/******************************************************************* -reduce a file name, removing .. elements. -********************************************************************/ -void unix_clean_name(char *s) -{ - char *p=NULL; - - DEBUG(3,("unix_clean_name [%s]\n",s)); - - /* remove any double slashes */ - string_sub(s, "//","/"); - - /* Remove leading ./ characters */ - if(strncmp(s, "./", 2) == 0) { - trim_string(s, "./", NULL); - if(*s == 0) - strcpy(s,"./"); - } - - while ((p = strstr(s,"/../")) != NULL) - { - pstring s1; - - *p = 0; - pstrcpy(s1,p+3); - - if ((p=strrchr(s,'/')) != NULL) - *p = 0; - else - *s = 0; - strcat(s,s1); - } - - trim_string(s,NULL,"/.."); -} - - -/******************************************************************* -a wrapper for the normal chdir() function -********************************************************************/ -int ChDir(char *path) -{ - int res; - static pstring LastDir=""; - - if (strcsequal(path,".")) return(0); - - if (*path == '/' && strcsequal(LastDir,path)) return(0); - DEBUG(3,("chdir to %s\n",path)); - res = sys_chdir(path); - if (!res) - pstrcpy(LastDir,path); - return(res); -} - -/* number of list structures for a caching GetWd function. */ -#define MAX_GETWDCACHE (50) - -struct -{ - ino_t inode; - dev_t dev; - char *text; - BOOL valid; -} ino_list[MAX_GETWDCACHE]; - -BOOL use_getwd_cache=True; - -/******************************************************************* - return the absolute current directory path -********************************************************************/ -char *GetWd(char *str) -{ - pstring s; - static BOOL getwd_cache_init = False; - struct stat st, st2; - int i; - - *s = 0; - - if (!use_getwd_cache) - return(sys_getwd(str)); - - /* init the cache */ - if (!getwd_cache_init) - { - getwd_cache_init = True; - for (i=0;i<MAX_GETWDCACHE;i++) - { - string_init(&ino_list[i].text,""); - ino_list[i].valid = False; - } - } - - /* Get the inode of the current directory, if this doesn't work we're - in trouble :-) */ - - if (stat(".",&st) == -1) - { - DEBUG(0,("Very strange, couldn't stat \".\"\n")); - return(sys_getwd(str)); - } - - - for (i=0; i<MAX_GETWDCACHE; i++) - if (ino_list[i].valid) - { - - /* If we have found an entry with a matching inode and dev number - then find the inode number for the directory in the cached string. - If this agrees with that returned by the stat for the current - directory then all is o.k. (but make sure it is a directory all - the same...) */ - - if (st.st_ino == ino_list[i].inode && - st.st_dev == ino_list[i].dev) - { - if (stat(ino_list[i].text,&st2) == 0) - { - if (st.st_ino == st2.st_ino && - st.st_dev == st2.st_dev && - (st2.st_mode & S_IFMT) == S_IFDIR) - { - strcpy (str, ino_list[i].text); - - /* promote it for future use */ - array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); - return (str); - } - else - { - /* If the inode is different then something's changed, - scrub the entry and start from scratch. */ - ino_list[i].valid = False; - } - } - } - } - - - /* We don't have the information to hand so rely on traditional methods. - The very slow getcwd, which spawns a process on some systems, or the - not quite so bad getwd. */ - - if (!sys_getwd(s)) - { - DEBUG(0,("Getwd failed, errno %s\n",strerror(errno))); - return (NULL); - } - - strcpy(str,s); - - DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev)); - - /* add it to the cache */ - i = MAX_GETWDCACHE - 1; - string_set(&ino_list[i].text,s); - ino_list[i].dev = st.st_dev; - ino_list[i].inode = st.st_ino; - ino_list[i].valid = True; - - /* put it at the top of the list */ - array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); - - return (str); -} - - - -/******************************************************************* -reduce a file name, removing .. elements and checking that -it is below dir in the heirachy. This uses GetWd() and so must be run -on the system that has the referenced file system. - -widelinks are allowed if widelinks is true -********************************************************************/ -BOOL reduce_name(char *s,char *dir,BOOL widelinks) -{ -#ifndef REDUCE_PATHS - return True; -#else - pstring dir2; - pstring wd; - pstring basename; - pstring newname; - char *p=NULL; - BOOL relative = (*s != '/'); - - *dir2 = *wd = *basename = *newname = 0; - - if (widelinks) - { - unix_clean_name(s); - /* can't have a leading .. */ - if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) - { - DEBUG(3,("Illegal file name? (%s)\n",s)); - return(False); - } - - if (strlen(s) == 0) - strcpy(s,"./"); - - return(True); - } - - DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); - - /* remove any double slashes */ - string_sub(s,"//","/"); - - pstrcpy(basename,s); - p = strrchr(basename,'/'); - - if (!p) - return(True); - - if (!GetWd(wd)) - { - DEBUG(0,("couldn't getwd for %s %s\n",s,dir)); - return(False); - } - - if (ChDir(dir) != 0) - { - DEBUG(0,("couldn't chdir to %s\n",dir)); - return(False); - } - - if (!GetWd(dir2)) - { - DEBUG(0,("couldn't getwd for %s\n",dir)); - ChDir(wd); - return(False); - } - - - if (p && (p != basename)) - { - *p = 0; - if (strcmp(p+1,".")==0) - p[1]=0; - if (strcmp(p+1,"..")==0) - *p = '/'; - } - - if (ChDir(basename) != 0) - { - ChDir(wd); - DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename)); - return(False); - } - - if (!GetWd(newname)) - { - ChDir(wd); - DEBUG(2,("couldn't get wd for %s %s\n",s,dir2)); - return(False); - } - - if (p && (p != basename)) - { - strcat(newname,"/"); - strcat(newname,p+1); - } - - { - int l = strlen(dir2); - if (dir2[l-1] == '/') - l--; - - if (strncmp(newname,dir2,l) != 0) - { - ChDir(wd); - DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l)); - return(False); - } - - if (relative) - { - if (newname[l] == '/') - pstrcpy(s,newname + l + 1); - else - pstrcpy(s,newname+l); - } - else - pstrcpy(s,newname); - } - - ChDir(wd); - - if (strlen(s) == 0) - strcpy(s,"./"); - - DEBUG(3,("reduced to %s\n",s)); - return(True); -#endif -} - -/**************************************************************************** -expand some *s -****************************************************************************/ -static void expand_one(char *Mask,int len) -{ - char *p1; - while ((p1 = strchr(Mask,'*')) != NULL) - { - int lfill = (len+1) - strlen(Mask); - int l1= (p1 - Mask); - pstring tmp; - pstrcpy(tmp,Mask); - memset(tmp+l1,'?',lfill); - pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); - pstrcpy(Mask,tmp); - } -} - -/**************************************************************************** -expand a wildcard expression, replacing *s with ?s -****************************************************************************/ -void expand_mask(char *Mask,BOOL doext) -{ - pstring mbeg,mext; - pstring dirpart; - pstring filepart; - BOOL hasdot = False; - char *p1; - BOOL absolute = (*Mask == '\\'); - - *mbeg = *mext = *dirpart = *filepart = 0; - - /* parse the directory and filename */ - if (strchr(Mask,'\\')) - dirname_dos(Mask,dirpart); - - filename_dos(Mask,filepart); - - pstrcpy(mbeg,filepart); - if ((p1 = strchr(mbeg,'.')) != NULL) - { - hasdot = True; - *p1 = 0; - p1++; - pstrcpy(mext,p1); - } - else - { - strcpy(mext,""); - if (strlen(mbeg) > 8) - { - pstrcpy(mext,mbeg + 8); - mbeg[8] = 0; - } - } - - if (*mbeg == 0) - strcpy(mbeg,"????????"); - if ((*mext == 0) && doext && !hasdot) - strcpy(mext,"???"); - - if (strequal(mbeg,"*") && *mext==0) - strcpy(mext,"*"); - - /* expand *'s */ - expand_one(mbeg,8); - if (*mext) - expand_one(mext,3); - - pstrcpy(Mask,dirpart); - if (*dirpart || absolute) strcat(Mask,"\\"); - strcat(Mask,mbeg); - strcat(Mask,"."); - strcat(Mask,mext); - - DEBUG(6,("Mask expanded to [%s]\n",Mask)); -} - - -/**************************************************************************** -does a string have any uppercase chars in it? -****************************************************************************/ -BOOL strhasupper(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (isupper(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (isupper(*s)) - return(True); - s++; - } - } - return(False); -} - -/**************************************************************************** -does a string have any lowercase chars in it? -****************************************************************************/ -BOOL strhaslower(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - return(True); - if (is_sj_lower (s[0], s[1])) - return (True); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (islower(*s)) - return(True); - s++; - } - } - return(False); -} - -/**************************************************************************** -find the number of chars in a string -****************************************************************************/ -int count_chars(char *s,char c) -{ - int count=0; - -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - while (*s) - { - if (is_shift_jis (*s)) - s += 2; - else - { - if (*s == c) - count++; - s++; - } - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (*s) - { - if (*s == c) - count++; - s++; - } - } - return(count); -} - - -/**************************************************************************** - make a dir struct -****************************************************************************/ -void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date) -{ - char *p; - pstring mask2; - - pstrcpy(mask2,mask); - - if ((mode & aDIR) != 0) - size = 0; - - memset(buf+1,' ',11); - if ((p = strchr(mask2,'.')) != NULL) - { - *p = 0; - memcpy(buf+1,mask2,MIN(strlen(mask2),8)); - memcpy(buf+9,p+1,MIN(strlen(p+1),3)); - *p = '.'; - } - else - memcpy(buf+1,mask2,MIN(strlen(mask2),11)); - - bzero(buf+21,DIR_STRUCT_SIZE-21); - CVAL(buf,21) = mode; - put_dos_date(buf,22,date); - SSVAL(buf,26,size & 0xFFFF); - SSVAL(buf,28,size >> 16); - StrnCpy(buf+30,fname,12); - if (!case_sensitive) - strupper(buf+30); - DEBUG(8,("put name [%s] into dir struct\n",buf+30)); -} - - -/******************************************************************* -close the low 3 fd's and open dev/null in their place -********************************************************************/ -void close_low_fds(void) -{ - int fd; - int i; - close(0); close(1); close(2); - /* try and use up these file descriptors, so silly - library routines writing to stdout etc won't cause havoc */ - for (i=0;i<3;i++) { - fd = open("/dev/null",O_RDWR,0); - if (fd < 0) fd = open("/dev/null",O_WRONLY,0); - if (fd < 0) { - DEBUG(0,("Can't open /dev/null\n")); - return; - } - if (fd != i) { - DEBUG(0,("Didn't get file descriptor %d\n",i)); - return; - } - } -} - -/**************************************************************************** -Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, -else -if SYSV use O_NDELAY -if BSD use FNDELAY -****************************************************************************/ -int set_blocking(int fd, BOOL set) -{ - int val; -#ifdef O_NONBLOCK -#define FLAG_TO_SET O_NONBLOCK -#else -#ifdef SYSV -#define FLAG_TO_SET O_NDELAY -#else /* BSD */ -#define FLAG_TO_SET FNDELAY -#endif -#endif - - if((val = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - if(set) /* Turn blocking on - ie. clear nonblock flag */ - val &= ~FLAG_TO_SET; - else - val |= FLAG_TO_SET; - return fcntl( fd, F_SETFL, val); -#undef FLAG_TO_SET -} - - -/**************************************************************************** -write to a socket -****************************************************************************/ -int write_socket(int fd,char *buf,int len) -{ - int ret=0; - - if (passive) - return(len); - DEBUG(6,("write_socket(%d,%d)\n",fd,len)); - ret = write_data(fd,buf,len); - - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret)); - return(ret); -} - -/**************************************************************************** -read from a socket -****************************************************************************/ -int read_udp_socket(int fd,char *buf,int len) -{ - int ret; - struct sockaddr sock; - int socklen; - - socklen = sizeof(sock); - bzero((char *)&sock,socklen); - bzero((char *)&lastip,sizeof(lastip)); - ret = recvfrom(fd,buf,len,0,&sock,&socklen); - if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); - return(0); - } - - lastip = *(struct in_addr *) &sock.sa_data[2]; - lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port); - - return(ret); -} - -/**************************************************************************** -read data from a device with a timout in msec. -mincount = if timeout, minimum to read before returning -maxcount = number to be read. -****************************************************************************/ -int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out) -{ - fd_set fds; - int selrtn; - int readret; - int nread = 0; - struct timeval timeout; - - /* just checking .... */ - if (maxcnt <= 0) return(0); - - smb_read_error = 0; - - /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; - - while (nread < mincnt) { - readret = read(fd, buf + nread, maxcnt - nread); - if (readret == 0) { - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - smb_read_error = READ_ERROR; - return -1; - } - nread += readret; - } - return(nread); - } - - /* Most difficult - timeout read */ - /* If this is ever called on a disk file and - mincnt is greater then the filesize then - system performance will suffer severely as - select always return true on disk files */ - - /* Set initial timeout */ - timeout.tv_sec = time_out / 1000; - timeout.tv_usec = 1000 * (time_out % 1000); - - for (nread=0; nread<mincnt; ) - { - FD_ZERO(&fds); - FD_SET(fd,&fds); - - selrtn = sys_select(&fds,&timeout); - - /* Check if error */ - if(selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - smb_read_error = READ_ERROR; - return -1; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - smb_read_error = READ_TIMEOUT; - return -1; - } - - readret = read(fd, buf+nread, maxcnt-nread); - if (readret == 0) { - /* we got EOF on the file descriptor */ - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - /* the descriptor is probably dead */ - smb_read_error = READ_ERROR; - return -1; - } - - nread += readret; - } - - /* Return the number we got */ - return(nread); -} - -/**************************************************************************** -read data from the client. Maxtime is in milliseconds -****************************************************************************/ -int read_max_udp(int fd,char *buffer,int bufsize,int maxtime) -{ - fd_set fds; - int selrtn; - int nread; - struct timeval timeout; - - FD_ZERO(&fds); - FD_SET(fd,&fds); - - timeout.tv_sec = maxtime / 1000; - timeout.tv_usec = (maxtime % 1000) * 1000; - - selrtn = sys_select(&fds,maxtime>0?&timeout:NULL); - - if (!FD_ISSET(fd,&fds)) - return 0; - - nread = read_udp_socket(fd, buffer, bufsize); - - /* return the number got */ - return(nread); -} - -/******************************************************************* -find the difference in milliseconds between two struct timeval -values -********************************************************************/ -int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew) -{ - return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + - ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000); -} - -/**************************************************************************** -send a keepalive packet (rfc1002) -****************************************************************************/ -BOOL send_keepalive(int client) -{ - unsigned char buf[4]; - - buf[0] = 0x85; - buf[1] = buf[2] = buf[3] = 0; - - return(write_data(client,(char *)buf,4) == 4); -} - - - -/**************************************************************************** - read data from the client, reading exactly N bytes. -****************************************************************************/ -int read_data(int fd,char *buffer,int N) -{ - int ret; - int total=0; - - smb_read_error = 0; - - while (total < N) - { - ret = read(fd,buffer + total,N - total); - if (ret == 0) { - smb_read_error = READ_EOF; - return 0; - } - if (ret == -1) { - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return total; -} - - -/**************************************************************************** - write data to a fd -****************************************************************************/ -int write_data(int fd,char *buffer,int N) -{ - int total=0; - int ret; - - while (total < N) - { - ret = write(fd,buffer + total,N - total); - - if (ret == -1) return -1; - if (ret == 0) return total; - - total += ret; - } - return total; -} - - -/**************************************************************************** -transfer some data between two fd's -****************************************************************************/ -int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align) -{ - static char *buf=NULL; - static int size=0; - char *buf1,*abuf; - int total = 0; - - DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen)); - - if (size == 0) { - size = lp_readsize(); - size = MAX(size,1024); - } - - while (!buf && size>0) { - buf = (char *)Realloc(buf,size+8); - if (!buf) size /= 2; - } - - if (!buf) { - DEBUG(0,("Can't allocate transfer buffer!\n")); - exit(1); - } - - abuf = buf + (align%8); - - if (header) - n += headlen; - - while (n > 0) - { - int s = MIN(n,size); - int ret,ret2=0; - - ret = 0; - - if (header && (headlen >= MIN(s,1024))) { - buf1 = header; - s = headlen; - ret = headlen; - headlen = 0; - header = NULL; - } else { - buf1 = abuf; - } - - if (header && headlen > 0) - { - ret = MIN(headlen,size); - memcpy(buf1,header,ret); - headlen -= ret; - header += ret; - if (headlen <= 0) header = NULL; - } - - if (s > ret) - ret += read(infd,buf1+ret,s-ret); - - if (ret > 0) - { - ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret); - if (ret2 > 0) total += ret2; - /* if we can't write then dump excess data */ - if (ret2 != ret) - transfer_file(infd,-1,n-(ret+headlen),NULL,0,0); - } - if (ret <= 0 || ret2 != ret) - return(total); - n -= ret; - } - return(total); -} - - -/**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -possibly store the result in the buffer -****************************************************************************/ -int read_smb_length(int fd,char *inbuf,int timeout) -{ - char *buffer; - char buf[4]; - int len=0, msg_type; - BOOL ok=False; - - if (inbuf) - buffer = inbuf; - else - buffer = buf; - - while (!ok) - { - if (timeout > 0) - ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4); - else - ok = (read_data(fd,buffer,4) == 4); - - if (!ok) - return(-1); - - len = smb_len(buffer); - msg_type = CVAL(buffer,0); - - if (msg_type == 0x85) - { - DEBUG(5,("Got keepalive packet\n")); - ok = False; - } - } - - DEBUG(10,("got smb length of %d\n",len)); - - return(len); -} - - - -/**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. -The timeout is in milli seconds -****************************************************************************/ -BOOL receive_smb(int fd,char *buffer, int timeout) -{ - int len,ret; - - smb_read_error = 0; - - bzero(buffer,smb_size + 100); - - len = read_smb_length(fd,buffer,timeout); - if (len == -1) - return(False); - - if (len > BUFFER_SIZE) { - DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) - exit(1); - } - - ret = read_data(fd,buffer+4,len); - if (ret != len) { - smb_read_error = READ_ERROR; - return False; - } - - return(True); -} - -/**************************************************************************** - read a message from a udp fd. -The timeout is in milli seconds -****************************************************************************/ -BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout) -{ - struct sockaddr_in from; - int fromlen = sizeof(from); - int32 msg_len = 0; - - if(timeout != 0) - { - struct timeval to; - fd_set fds; - int selrtn; - - FD_ZERO(&fds); - FD_SET(fd,&fds); - - to.tv_sec = timeout / 1000; - to.tv_usec = (timeout % 1000) * 1000; - - selrtn = sys_select(&fds,&to); - - /* Check if error */ - if(selrtn == -1) - { - /* something is wrong. Maybe the socket is dead? */ - smb_read_error = READ_ERROR; - return False; - } - - /* Did we timeout ? */ - if (selrtn == 0) - { - smb_read_error = READ_TIMEOUT; - return False; - } - } - - /* - * Read a loopback udp message. - */ - msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], - buffer_len - UDP_CMD_HEADER_LEN, 0, - (struct sockaddr *)&from, &fromlen); - - if(msg_len < 0) - { - DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno))); - return False; - } - - /* Validate message length. */ - if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN)) - { - DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n", - msg_len, - buffer_len - UDP_CMD_HEADER_LEN)); - return False; - } - - /* Validate message from address (must be localhost). */ - if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) - { - DEBUG(0,("receive_local_message: invalid 'from' address \ -(was %x should be 127.0.0.1\n", from.sin_addr.s_addr)); - return False; - } - - /* Setup the message header */ - SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len); - SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port)); - - return True; -} - -/**************************************************************************** - structure to hold a linked list of local udp messages. - for processing. -****************************************************************************/ - -typedef struct _udp_message_list { - struct _udp_message_list *msg_next; - char *msg_buf; - int msg_len; -} udp_message_list; - -static udp_message_list *udp_msg_head = NULL; - -/**************************************************************************** - Function to push a linked list of local udp messages ready - for processing. -****************************************************************************/ -BOOL push_local_message(char *buf, int msg_len) -{ - udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list)); - - if(msg == NULL) - { - DEBUG(0,("push_local_message: malloc fail (1)\n")); - return False; - } - - msg->msg_buf = (char *)malloc(msg_len); - if(msg->msg_buf == NULL) - { - DEBUG(0,("push_local_message: malloc fail (2)\n")); - free((char *)msg); - return False; - } - - memcpy(msg->msg_buf, buf, msg_len); - msg->msg_len = msg_len; - - msg->msg_next = udp_msg_head; - udp_msg_head = msg; - - return True; -} - -/**************************************************************************** - Do a select on an two fd's - with timeout. - - If a local udp message has been pushed onto the - queue (this can only happen during oplock break - processing) return this first. - - If the first smbfd is ready then read an smb from it. - if the second (loopback UDP) fd is ready then read a message - from it and setup the buffer header to identify the length - and from address. - Returns False on timeout or error. - Else returns True. - -The timeout is in milli seconds -****************************************************************************/ -BOOL receive_message_or_smb(int smbfd, int oplock_fd, - char *buffer, int buffer_len, - int timeout, BOOL *got_smb) -{ - fd_set fds; - int selrtn; - struct timeval to; - - *got_smb = False; - - /* - * Check to see if we already have a message on the udp queue. - * If so - copy and return it. - */ - - if(udp_msg_head) - { - udp_message_list *msg = udp_msg_head; - memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len)); - udp_msg_head = msg->msg_next; - - /* Free the message we just copied. */ - free((char *)msg->msg_buf); - free((char *)msg); - return True; - } - - FD_ZERO(&fds); - FD_SET(smbfd,&fds); - FD_SET(oplock_fd,&fds); - - to.tv_sec = timeout / 1000; - to.tv_usec = (timeout % 1000) * 1000; - - selrtn = sys_select(&fds,timeout>0?&to:NULL); - - /* Check if error */ - if(selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - smb_read_error = READ_ERROR; - return False; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - smb_read_error = READ_TIMEOUT; - return False; - } - - if (FD_ISSET(smbfd,&fds)) - { - *got_smb = True; - return receive_smb(smbfd, buffer, 0); - } - else - { - return receive_local_message(oplock_fd, buffer, buffer_len, 0); - } -} - -/**************************************************************************** - send an smb to a fd -****************************************************************************/ -BOOL send_smb(int fd,char *buffer) -{ - int len; - int ret,nwritten=0; - len = smb_len(buffer) + 4; - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret)); - close_sockets(); - exit(1); - } - nwritten += ret; - } - - - return True; -} - - -/**************************************************************************** -find a pointer to a netbios name -****************************************************************************/ -char *name_ptr(char *buf,int ofs) -{ - unsigned char c = *(unsigned char *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16 l; - char p[2]; - memcpy(p,buf+ofs,2); - p[0] &= ~0xC0; - l = RSVAL(p,0); - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); -} - -/**************************************************************************** -extract a netbios name from a buf -****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) -{ - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - strcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); -} - -/**************************************************************************** -return the total storage length of a mangled name -****************************************************************************/ -int name_len( char *s ) - { - int len; - - /* If the two high bits of the byte are set, return 2. */ - if( 0xC0 == (*(unsigned char *)s & 0xC0) ) - return(2); - - /* Add up the length bytes. */ - for( len = 1; (*s); s += (*s) + 1 ) - { - len += *s + 1; - } - - return( len ); - } /* name_len */ - -/**************************************************************************** -send a single packet to a port on another machine -****************************************************************************/ -BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) -{ - BOOL ret; - int out_fd; - struct sockaddr_in sock_out; - - if (passive) - return(True); - - /* create a socket to write to */ - out_fd = socket(AF_INET, type, 0); - if (out_fd == -1) - { - DEBUG(0,("socket failed")); - return False; - } - - /* set the address and port */ - bzero((char *)&sock_out,sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; - - if (DEBUGLEVEL > 0) - DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n", - len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM")); - - /* send it */ - ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0); - - if (!ret) - DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); - - close(out_fd); - return(ret); -} - -/******************************************************************* -sleep for a specified number of milliseconds -********************************************************************/ -void msleep(int t) -{ - int tdiff=0; - struct timeval tval,t1,t2; - fd_set fds; - - GetTimeOfDay(&t1); - GetTimeOfDay(&t2); - - while (tdiff < t) { - tval.tv_sec = (t-tdiff)/1000; - tval.tv_usec = 1000*((t-tdiff)%1000); - - FD_ZERO(&fds); - errno = 0; - sys_select(&fds,&tval); - - GetTimeOfDay(&t2); - tdiff = TvalDiff(&t1,&t2); - } -} - -/**************************************************************************** -check if a string is part of a list -****************************************************************************/ -BOOL in_list(char *s,char *list,BOOL casesensitive) -{ - pstring tok; - char *p=list; - - if (!list) return(False); - - while (next_token(&p,tok,LIST_SEP)) - { - if (casesensitive) { - if (strcmp(tok,s) == 0) - return(True); - } else { - if (StrCaseCmp(tok,s) == 0) - return(True); - } - } - return(False); -} - -/* this is used to prevent lots of mallocs of size 1 */ -static char *null_string = NULL; - -/**************************************************************************** -set a string value, allocing the space for the string -****************************************************************************/ -BOOL string_init(char **dest,char *src) -{ - int l; - if (!src) - src = ""; - - l = strlen(src); - - if (l == 0) - { - if (!null_string) - null_string = (char *)malloc(1); - - *null_string = 0; - *dest = null_string; - } - else - { - (*dest) = (char *)malloc(l+1); - if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); - return False; - } - - strcpy(*dest,src); - } - return(True); -} - -/**************************************************************************** -free a string value -****************************************************************************/ -void string_free(char **s) -{ - if (!s || !(*s)) return; - if (*s == null_string) - *s = NULL; - if (*s) free(*s); - *s = NULL; -} - -/**************************************************************************** -set a string value, allocing the space for the string, and deallocating any -existing space -****************************************************************************/ -BOOL string_set(char **dest,char *src) -{ - string_free(dest); - - return(string_init(dest,src)); -} - -/**************************************************************************** -substitute a string for a pattern in another string. Make sure there is -enough room! - -This routine looks for pattern in s and replaces it with -insert. It may do multiple replacements. - -return True if a substitution was done. -****************************************************************************/ -BOOL string_sub(char *s,char *pattern,char *insert) -{ - BOOL ret = False; - char *p; - int ls,lp,li; - - if (!insert || !pattern || !s) return(False); - - ls = strlen(s); - lp = strlen(pattern); - li = strlen(insert); - - if (!*pattern) return(False); - - while (lp <= ls && (p = strstr(s,pattern))) - { - ret = True; - memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp)); - memcpy(p,insert,li); - s = p + li; - ls = strlen(s); - } - return(ret); -} - - - -/********************************************************* -* Recursive routine that is called by mask_match. -* Does the actual matching. -*********************************************************/ -BOOL do_match(char *str, char *regexp, int case_sig) -{ - char *p; - - for( p = regexp; *p && *str; ) { - switch(*p) { - case '?': - str++; p++; - break; - - case '*': - /* Look for a character matching - the one after the '*' */ - p++; - if(!*p) - return True; /* Automatic match */ - while(*str) { - while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str)))) - str++; - if(do_match(str,p,case_sig)) - return True; - if(!*str) - return False; - else - str++; - } - return False; - - default: - if(case_sig) { - if(*str != *p) - return False; - } else { - if(toupper(*str) != toupper(*p)) - return False; - } - str++, p++; - break; - } - } - if(!*p && !*str) - return True; - - if (!*p && str[0] == '.' && str[1] == 0) - return(True); - - if (!*str && *p == '?') - { - while (*p == '?') p++; - return(!*p); - } - - if(!*str && (*p == '*' && p[1] == '\0')) - return True; - return False; -} - - -/********************************************************* -* Routine to match a given string with a regexp - uses -* simplified regexp that takes * and ? only. Case can be -* significant or not. -*********************************************************/ -BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) -{ - char *p; - pstring p1, p2; - fstring ebase,eext,sbase,sext; - - BOOL matched; - - /* Make local copies of str and regexp */ - StrnCpy(p1,regexp,sizeof(pstring)-1); - StrnCpy(p2,str,sizeof(pstring)-1); - - if (!strchr(p2,'.')) { - strcat(p2,"."); - } - -/* - if (!strchr(p1,'.')) { - strcat(p1,"."); - } -*/ - -#if 0 - if (strchr(p1,'.')) - { - string_sub(p1,"*.*","*"); - string_sub(p1,".*","*"); - } -#endif - - /* Remove any *? and ** as they are meaningless */ - for(p = p1; *p; p++) - while( *p == '*' && (p[1] == '?' ||p[1] == '*')) - (void)strcpy( &p[1], &p[2]); - - if (strequal(p1,"*")) return(True); - - DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); - - if (trans2) { - fstrcpy(ebase,p1); - fstrcpy(sbase,p2); - } else { - if ((p=strrchr(p1,'.'))) { - *p = 0; - fstrcpy(ebase,p1); - fstrcpy(eext,p+1); - } else { - fstrcpy(ebase,p1); - eext[0] = 0; - } - - if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) { - *p = 0; - fstrcpy(sbase,p2); - fstrcpy(sext,p+1); - } else { - fstrcpy(sbase,p2); - fstrcpy(sext,""); - } - } - - matched = do_match(sbase,ebase,case_sig) && - (trans2 || do_match(sext,eext,case_sig)); - - DEBUG(8,("mask_match returning %d\n", matched)); - - return matched; -} - - - -/**************************************************************************** -become a daemon, discarding the controlling terminal -****************************************************************************/ -void become_daemon(void) -{ -#ifndef NO_FORK_DEBUG - if (fork()) - exit(0); - - /* detach from the terminal */ -#ifdef USE_SETSID - setsid(); -#else /* USE_SETSID */ -#ifdef TIOCNOTTY - { - int i = open("/dev/tty", O_RDWR); - if (i >= 0) - { - ioctl(i, (int) TIOCNOTTY, (char *)0); - close(i); - } - } -#endif /* TIOCNOTTY */ -#endif /* USE_SETSID */ - /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(); -#endif /* NO_FORK_DEBUG */ -} - - -/**************************************************************************** -put up a yes/no prompt -****************************************************************************/ -BOOL yesno(char *p) -{ - pstring ans; - printf("%s",p); - - if (!fgets(ans,sizeof(ans)-1,stdin)) - return(False); - - if (*ans == 'y' || *ans == 'Y') - return(True); - - return(False); -} - -/**************************************************************************** -read a line from a file with possible \ continuation chars. -Blanks at the start or end of a line are stripped. -The string will be allocated if s2 is NULL -****************************************************************************/ -char *fgets_slash(char *s2,int maxlen,FILE *f) -{ - char *s=s2; - int len = 0; - int c; - BOOL start_of_line = True; - - if (feof(f)) - return(NULL); - - if (!s2) - { - maxlen = MIN(maxlen,8); - s = (char *)Realloc(s,maxlen); - } - - if (!s || maxlen < 2) return(NULL); - - *s = 0; - - while (len < maxlen-1) - { - c = getc(f); - switch (c) - { - case '\r': - break; - case '\n': - while (len > 0 && s[len-1] == ' ') - { - s[--len] = 0; - } - if (len > 0 && s[len-1] == '\\') - { - s[--len] = 0; - start_of_line = True; - break; - } - return(s); - case EOF: - if (len <= 0 && !s2) - free(s); - return(len>0?s:NULL); - case ' ': - if (start_of_line) - break; - default: - start_of_line = False; - s[len++] = c; - s[len] = 0; - } - if (!s2 && len > maxlen-3) - { - maxlen *= 2; - s = (char *)Realloc(s,maxlen); - if (!s) return(NULL); - } - } - return(s); -} - - - -/**************************************************************************** -set the length of a file from a filedescriptor. -Returns 0 on success, -1 on failure. -****************************************************************************/ -int set_filelen(int fd, long len) -{ -/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot - extend a file with ftruncate. Provide alternate implementation - for this */ - -#if FTRUNCATE_CAN_EXTEND - return ftruncate(fd, len); -#else - struct stat st; - char c = 0; - long currpos = lseek(fd, 0L, SEEK_CUR); - - if(currpos < 0) - return -1; - /* Do an fstat to see if the file is longer than - the requested size (call ftruncate), - or shorter, in which case seek to len - 1 and write 1 - byte of zero */ - if(fstat(fd, &st)<0) - return -1; - -#ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) return 0; -#endif - - if(st.st_size == len) - return 0; - if(st.st_size > len) - return ftruncate(fd, len); - - if(lseek(fd, len-1, SEEK_SET) != len -1) - return -1; - if(write(fd, &c, 1)!=1) - return -1; - /* Seek to where we were */ - lseek(fd, currpos, SEEK_SET); - return 0; -#endif -} - - -/**************************************************************************** -return the byte checksum of some data -****************************************************************************/ -int byte_checksum(char *buf,int len) -{ - unsigned char *p = (unsigned char *)buf; - int ret = 0; - while (len--) - ret += *p++; - return(ret); -} - - - -#ifdef HPUX -/**************************************************************************** -this is a version of setbuffer() for those machines that only have setvbuf -****************************************************************************/ - void setbuffer(FILE *f,char *buf,int bufsize) -{ - setvbuf(f,buf,_IOFBF,bufsize); -} -#endif - - -/**************************************************************************** -parse out a directory name from a path name. Assumes dos style filenames. -****************************************************************************/ -char *dirname_dos(char *path,char *buf) -{ - char *p = strrchr(path,'\\'); - - if (!p) - strcpy(buf,path); - else - { - *p = 0; - strcpy(buf,path); - *p = '\\'; - } - - return(buf); -} - - -/**************************************************************************** -parse out a filename from a path name. Assumes dos style filenames. -****************************************************************************/ -static char *filename_dos(char *path,char *buf) -{ - char *p = strrchr(path,'\\'); - - if (!p) - strcpy(buf,path); - else - strcpy(buf,p+1); - - return(buf); -} - - - -/**************************************************************************** -expand a pointer to be a particular size -****************************************************************************/ -void *Realloc(void *p,int size) -{ - void *ret=NULL; - - if (size == 0) { - if (p) free(p); - DEBUG(5,("Realloc asked for 0 bytes\n")); - return NULL; - } - - if (!p) - ret = (void *)malloc(size); - else - ret = (void *)realloc(p,size); - - if (!ret) - DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size)); - - return(ret); -} - -#ifdef NOSTRDUP -/**************************************************************************** -duplicate a string -****************************************************************************/ - char *strdup(char *s) -{ - char *ret = NULL; - if (!s) return(NULL); - ret = (char *)malloc(strlen(s)+1); - if (!ret) return(NULL); - strcpy(ret,s); - return(ret); -} -#endif - - -/**************************************************************************** - Signal handler for SIGPIPE (write on a disconnected socket) -****************************************************************************/ -void Abort(void ) -{ - DEBUG(0,("Probably got SIGPIPE\nExiting\n")); - exit(2); -} - -/**************************************************************************** -get my own name and IP -****************************************************************************/ -BOOL get_myname(char *my_name,struct in_addr *ip) -{ - struct hostent *hp; - pstring hostname; - - *hostname = 0; - - /* get my host name */ - if (gethostname(hostname, MAXHOSTNAMELEN) == -1) - { - DEBUG(0,("gethostname failed\n")); - return False; - } - - /* get host info */ - if ((hp = Get_Hostbyname(hostname)) == 0) - { - DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname)); - return False; - } - - if (my_name) - { - /* split off any parts after an initial . */ - char *p = strchr(hostname,'.'); - if (p) *p = 0; - - fstrcpy(my_name,hostname); - } - - if (ip) - putip((char *)ip,(char *)hp->h_addr); - - return(True); -} - - -/**************************************************************************** -true if two IP addresses are equal -****************************************************************************/ -BOOL ip_equal(struct in_addr ip1,struct in_addr ip2) -{ - uint32 a1,a2; - a1 = ntohl(ip1.s_addr); - a2 = ntohl(ip2.s_addr); - return(a1 == a2); -} - - -/**************************************************************************** -open a socket of the specified type, port and address for incoming data -****************************************************************************/ -int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) -{ - struct hostent *hp; - struct sockaddr_in sock; - pstring host_name; - int res; - - /* get my host name */ - if (gethostname(host_name, MAXHOSTNAMELEN) == -1) - { DEBUG(0,("gethostname failed\n")); return -1; } - - /* get host info */ - if ((hp = Get_Hostbyname(host_name)) == 0) - { - DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name)); - return -1; - } - - bzero((char *)&sock,sizeof(sock)); - memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); -#if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */ - sock.sin_len = sizeof(sock); -#endif - sock.sin_port = htons( port ); - sock.sin_family = hp->h_addrtype; - sock.sin_addr.s_addr = socket_addr; - res = socket(hp->h_addrtype, type, 0); - if (res == -1) - { DEBUG(0,("socket failed\n")); return -1; } - - { - int one=1; - setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); - } - - /* now we've got a socket - we need to bind it */ - if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) - { - if (port) { - if (port == SMB_PORT || port == NMB_PORT) - DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n", - port,socket_addr,strerror(errno))); - close(res); - - if (dlevel > 0 && port < 1000) - port = 7999; - - if (port >= 1000 && port < 9000) - return(open_socket_in(type,port+1,dlevel,socket_addr)); - } - - return(-1); - } - DEBUG(3,("bind succeeded on port %d\n",port)); - - return res; -} - - -/**************************************************************************** - create an outgoing socket - **************************************************************************/ -int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) -{ - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout * 1000) / connect_loop; - - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } - - if (type != SOCK_STREAM) return(res); - - bzero((char *)&sock_out,sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); - - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; - - /* set it non-blocking */ - set_blocking(res,False); - - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && loops--) { - msleep(connect_loop); - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); - close(res); - return -1; - } - -#ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } -#endif - - if (ret < 0) { - DEBUG(1,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,strerror(errno))); - return -1; - } - - /* set it blocking again */ - set_blocking(res,True); - - return res; -} - - -/**************************************************************************** -interpret a protocol description string, with a default -****************************************************************************/ -int interpret_protocol(char *str,int def) -{ - if (strequal(str,"NT1")) - return(PROTOCOL_NT1); - if (strequal(str,"LANMAN2")) - return(PROTOCOL_LANMAN2); - if (strequal(str,"LANMAN1")) - return(PROTOCOL_LANMAN1); - if (strequal(str,"CORE")) - return(PROTOCOL_CORE); - if (strequal(str,"COREPLUS")) - return(PROTOCOL_COREPLUS); - if (strequal(str,"CORE+")) - return(PROTOCOL_COREPLUS); - - DEBUG(0,("Unrecognised protocol level %s\n",str)); - - return(def); -} - -/**************************************************************************** -interpret a security level -****************************************************************************/ -int interpret_security(char *str,int def) -{ - if (strequal(str,"SERVER")) - return(SEC_SERVER); - if (strequal(str,"USER")) - return(SEC_USER); - if (strequal(str,"SHARE")) - return(SEC_SHARE); - - DEBUG(0,("Unrecognised security level %s\n",str)); - - return(def); -} - - -/**************************************************************************** -interpret an internet address or name into an IP address in 4 byte form -****************************************************************************/ -uint32 interpret_addr(char *str) -{ - struct hostent *hp; - uint32 res; - int i; - BOOL pure_address = True; - - if (strcmp(str,"0.0.0.0") == 0) return(0); - if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF); - - for (i=0; pure_address && str[i]; i++) - if (!(isdigit(str[i]) || str[i] == '.')) - pure_address = False; - - /* if it's in the form of an IP address then get the lib to interpret it */ - if (pure_address) { - res = inet_addr(str); - } else { - /* otherwise assume it's a network name of some sort and use - Get_Hostbyname */ - if ((hp = Get_Hostbyname(str)) == 0) { - DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str)); - return 0; - } - if(hp->h_addr == NULL) { - DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str)); - return 0; - } - putip((char *)&res,(char *)hp->h_addr); - } - - if (res == (uint32)-1) return(0); - - return(res); -} - -/******************************************************************* - a convenient addition to interpret_addr() - ******************************************************************/ -struct in_addr *interpret_addr2(char *str) -{ - static struct in_addr ret; - uint32 a = interpret_addr(str); - ret.s_addr = a; - return(&ret); -} - -/******************************************************************* - check if an IP is the 0.0.0.0 - ******************************************************************/ -BOOL zero_ip(struct in_addr ip) -{ - uint32 a; - putip((char *)&a,(char *)&ip); - return(a == 0); -} - - -/******************************************************************* - matchname - determine if host name matches IP address - ******************************************************************/ -static BOOL matchname(char *remotehost,struct in_addr addr) -{ - struct hostent *hp; - int i; - - if ((hp = Get_Hostbyname(remotehost)) == 0) { - DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost)); - return False; - } - - /* - * Make sure that gethostbyname() returns the "correct" host name. - * Unfortunately, gethostbyname("localhost") sometimes yields - * "localhost.domain". Since the latter host name comes from the - * local DNS, we just have to trust it (all bets are off if the local - * DNS is perverted). We always check the address list, though. - */ - - if (strcasecmp(remotehost, hp->h_name) - && strcasecmp(remotehost, "localhost")) { - DEBUG(0,("host name/name mismatch: %s != %s", - remotehost, hp->h_name)); - return False; - } - - /* Look up the host address in the address list we just got. */ - for (i = 0; hp->h_addr_list[i]; i++) { - if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0) - return True; - } - - /* - * The host name does not map to the original host address. Perhaps - * someone has compromised a name server. More likely someone botched - * it, but that could be dangerous, too. - */ - - DEBUG(0,("host name/address mismatch: %s != %s", - inet_ntoa(addr), hp->h_name)); - return False; -} - -/******************************************************************* - Reset the 'done' variables so after a client process is created - from a fork call these calls will be re-done. This should be - expanded if more variables need reseting. - ******************************************************************/ - -static BOOL global_client_name_done = False; -static BOOL global_client_addr_done = False; - -void reset_globals_after_fork() -{ - global_client_name_done = False; - global_client_addr_done = False; -} - -/******************************************************************* - return the DNS name of the client - ******************************************************************/ -char *client_name(void) -{ - extern int Client; - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static pstring name_buf; - struct hostent *hp; - - if (global_client_name_done) - return name_buf; - - strcpy(name_buf,"UNKNOWN"); - - if (getpeername(Client, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); - return name_buf; - } - - /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *) &sockin->sin_addr, - sizeof(sockin->sin_addr), - AF_INET)) == 0) { - DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr())); - StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1); - } else { - StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); - if (!matchname(name_buf, sockin->sin_addr)) { - DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr())); - strcpy(name_buf,"UNKNOWN"); - } - } - global_client_name_done = True; - return name_buf; -} - -/******************************************************************* - return the IP addr of the client as a string - ******************************************************************/ -char *client_addr(void) -{ - extern int Client; - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static fstring addr_buf; - - if (global_client_addr_done) - return addr_buf; - - strcpy(addr_buf,"0.0.0.0"); - - if (getpeername(Client, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); - return addr_buf; - } - - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - - global_client_addr_done = True; - return addr_buf; -} - -/******************************************************************* -sub strings with useful parameters -Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and -Paul Rippin <pr3245@nopc.eurostat.cec.be> -********************************************************************/ -void standard_sub_basic(char *str) - { - char *s, *p; - char pidstr[10]; - struct passwd *pass; - - for (s = str ; (p = strchr(s,'%')) != NULL ; s = p ) - { - switch (*(p+1)) - { - case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL) - string_sub(p,"%G",gidtoname(pass->pw_gid)); - else - p += 2; - break; - case 'I' : string_sub(p,"%I",client_addr()); break; - case 'L' : string_sub(p,"%L",local_machine); break; - case 'M' : string_sub(p,"%M",client_name()); break; - case 'R' : string_sub(p,"%R",remote_proto); break; - case 'T' : string_sub(p,"%T",timestring()); break; - case 'U' : string_sub(p,"%U",sesssetup_user); break; - case 'a' : string_sub(p,"%a",remote_arch); break; - case 'd' : sprintf(pidstr,"%d",(int)getpid()); - string_sub(p,"%d",pidstr); - break; - case 'h' : string_sub(p,"%h",myhostname); break; - case 'm' : string_sub(p,"%m",remote_machine); break; - case 'v' : string_sub(p,"%v",VERSION); break; - case '\0' : p++; break; /* don't run off end if last character is % */ - default : p+=2; break; - } - } - return; -} - -/******************************************************************* -are two IPs on the same subnet? -********************************************************************/ -BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) -{ - uint32 net1,net2,nmask; - - nmask = ntohl(mask.s_addr); - net1 = ntohl(ip1.s_addr); - net2 = ntohl(ip2.s_addr); - - return((net1 & nmask) == (net2 & nmask)); -} - - -/******************************************************************* -write a string in unicoode format -********************************************************************/ -int PutUniCode(char *dst,char *src) -{ - int ret = 0; - while (*src) { - dst[ret++] = src[0]; - dst[ret++] = 0; - src++; - } - dst[ret++]=0; - dst[ret++]=0; - return(ret); -} - -/**************************************************************************** -a wrapper for gethostbyname() that tries with all lower and all upper case -if the initial name fails -****************************************************************************/ -struct hostent *Get_Hostbyname(char *name) -{ - char *name2 = strdup(name); - struct hostent *ret; - - if (!name2) - { - DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n")); - exit(0); - } - - if (!isalnum(*name2)) - { - free(name2); - return(NULL); - } - - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* try with all lowercase */ - strlower(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* try with all uppercase */ - strupper(name2); - ret = sys_gethostbyname(name2); - if (ret != NULL) - { - free(name2); - return(ret); - } - - /* nothing works :-( */ - free(name2); - return(NULL); -} - - -/**************************************************************************** -check if a process exists. Does this work on all unixes? -****************************************************************************/ -BOOL process_exists(int pid) -{ -#ifdef LINUX - fstring s; - sprintf(s,"/proc/%d",pid); - return(directory_exist(s,NULL)); -#else - { - static BOOL tested=False; - static BOOL ok=False; - fstring s; - if (!tested) { - tested = True; - sprintf(s,"/proc/%05d",(int)getpid()); - ok = file_exist(s,NULL); - } - if (ok) { - sprintf(s,"/proc/%05d",pid); - return(file_exist(s,NULL)); - } - } - - /* CGH 8/16/96 - added ESRCH test */ - return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH); -#endif -} - - -/******************************************************************* -turn a uid into a user name -********************************************************************/ -char *uidtoname(int uid) -{ - static char name[40]; - struct passwd *pass = getpwuid(uid); - if (pass) return(pass->pw_name); - sprintf(name,"%d",uid); - return(name); -} - -/******************************************************************* -turn a gid into a group name -********************************************************************/ -char *gidtoname(int gid) -{ - static char name[40]; - struct group *grp = getgrgid(gid); - if (grp) return(grp->gr_name); - sprintf(name,"%d",gid); - return(name); -} - -/******************************************************************* -block sigs -********************************************************************/ -void BlockSignals(BOOL block,int signum) -{ -#ifdef USE_SIGBLOCK - int block_mask = sigmask(signum); - static int oldmask = 0; - if (block) - oldmask = sigblock(block_mask); - else - sigsetmask(oldmask); -#elif defined(USE_SIGPROCMASK) - sigset_t set; - sigemptyset(&set); - sigaddset(&set,signum); - sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); -#endif -} - -#if AJT -/******************************************************************* -my own panic function - not suitable for general use -********************************************************************/ -void ajt_panic(void) -{ - system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT"); -} -#endif - -#ifdef USE_DIRECT -#define DIRECT direct -#else -#define DIRECT dirent -#endif - -/******************************************************************* -a readdir wrapper which just returns the file name -also return the inode number if requested -********************************************************************/ -char *readdirname(void *p) -{ - struct DIRECT *ptr; - char *dname; - - if (!p) return(NULL); - - ptr = (struct DIRECT *)readdir(p); - if (!ptr) return(NULL); - - dname = ptr->d_name; - -#ifdef NEXT2 - if (telldir(p) < 0) return(NULL); -#endif - -#ifdef SUNOS5 - /* this handles a broken compiler setup, causing a mixture - of BSD and SYSV headers and libraries */ - { - static BOOL broken_readdir = False; - if (!broken_readdir && !(*(dname)) && strequal("..",dname-2)) - { - DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n")); - broken_readdir = True; - } - if (broken_readdir) - dname = dname - 2; - } -#endif - - { - static pstring buf; - pstrcpy(buf, dname); - unix_to_dos(buf, True); - dname = buf; - } - - return(dname); -} - -/******************************************************************* - Utility function used to decide if the last component - of a path matches a (possibly wildcarded) entry in a namelist. -********************************************************************/ - -BOOL is_in_path(char *name, name_compare_entry *namelist) -{ - pstring last_component; - char *p; - - DEBUG(8, ("is_in_path: %s\n", name)); - - /* if we have no list it's obviously not in the path */ - if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) - { - DEBUG(8,("is_in_path: no name list.\n")); - return False; - } - - /* Get the last component of the unix name. */ - p = strrchr(name, '/'); - strncpy(last_component, p ? p : name, sizeof(last_component)-1); - last_component[sizeof(last_component)-1] = '\0'; - - for(; namelist->name != NULL; namelist++) - { - if(namelist->is_wild) - { - /* look for a wildcard match. */ - if (mask_match(last_component, namelist->name, case_sensitive, False)) - { - DEBUG(8,("is_in_path: mask match succeeded\n")); - return True; - } - } - else - { - if((case_sensitive && (strcmp(last_component, namelist->name) == 0))|| - (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) - { - DEBUG(8,("is_in_path: match succeeded\n")); - return True; - } - } - } - DEBUG(8,("is_in_path: match not found\n")); - - return False; -} - -/******************************************************************* - Strip a '/' separated list into an array of - name_compare_enties structures suitable for - passing to is_in_path(). We do this for - speed so we can pre-parse all the names in the list - and don't do it for each call to is_in_path(). - namelist is modified here and is assumed to be - a copy owned by the caller. - We also check if the entry contains a wildcard to - remove a potentially expensive call to mask_match - if possible. -********************************************************************/ - -void set_namearray(name_compare_entry **ppname_array, char *namelist) -{ - char *name_end; - char *nameptr = namelist; - int num_entries = 0; - int i; - - (*ppname_array) = NULL; - - if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) - return; - - /* We need to make two passes over the string. The - first to count the number of elements, the second - to split it. - */ - while(*nameptr) - { - if ( *nameptr == '/' ) - { - /* cope with multiple (useless) /s) */ - nameptr++; - continue; - } - /* find the next / */ - name_end = strchr(nameptr, '/'); - - /* oops - the last check for a / didn't find one. */ - if (name_end == NULL) - break; - - /* next segment please */ - nameptr = name_end + 1; - num_entries++; - } - - if(num_entries == 0) - return; - - if(( (*ppname_array) = (name_compare_entry *)malloc( - (num_entries + 1) * sizeof(name_compare_entry))) == NULL) - { - DEBUG(0,("set_namearray: malloc fail\n")); - return; - } - - /* Now copy out the names */ - nameptr = namelist; - i = 0; - while(*nameptr) - { - if ( *nameptr == '/' ) - { - /* cope with multiple (useless) /s) */ - nameptr++; - continue; - } - /* find the next / */ - if ((name_end = strchr(nameptr, '/')) != NULL) - { - *name_end = 0; - } - - /* oops - the last check for a / didn't find one. */ - if(name_end == NULL) - break; - - (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) || - (strchr( nameptr, '*')!=NULL)); - if(((*ppname_array)[i].name = strdup(nameptr)) == NULL) - { - DEBUG(0,("set_namearray: malloc fail (1)\n")); - return; - } - - /* next segment please */ - nameptr = name_end + 1; - i++; - } - - (*ppname_array)[i].name = NULL; - - return; -} - -/**************************************************************************** -routine to free a namearray. -****************************************************************************/ - -void free_namearray(name_compare_entry *name_array) -{ - if(name_array == 0) - return; - - if(name_array->name != NULL) - free(name_array->name); - - free((char *)name_array); -} - -/**************************************************************************** -routine to do file locking -****************************************************************************/ -BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) -{ -#if HAVE_FCNTL_LOCK - struct flock lock; - int ret; - -#if 1 - uint32 mask = 0xC0000000; - - /* make sure the count is reasonable, we might kill the lockd otherwise */ - count &= ~mask; - - /* the offset is often strange - remove 2 of its bits if either of - the top two bits are set. Shift the top ones by two bits. This - still allows OLE2 apps to operate, but should stop lockd from - dieing */ - if ((offset & mask) != 0) - offset = (offset & ~mask) | ((offset & mask) >> 2); -#else - uint32 mask = ((unsigned)1<<31); - - /* interpret negative counts as large numbers */ - if (count < 0) - count &= ~mask; - - /* no negative offsets */ - offset &= ~mask; - - /* count + offset must be in range */ - while ((offset < 0 || (offset + count < 0)) && mask) - { - offset &= ~mask; - mask = mask >> 1; - } -#endif - - - DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = (int)offset; - lock.l_len = (int)count; - lock.l_pid = 0; - - errno = 0; - - ret = fcntl(fd,op,&lock); - - if (errno != 0) - DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); - - /* a lock query */ - if (op == F_GETLK) - { - if ((ret != -1) && - (lock.l_type != F_UNLCK) && - (lock.l_pid != 0) && - (lock.l_pid != getpid())) - { - DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid)); - return(True); - } - - /* it must be not locked or locked by me */ - return(False); - } - - /* a lock set or unset */ - if (ret == -1) - { - DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n", - offset,count,op,type,strerror(errno))); - - /* perhaps it doesn't support this sort of locking?? */ - if (errno == EINVAL) - { - DEBUG(3,("locking not supported? returning True\n")); - return(True); - } - - return(False); - } - - /* everything went OK */ - DEBUG(8,("Lock call successful\n")); - - return(True); -#else - return(False); -#endif -} - -/******************************************************************* -lock a file - returning a open file descriptor or -1 on failure -The timeout is in seconds. 0 means no timeout -********************************************************************/ -int file_lock(char *name,int timeout) -{ - int fd = open(name,O_RDWR|O_CREAT,0666); - time_t t=0; - if (fd < 0) return(-1); - -#if HAVE_FCNTL_LOCK - if (timeout) t = time(NULL); - while (!timeout || (time(NULL)-t < timeout)) { - if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd); - msleep(LOCK_RETRY_TIMEOUT); - } - return(-1); -#else - return(fd); -#endif -} - -/******************************************************************* -unlock a file locked by file_lock -********************************************************************/ -void file_unlock(int fd) -{ - if (fd<0) return; -#if HAVE_FCNTL_LOCK - fcntl_lock(fd,F_SETLK,0,1,F_UNLCK); -#endif - close(fd); -} - -/******************************************************************* -is the name specified one of my netbios names -returns true is it is equal, false otherwise -********************************************************************/ -BOOL is_myname(char *s) -{ - int n; - BOOL ret = False; - - for (n=0; my_netbios_names[n]; n++) { - if (strequal(my_netbios_names[n], s)) - ret=True; - } - DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); - return(ret); -} - -/******************************************************************* -set the horrid remote_arch string based on an enum. -********************************************************************/ -void set_remote_arch(enum remote_arch_types type) -{ - ra_type = type; - switch( type ) - { - case RA_WFWG: - strcpy(remote_arch, "WfWg"); - return; - case RA_OS2: - strcpy(remote_arch, "OS2"); - return; - case RA_WIN95: - strcpy(remote_arch, "Win95"); - return; - case RA_WINNT: - strcpy(remote_arch, "WinNT"); - return; - case RA_SAMBA: - strcpy(remote_arch,"Samba"); - return; - default: - ra_type = RA_UNKNOWN; - strcpy(remote_arch, "UNKNOWN"); - break; - } -} - -/******************************************************************* - Get the remote_arch type. -********************************************************************/ -enum remote_arch_types get_remote_arch() -{ - return ra_type; -} - - -/******************************************************************* -skip past some unicode strings in a buffer -********************************************************************/ -char *skip_unicode_string(char *buf,int n) -{ - while (n--) - { - while (*buf) - buf += 2; - buf += 2; - } - return(buf); -} - -/******************************************************************* -Return a ascii version of a unicode string -Hack alert: uses fixed buffer(s) and only handles ascii strings -********************************************************************/ -#define MAXUNI 1024 -char *unistr2(uint16 *buf) -{ - static char lbufs[8][MAXUNI]; - static int nexti; - char *lbuf = lbufs[nexti]; - char *p; - nexti = (nexti+1)%8; - for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++) - { - *p = *buf; - } - *p = 0; - return lbuf; -} - -/******************************************************************* -Return a ascii version of a unicode string -Hack alert: uses fixed buffer(s) and only handles ascii strings -********************************************************************/ -#define MAXUNI 1024 -char *unistr(char *buf) -{ - static char lbufs[8][MAXUNI]; - static int nexti; - char *lbuf = lbufs[nexti]; - char *p; - - nexti = (nexti+1)%8; - - for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2) - { - *p = *buf; - } - *p = 0; - return lbuf; -} - -/******************************************************************* -strncpy for unicode strings -********************************************************************/ -int unistrncpy(char *dst, char *src, int len) -{ - int num_wchars = 0; - - while (*src && len > 0) - { - *dst++ = *src++; - *dst++ = *src++; - len--; - num_wchars++; - } - *dst++ = 0; - *dst++ = 0; - - return num_wchars; -} - - -/******************************************************************* -strcpy for unicode strings. returns length (in num of wide chars) -********************************************************************/ -int unistrcpy(char *dst, char *src) -{ - int num_wchars = 0; - - while (*src) - { - *dst++ = *src++; - *dst++ = *src++; - num_wchars++; - } - *dst++ = 0; - *dst++ = 0; - - return num_wchars; -} - - -/******************************************************************* -safe string copy into a fstring -********************************************************************/ -void fstrcpy(char *dest, char *src) -{ - int maxlength = sizeof(fstring) - 1; - if (!dest) { - DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); - return; - } - - if (!src) { - *dest = 0; - return; - } - - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", - strlen(src))); - } -} - -/******************************************************************* -safe string copy into a pstring -********************************************************************/ -void pstrcpy(char *dest, char *src) -{ - int maxlength = sizeof(pstring) - 1; - if (!dest) { - DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); - return; - } - - if (!src) { - *dest = 0; - return; - } - - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", - strlen(src))); - } -} - - -/******************************************************************* -align a pointer to a multiple of 4 bytes -********************************************************************/ -char *align4(char *q, char *base) -{ - if ((q - base) & 3) - { - q += 4 - ((q - base) & 3); - } - return q; -} - -/******************************************************************* -align a pointer to a multiple of 2 bytes -********************************************************************/ -char *align2(char *q, char *base) -{ - if ((q - base) & 1) - { - q++; - } - return q; -} - -/******************************************************************* -align a pointer to a multiple of align_offset bytes. looks like it -will work for offsets of 0, 2 and 4... -********************************************************************/ -char *align_offset(char *q, char *base, int align_offset_len) -{ - if (align_offset_len != 0 && ((q - base) & (align_offset_len-1))) - { - q += align_offset_len - ((q - base) & (align_offset_len)); - } - return q; -} - |