2 Unix SMB/Netbios implementation.
4 MSDfs services for Samba
5 Copyright (C) Shirish Kalele 2000
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 /***********************************************************************
23 * Parses the per-service Dfs map file which is of the form:
25 * alternate_path1:proximity:ttl
26 * alternate_path2:proximity:ttl
30 * Junction points are directories in the service (upon encountering which
31 * Samba redirects the client to the servers hosting the underlying share)
33 * Alternate paths are of the form: \\smbserver\share
34 * Currently, the parser detects alternate paths by the leading \'s
36 ***********************************************************************/
42 #define MAX_ALTERNATE_PATHS 256
44 extern int DEBUGLEVEL;
46 static char* Dfs_Crop_Whitespace(char* line)
49 int len = strlen(line);
51 if(line[0]=='#' || line[0]==';') return NULL;
53 for(i=0;i<len && line[i]==' ';i++);
55 if(i>=len) return NULL;
59 /* crop off the newline at the end, if present */
60 /* if(line[len-1]=='\n') line[len-1]='\0'; */
62 /* remove white sace from the end */
63 for(i=strlen(line)-1;i>=0 && isspace(line[i]);i--);
69 if(line[0] == '\0') return NULL;
74 static BOOL parse_referral(char* s, struct referral* ref)
76 #define MAXTOK_IN_REFERRAL 3
77 char *tok[MAXTOK_IN_REFERRAL+1];
81 if(s[1]=='\\') s = &s[1]; /* skip one backslash
84 tok[count++] = strtok(s,":");
86 while( ((tok[count]=strtok(NULL,":")) != NULL) && count<MAXTOK_IN_REFERRAL)
89 DEBUG(10,("parse_referral: Tokens"));
91 DEBUG(10,(" %s",tok[i]));
94 pstrcpy(ref->alternate_path,tok[0]);
97 DEBUG(6,("Invalid referral line: %s\n",s));
102 ref->proximity = atoi(tok[1]);
107 ref->ttl = atoi(tok[2]);
109 ref->ttl = REFERRAL_TTL;
114 static BOOL load_dfsmap(char* fname, int snum)
116 struct junction_map* junction = NULL;
117 struct referral tmp_ref_array[MAX_ALTERNATE_PATHS];
121 if(lp_dfsmap_loaded(snum))
124 if((fp = sys_fopen(fname,"r")) == NULL)
126 DEBUG(1,("can't open dfs map file %s for service [%s]\nError was %s",fname,
127 lp_servicename(snum), strerror(errno)));
131 if(!msdfs_open(True))
139 if(!fgets(rawline,PSTRING_LEN,fp))
142 if((line = Dfs_Crop_Whitespace(rawline)) == NULL)
145 DEBUG(6,("load_dfsmap: Cropped line: %s\n",line));
147 /* the line contains a new junction or
148 an alternate path to current junction */
152 /* a junction encountered. add the current junction first */
155 junction->referral_count = ref_count;
156 junction->referral_list = tmp_ref_array;
157 DEBUG(4,("Adding Dfs junction: %s\\%s Referrals: %u First referral path: %s\n",
158 junction->service_name,junction->volume_name,
159 junction->referral_count, junction->referral_list[0].alternate_path));
161 if(!add_junction_entry(junction))
163 DEBUG(6,("Unable to add junction entry %s:%s after parsing\n",
164 junction->service_name,junction->volume_name));
169 /* then, create a new junction_map node */
170 if((junction = (struct junction_map*) malloc(sizeof(struct junction_map))) == NULL)
172 DEBUG(0,("Couldn't malloc for Dfs junction_map node\n"));
175 pstrcpy(junction->service_name,lp_servicename(snum));
176 pstrcpy(junction->volume_name,line);
181 /* referral encountered. add to current junction */
184 DEBUG(4,("Invalid entry in Dfs map file.\nAlternate path defined outside of a junction in line:\n%s\n",line));
188 /* parse the referral */
189 if(!parse_referral(line,&tmp_ref_array[ref_count]))
196 /* End of file. Add the current junction and return */
199 junction->referral_count = ref_count;
200 junction->referral_list = tmp_ref_array;
201 DEBUG(4,("Adding Dfs junction: %s\%s Referrals: %u First referral path: %s\n",
202 junction->service_name,junction->volume_name,
203 junction->referral_count, junction->referral_list[0].alternate_path));
204 if(!add_junction_entry(junction))
206 DEBUG(6,("Unable to add junction entry %s:%s after parsing\n",
207 junction->service_name,junction->volume_name));
217 void load_dfsmaps(void)
223 for(i=0;*lp_servicename(i) && *lp_dfsmap(i)
224 && !lp_dfsmap_loaded(i);i++)
226 char* dfsmapfile = lp_dfsmap(i);
227 DEBUG(4,("loading dfsmap for servicename: %s\n",lp_servicename(i)));
228 if(load_dfsmap(dfsmapfile,i))
230 set_dfsmap_loaded(i,True);
234 DEBUG(0,("handle_dfsmap: Unable to load Dfs map file %s.\nService %s not using MS Dfs",dfsmapfile,lp_servicename(i)));
235 set_dfsmap_loaded(i,False);
242 /* Stub function if MS_DFS is not defined */
244 void load_dfsmaps(void)