1
1

* smbfs.c: Allow username in URL (/#smb:[user@]machine) and

reformat changed functions.
(smbfs_get_host_and_username): Fix comment.
(smbfs_fill_names): Add username@ before hostname.
(smbfs_open_link): Use IPC$ if share is empty.
(smbfs_get_path): Pass remote_path to smbfs_open_link().
(smbfs_stat): Copy username@ to server_url if passed.
Этот коммит содержится в:
Andrew V. Samoilov 2002-10-09 13:18:10 +00:00
родитель c8b0c913b7
Коммит 872e77eb1d
2 изменённых файлов: 194 добавлений и 201 удалений

Просмотреть файл

@ -1,3 +1,13 @@
2002-10-09 Andrew V. Samoilov <sav@bcs.zp.ua>
* smbfs.c: Allow username in URL (/#smb:[user@]machine) and
reformat changed functions.
(smbfs_get_host_and_username): Fix comment.
(smbfs_fill_names): Add username@ before hostname.
(smbfs_open_link): Use IPC$ if share is empty.
(smbfs_get_path): Pass remote_path to smbfs_open_link().
(smbfs_stat): Copy username@ to server_url if passed.
2002-10-07 Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz> 2002-10-07 Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
* ftpfs.c (linear_abort): Add a timeout after which a reconnect * ftpfs.c (linear_abort): Add a timeout after which a reconnect
@ -75,7 +85,7 @@
2002-09-24 Andrew V. Samoilov <sav@bcs.zp.ua> 2002-09-24 Andrew V. Samoilov <sav@bcs.zp.ua>
* smbfs.c: Undef USE_NCURSES - no needs to include *curces.h. * smbfs.c: Undef USE_NCURSES - no needs to include *curses.h.
(smbfs_loaddir): Fix warning. (smbfs_loaddir): Fix warning.
2002-09-21 Pavel Roskin <proski@gnu.org> 2002-09-21 Pavel Roskin <proski@gnu.org>

Просмотреть файл

@ -323,7 +323,8 @@ smbfs_fill_names (vfs *me, void (*func)(char *))
for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++) { for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++) {
if (smbfs_connections [i].cli) { if (smbfs_connections [i].cli) {
path = g_strconcat (URL_HEADER, path = g_strconcat (URL_HEADER,
smbfs_connections[i].host, smbfs_connections[i].user, "@",
smbfs_connections[i].host,
"/", smbfs_connections[i].service, "/", smbfs_connections[i].service,
NULL); NULL);
(*func)(path); (*func)(path);
@ -845,30 +846,10 @@ smbfs_symlink (vfs *me, char *n1, char *n2)
} }
/* Extract the hostname and username from the path */ /* Extract the hostname and username from the path */
/* path is in the form: hostname:user/remote-dir */ /* path is in the form: [user@]hostname/share/remote-dir */
#if 0
static char *
smbfs_get_host_and_username
(char **path, char **host, char **user, int *port, char **pass)
{
/* char *p, *ret; */
char *ret;
ret = vfs_split_url (*path, host, user, port, pass, SMB_PORT, 0);
#if 0
if ((p = strchr(*path, '@'))) /* user:pass@server */
*path = ++p; /* don't want user:pass@ in path */
if ((p = strchr(ret, '@'))) /* user:pass@server */
ret = ++p; /* don't want user:pass@ in path */
#endif
return ret;
}
#else
#define smbfs_get_host_and_username(path, host, user, port, pass) \ #define smbfs_get_host_and_username(path, host, user, port, pass) \
vfs_split_url (*path, host, user, port, pass, SMB_PORT, 0) vfs_split_url (*path, host, user, port, pass, SMB_PORT, 0)
#endif
/***************************************************** /*****************************************************
return a connection to a SMB server return a connection to a SMB server
current_bucket needs to be set before calling current_bucket needs to be set before calling
@ -1031,150 +1012,147 @@ smbfs_get_free_bucket ()
/* This routine keeps track of open connections */ /* This routine keeps track of open connections */
/* Returns a connected socket to host */ /* Returns a connected socket to host */
static smbfs_connection * static smbfs_connection *
smbfs_open_link(char *host, char *path, const char *user, int *port, char *this_pass) smbfs_open_link (char *host, char *path, const char *user, int *port,
char *this_pass)
{ {
int i; int i;
smbfs_connection *bucket; smbfs_connection *bucket;
pstring service; pstring service;
struct in_addr *dest_ip = NULL; struct in_addr *dest_ip = NULL;
DEBUG(3, ("smbfs_open_link(host:%s, path:%s)\n", host, path)); DEBUG (3, ("smbfs_open_link(host:%s, path:%s)\n", host, path));
if (strcmp(host, path) == 0) /* if host & path are same: */ if (strcmp (host, path) == 0) /* if host & path are same: */
pstrcpy(service, IPC); /* setup for browse */ pstrcpy (service, IPC); /* setup for browse */
else { /* get share name from path, path starts with server name */ else { /* get share name from path, path starts with server name */
char *p; char *p;
if ((p = strchr(path, '/'))) /* get share aka */ if ((p = strchr (path, '/'))) /* get share aka */
pstrcpy(service, ++p); /* service name from path */ pstrcpy (service, ++p); /* service name from path */
else else
pstrcpy(service, ""); pstrcpy (service, "");
/* now check for trailing directory/filenames */ /* now check for trailing directory/filenames */
p = strchr(service, '/'); p = strchr (service, '/');
if (p) if (p)
*p = 0; /* cut off dir/files: sharename only */ *p = 0; /* cut off dir/files: sharename only */
if (!*service)
pstrcpy (service, IPC); /* setup for browse */
DEBUG (6, ("smbfs_open_link: service from path:%s\n", service));
}
DEBUG(6, ("smbfs_open_link: service from path:%s\n", service)); if (got_user)
} user = username; /* global from getenv */
if (got_user)
user = username; /* global from getenv */
/* Is the link actually open? */ /* Is the link actually open? */
for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++) { for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++) {
if (!smbfs_connections[i].cli) if (!smbfs_connections[i].cli)
continue; continue;
if ((strcmp (host, smbfs_connections [i].host) == 0) && if ((strcmp (host, smbfs_connections[i].host) == 0) &&
(strcmp (user, smbfs_connections [i].user) == 0) && (strcmp (user, smbfs_connections[i].user) == 0) &&
(strcmp (service, smbfs_connections [i].service) == 0)) { (strcmp (service, smbfs_connections[i].service) == 0)) {
int retries = 0; int retries = 0;
BOOL inshare = (*host != 0 && *path != 0 && strchr(path, '/')); BOOL inshare = (*host != 0 && *path != 0 && strchr (path, '/'));
/* check if this connection has died */ /* check if this connection has died */
while (!chkpath(smbfs_connections[i].cli, "\\", !inshare)) { while (!chkpath (smbfs_connections[i].cli, "\\", !inshare)) {
if (!reconnect(&smbfs_connections[i], &retries)) if (!reconnect (&smbfs_connections[i], &retries))
return 0; return 0;
} }
DEBUG(6, ("smbfs_open_link: returning smbfs_connection[%d]\n", i)); DEBUG (6, ("smbfs_open_link: returning smbfs_connection[%d]\n", i));
current_bucket = &smbfs_connections[i]; current_bucket = &smbfs_connections[i];
smbfs_connections [i].last_use = time(NULL); smbfs_connections[i].last_use = time (NULL);
return &smbfs_connections [i]; return &smbfs_connections[i];
} }
/* connection not found, find if we have ip for new connection */ /* connection not found, find if we have ip for new connection */
if (strcmp (host, smbfs_connections [i].host) == 0) if (strcmp (host, smbfs_connections[i].host) == 0)
dest_ip = &smbfs_connections[i].cli->dest_ip; dest_ip = &smbfs_connections[i].cli->dest_ip;
} }
/* make new connection */ /* make new connection */
bucket = smbfs_get_free_bucket (); bucket = smbfs_get_free_bucket ();
bucket->name_type = 0x20; bucket->name_type = 0x20;
bucket->home = 0; bucket->home = 0;
bucket->port = *port; bucket->port = *port;
bucket->have_ip = False; bucket->have_ip = False;
if (dest_ip) { if (dest_ip) {
bucket->have_ip = True; bucket->have_ip = True;
bucket->dest_ip = *dest_ip; bucket->dest_ip = *dest_ip;
} }
current_bucket = bucket; current_bucket = bucket;
bucket->user = g_strdup(user); bucket->user = g_strdup (user);
bucket->service = g_strdup (service); bucket->service = g_strdup (service);
if (!(*host)) { /* if blank host name, browse for servers */ if (!(*host)) { /* if blank host name, browse for servers */
if (!get_master_browser(&host)) /* set host to ip of master browser */ if (!get_master_browser (&host)) /* set host to ip of master browser */
return 0; /* couldnt find master browser? */ return 0; /* could not find master browser? */
g_free (host); g_free (host);
bucket->host = g_strdup(""); /* blank host means master browser */ bucket->host = g_strdup (""); /* blank host means master browser */
} else } else
bucket->host = g_strdup(host); bucket->host = g_strdup (host);
if (!bucket_set_authinfo (bucket, if (!bucket_set_authinfo (bucket, 0, /* domain currently not used */
0, /* domain currently not used */ user, this_pass, 1))
user, return 0;
this_pass,
1))
return 0;
/* connect to share */ /* connect to share */
while (!(bucket->cli = smbfs_do_connect(host, service))) { while (!(bucket->cli = smbfs_do_connect (host, service))) {
if (my_errno != EPERM) if (my_errno != EPERM)
return 0; return 0;
message_1s (1, MSG_ERROR, message_1s (1, MSG_ERROR, _(" Authentication failed "));
_(" Authentication failed "));
/* authentication failed, try again */ /* authentication failed, try again */
authinfo_remove (bucket->host, bucket->service); authinfo_remove (bucket->host, bucket->service);
if (!bucket_set_authinfo (bucket, if (!bucket_set_authinfo (bucket, bucket->domain, bucket->user, 0, 0))
bucket->domain, return 0;
bucket->user,
0,
0))
return 0;
} }
smbfs_open_connections++; smbfs_open_connections++;
DEBUG(3, ("smbfs_open_link:smbfs_open_connections: %d\n", DEBUG (3, ("smbfs_open_link:smbfs_open_connections: %d\n",
smbfs_open_connections)); smbfs_open_connections));
return bucket; return bucket;
} }
static char * static char *
smbfs_get_path(smbfs_connection **sc, char *path) smbfs_get_path (smbfs_connection ** sc, char *path)
{ {
char *user, *host, *remote_path, *pass; char *user, *host, *remote_path, *pass;
int port = SMB_PORT; int port = SMB_PORT;
DEBUG(3, ("smbfs_get_path(%s)\n", path)); DEBUG (3, ("smbfs_get_path(%s)\n", path));
if (strncmp (path, URL_HEADER, HEADER_LEN)) if (strncmp (path, URL_HEADER, HEADER_LEN))
return NULL; return NULL;
path += HEADER_LEN; path += HEADER_LEN;
if (*path == '/') /* '/' leading server name */ if (*path == '/') /* '/' leading server name */
path++; /* probably came from server browsing */ path++; /* probably came from server browsing */
if ((remote_path = smbfs_get_host_and_username( if ((remote_path =
&path, &host, &user, &port, &pass))) smbfs_get_host_and_username (&path, &host, &user, &port, &pass)))
if ((*sc = smbfs_open_link (host, path, user, &port, pass)) == NULL){ if ((*sc =
g_free (remote_path); smbfs_open_link (host, remote_path, user, &port, pass)) == NULL) {
remote_path = NULL; g_free (remote_path);
} remote_path = NULL;
}
g_free (host); g_free (host);
g_free (user); g_free (user);
if (pass) wipe_password (pass); if (pass)
wipe_password (pass);
if (!remote_path) return NULL; if (!remote_path)
return NULL;
/* NOTE: tildes are deprecated. See ftpfs.c */ /* NOTE: tildes are deprecated. See ftpfs.c */
{ {
int f = !strcmp( remote_path, "/~" ); int f = !strcmp (remote_path, "/~");
if (f || !strncmp( remote_path, "/~/", 3 )) { if (f || !strncmp (remote_path, "/~/", 3)) {
char *s; char *s;
s = concat_dir_and_file( (*sc)->home, remote_path +3-f ); s = concat_dir_and_file ((*sc)->home, remote_path + 3 - f);
g_free (remote_path); g_free (remote_path);
return s; return s;
}
} }
return remote_path; }
return remote_path;
} }
#if 0 #if 0
@ -1457,95 +1435,100 @@ loaddir(vfs *me, const char *path)
} }
static int static int
smbfs_stat (vfs *me, char *path, struct stat *buf) smbfs_stat (vfs * me, char *path, struct stat *buf)
{ {
char *remote_dir; smbfs_connection *sc;
smbfs_connection *sc; pstring server_url;
pstring server_url; char *service, *pp;
char *service, *pp; const char *p;
const char *p;
DEBUG(3, ("smbfs_stat(path:%s)\n", path)); DEBUG (3, ("smbfs_stat(path:%s)\n", path));
#if 0 if (!current_info) {
if (p = strchr(path, '@')) /* user:pass@server */ DEBUG (1, ("current_info = NULL: "));
path = ++p; /* don't want user:pass@ in path */ if (loaddir (me, path) < 0)
#endif return -1;
}
if (!current_info) { /* check if stating server */
DEBUG(1, ("current_info = NULL: ")); p = path;
if (loaddir(me, path) < 0) if (strncmp (p, URL_HEADER, HEADER_LEN)) {
return -1; DEBUG (1, ("'%s' doesnt start with '%s' (length %d)\n",
p, URL_HEADER, HEADER_LEN));
return -1;
}
p += HEADER_LEN;
if (*p == '/')
p++;
pp = strchr (p, '/'); /* advance past next '/' */
pstrcpy (server_url, URL_HEADER);
if (pp) {
char *t = strchr (p, '@');
if (t && t < pp) { /* user@server */
*t = 0;
pstrcat (server_url, p);
pstrcat (server_url, "@");
*t = '@';
} }
}
pstrcat (server_url, current_bucket->host);
pstrcpy(server_url, URL_HEADER); if (!pp) {
pstrcat(server_url, current_bucket->host); if (!current_info->server_list) {
if (loaddir (me, path) < 0)
/* check if stating server */
p = path;
if (strncmp(p, URL_HEADER, HEADER_LEN)) {
DEBUG(1, ("'%s' doesnt start with '%s' (length %d)\n",
p, URL_HEADER, HEADER_LEN));
return -1; return -1;
} }
return fake_server_stat (server_url, path, buf);
}
if (!strchr (++pp, '/')) {
return fake_share_stat (server_url, path, buf);
}
p += HEADER_LEN; /* stating inside share at this point */
if (*p == '/') if (!(service = smbfs_get_path (&sc, path))) /* connects if necessary */
p++; return -1;
pp = strchr(p, '/'); /* advance past next '/' */ {
if (!pp) { int hostlen = strlen (current_bucket->host);
if (!current_info->server_list) { char *pp = service + strlen (service) - hostlen;
if (loaddir(me, path) < 0) char *sp = server_url + strlen (server_url) - hostlen;
return -1;
}
return fake_server_stat(server_url, path, buf);
}
if (!strchr(++pp, '/')) {
return fake_share_stat(server_url, path, buf);
}
/* stating inside share at this point */ if (strcmp (sp, pp) == 0) {
if (!(remote_dir = smbfs_get_path (&sc, path))) /* connects if necessary */ /* make server name appear as directory */
return -1; DEBUG (1, ("smbfs_stat: showing server as directory\n"));
g_free (remote_dir); memset (buf, 0, sizeof (struct stat));
{ buf->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH;
int hostlen = strlen(current_bucket->host); g_free (service);
char *pp = path + strlen(path)-hostlen; return 0;
char *sp = server_url + strlen(server_url)-hostlen;
if (strcmp(sp, pp) == 0) {
/* make server name appear as directory */
DEBUG(1, ("smbfs_stat: showing server as directory\n"));
memset(buf, 0, sizeof(struct stat));
buf->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH;
return 0;
}
} }
/* check if current_info is in share requested */ }
p = service = g_strdup(p); /* check if current_info is in share requested */
pp = strchr(p, '/'); p = service;
if (pp) { pp = strchr (p, '/');
p = ++pp; /* advance past server name */ if (pp) {
pp = strchr(p, '/'); p = ++pp; /* advance past server name */
pp = strchr (p, '/');
}
if (pp)
*pp = 0; /* cut off everthing after service name */
else
p = IPC; /* browsing for services */
pp = current_info->dirname;
if (*pp == '/')
pp++;
if (strncmp (p, pp, strlen (p)) != 0) {
DEBUG (6, ("desired '%s' is not loaded, we have '%s'\n", p, pp));
if (loaddir (me, path) < 0) {
g_free (service);
return -1;
} }
if (pp) DEBUG (6, ("loaded dir: '%s'\n", current_info->dirname));
*pp = 0; /* cut off everthing after service name */ }
else g_free (service);
p = IPC; /* browsing for services */ /* stat dirs & files under shares now */
pp = current_info->dirname; return get_stat_info (sc, path, buf);
if (*pp == '/');
pp++;
if (strncmp(p, pp, strlen(p)) != 0) {
DEBUG(6, ("desired '%s' is not loaded, we have '%s'\n", p, pp));
if (loaddir(me, path) < 0) {
g_free (service);
return -1;
}
DEBUG(6, ("loaded dir: '%s'\n", current_info->dirname));
}
g_free(service);
/* stat dirs & files under shares now */
return get_stat_info(sc, path, buf);
} }
#define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */ #define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */