[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