[code] smb_url.c
Michael B. Allen
mballen at erols.com
Thu Dec 28 09:26:50 GMT 2000
This might save you a few clock cycles Richard. Shouldn't be too hard
to adgust when the syntax is solidified. So far it parses:
smb://[[domain/]user[:pass]@][workgroup#]host[:port][/share[/path]]
into
struct smb_url *
Mike
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct smb_url {
char *domain;
char *username;
char *password;
char *workgroup;
char *host;
int port;
char *share;
char *path;
char *file;
};
void
smb_url_destroy(struct smb_url *url)
{
if (url) {
free(url->domain);
free(url->username);
free(url->password);
free(url->workgroup);
free(url->host);
free(url->share);
free(url->path);
free(url->file);
free(url);
}
}
char *
substring(const char *str, int from, int to)
{
char *result;
int size = to - from;
if (size < 1) {
return NULL;
}
result = malloc(size + 1);
memcpy(result, str + from, size);
result[size] = '\0';
/* printf("from: %d, to: %d result: >%s<\n", from, to, result); */
return result;
}
struct smb_url *
smb_url_parse(const char *str)
{
int len, start, end, share, path, i, user;
char *port;
struct smb_url *url = malloc(sizeof *url);
if (url) {
/*
* Must I initialize this struct? I get a core otherwise :~(
* How do I just malloc with zeros?
*/
url->domain = NULL;
url->username = NULL;
url->password = NULL;
url->workgroup = NULL;
url->host = NULL;
url->port = 0;
url->share = NULL;
url->path = NULL;
url->file = NULL;
if (str[0] != 's' ||
str[1] != 'm' ||
str[2] != 'b' ||
str[3] != ':' ||
str[4] != '/' ||
str[5] != '/' ) {
return NULL;
}
start = 6;
share = path = len = strlen(str);
end = len - 1;
while(end > start && str[end] != '@') {
if (str[end] == '/') {
path = share;
share = end;
}
end--;
}
url->share = substring(str, share + 1, path);
url->path = substring(str, path + 1, len);
if (str[end] == '@') {
i = start;
user = start;
while(i < end) {
if (str[i] == '/') {
url->domain = substring(str, start, i);
user = i + 1;
} else if (str[i] == ':') {
url->password = substring(str, i + 1, end);
break;
}
i++;
}
url->username = substring(str, user, i);
start = end + 1;
}
i = start;
while(i < share) {
if (str[i] == '#') {
url->workgroup = substring(str, start, i);
start = i + 1;
} else if (str[i] == ':') {
port = substring(str, i + 1, share);
if (port) {
url->port = atoi(port);
free(port);
}
share = i;
break;
}
i++;
}
url->host = substring(str, start, share);
}
return url;
}
/*
* smb://[[domain/]user[:pass]@][workgroup#]host[:port][/share[/path]]
*/
#define INPUT_SIZE 12
char *input[] = {
"smb://server",
"smb://server:567/share",
"smb://server/share/path",
"smb://server/share/some/sub/directory//path",
"smb://user@server:777/share/path",
"smb://domain/user:password@server",
"smb://user:p@a!s@server/share/path",
"smb://domain/user@server/share",
"smb://workgroup#",
"smb://workgroup#server:123",
"smb://user@workgroup#",
"smb://domain/username:password@workgroup#server:5139/share/dir/file"
};
int
main( int argc, char *argv[] )
{
int i;
struct smb_url *url;
for (i = 0; i < INPUT_SIZE; i++) {
printf("url: %s\n", input[i]);
url = smb_url_parse(input[i]);
if(url) {
printf(" host: %s\n", url->host);
printf(" share: %s\n", url->share);
printf(" path: %s\n", url->path);
printf(" domain: %s\n", url->domain);
printf(" username: %s\n", url->username);
printf(" password: %s\n", url->password);
printf("workgroup: %s\n", url->workgroup);
printf(" port: %d\n", url->port);
printf(" file: %s\n", url->file);
smb_url_destroy(url);
} else {
printf("error\n");
}
printf("\n");
}
return 0;
}
More information about the samba-technical
mailing list