summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-04-03 17:15:49 -0300
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2009-04-03 17:15:49 -0300
commitb3b18c152c26c9c514bab1af4cb9213ce2e2a5e5 (patch)
tree846de128480e3243cdefe5f929e68f3e6d01a8c6
parent478dedfec2e78cf436d33c1e00477bcffc81374a (diff)
downloadobexd-b3b18c152c26c9c514bab1af4cb9213ce2e2a5e5.tar.gz
Introduce symlinks option.
It can be use to enable symbolic links on root folder.
-rw-r--r--src/bluetooth.c10
-rw-r--r--src/bluetooth.h5
-rw-r--r--src/ftp.c70
-rw-r--r--src/main.c13
-rw-r--r--src/obex.h1
5 files changed, 79 insertions, 20 deletions
diff --git a/src/bluetooth.c b/src/bluetooth.c
index 10f3f8f..37d7b99 100644
--- a/src/bluetooth.c
+++ b/src/bluetooth.c
@@ -172,7 +172,8 @@ static gint server_stop(struct server *server)
static gint server_register(guint16 service, const gchar *name, guint8 channel,
const gchar *folder, gboolean secure,
- gboolean auto_accept, const gchar *capability)
+ gboolean auto_accept, gboolean symlinks,
+ const gchar *capability)
{
struct server *server;
int err;
@@ -182,6 +183,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
server->name = g_strdup(name);
server->folder = g_strdup(folder);
server->auto_accept = auto_accept;
+ server->symlinks = symlinks;
server->capability = g_strdup(capability);
server->channel = channel;
server->secure = secure;
@@ -203,10 +205,12 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
guint8 channel, gboolean secure,
- gboolean auto_accept, const gchar *capability)
+ gboolean auto_accept, gboolean symlinks,
+ const gchar *capability)
{
return server_register(service, name, channel, folder,
- secure, auto_accept, capability);
+ secure, auto_accept, symlinks,
+ capability);
}
void bluetooth_exit(void)
diff --git a/src/bluetooth.h b/src/bluetooth.h
index df74ca5..7871177 100644
--- a/src/bluetooth.h
+++ b/src/bluetooth.h
@@ -28,8 +28,9 @@
#endif
gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
- guint8 channel, gboolean secure, gboolean auto_accept,
- const gchar *capability);
+ guint8 channel, gboolean secure,
+ gboolean auto_accept, gboolean symlinks,
+ const gchar *capability);
void bluetooth_exit(void);
void bluetooth_start(void);
void bluetooth_stop(void);
diff --git a/src/ftp.c b/src/ftp.c
index 9ab13c5..5c442fc 100644
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -114,16 +114,25 @@ static gboolean folder_listing(struct obex_session *os, guint32 *size)
struct dirent *ep;
DIR *dp;
GString *listing;
+ gboolean root;
+ int err;
listing = g_string_new(FL_VERSION);
listing = g_string_append(listing, FL_TYPE);
listing = g_string_append(listing, FL_BODY_BEGIN);
- if (strcmp(os->current_folder,os->server->folder))
+ root = g_str_equal(os->current_folder, os->server->folder);
+
+ if (root && os->server->symlinks)
+ err = stat(os->current_folder, &dstat);
+ else {
listing = g_string_append(listing, FL_PARENT_FOLDER_ELEMENT);
+ err = lstat(os->current_folder, &dstat);
+ }
- if (lstat(os->current_folder, &dstat) < 0) {
- error("lstat: %s(%d)", strerror(errno), errno);
+ if (err < 0) {
+ error("%s: %s(%d)", root ? "stat" : "lstat",
+ strerror(errno), errno);
goto failed;
}
@@ -149,8 +158,14 @@ static gboolean folder_listing(struct obex_session *os, guint32 *size)
fullname = g_build_filename(os->current_folder, ep->d_name, NULL);
- if (lstat(fullname, &fstat) < 0) {
- debug("lstat: %s(%d)", strerror(errno), errno);
+ if (root && os->server->symlinks)
+ err = stat(fullname, &fstat);
+ else
+ err = lstat(fullname, &fstat);
+
+ if (err < 0) {
+ debug("%s: %s(%d)", root ? "stat" : "lstat",
+ strerror(errno), errno);
g_free(name);
g_free(fullname);
continue;
@@ -229,6 +244,30 @@ static gboolean get_by_type(struct obex_session *os, gchar *type, guint32 *size)
return FALSE;
}
+static gboolean ftp_prepare_get(struct obex_session *os, gchar *file,
+ guint32 *size)
+{
+ gboolean root;
+
+ root = g_str_equal(os->server->folder, os->current_folder);
+
+ if (!root || !os->server->symlinks) {
+ struct stat dstat;
+ int err;
+
+ err = lstat(file, &dstat);
+ if (err < 0) {
+ debug("lstat: %s(%d)", strerror(errno), errno);
+ return FALSE;
+ }
+
+ if (S_ISLNK(dstat.st_mode))
+ return FALSE;
+ }
+
+ return os_prepare_get(os, file, size);
+}
+
void ftp_get(obex_t *obex, obex_object_t *obj)
{
obex_headerdata_t hv;
@@ -248,10 +287,9 @@ void ftp_get(obex_t *obex, obex_object_t *obj)
if (!os->name)
goto fail;
- path = g_build_filename(os->current_folder,
- os->name, NULL);
+ path = g_build_filename(os->current_folder, os->name, NULL);
- ret = os_prepare_get(os, path, &size);
+ ret = ftp_prepare_get(os, path, &size);
g_free(path);
@@ -357,6 +395,8 @@ void ftp_setpath(obex_t *obex, obex_object_t *obj)
guint8 *nonhdr;
gchar *fullname;
struct stat dstat;
+ gboolean root;
+ int err;
os = OBEX_GetUserData(obex);
@@ -367,12 +407,14 @@ void ftp_setpath(obex_t *obex, obex_object_t *obj)
return;
}
+ root = g_str_equal(os->server->folder, os->current_folder);
+
/* Check flag "Backup" */
if ((nonhdr[0] & 0x01) == 0x01) {
debug("Set to parent path");
- if (strcmp(os->server->folder, os->current_folder) == 0) {
+ if (root) {
OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
return;
}
@@ -414,9 +456,15 @@ void ftp_setpath(obex_t *obex, obex_object_t *obj)
debug("Fullname: %s", fullname);
- if (lstat(fullname, &dstat) < 0) {
+ if (root && os->server->symlinks)
+ err = stat(fullname, &dstat);
+ else
+ err = lstat(fullname, &dstat);
+
+ if (err < 0) {
int err = errno;
- debug("lstat: %s(%d)", strerror(err), err);
+ debug("%s: %s(%d)", root ? "stat" : "lstat",
+ strerror(err), err);
if (err == ENOENT)
goto not_found;
diff --git a/src/main.c b/src/main.c
index 18bc496..0315f55 100644
--- a/src/main.c
+++ b/src/main.c
@@ -124,6 +124,7 @@ static gboolean option_opp = FALSE;
static gboolean option_ftp = FALSE;
static gboolean option_pbap = FALSE;
static gboolean option_pcsuite = FALSE;
+static gboolean option_symlinks = FALSE;
static GOptionEntry options[] = {
{ "nodaemon", 'n', G_OPTION_FLAG_REVERSE,
@@ -133,6 +134,8 @@ static GOptionEntry options[] = {
"Enable debug information output" },
{ "root", 'r', 0, G_OPTION_ARG_STRING, &option_root,
"Specify root folder location", "PATH" },
+ { "symlinks", 'l', 0, G_OPTION_ARG_NONE, &option_symlinks,
+ "Enable symlinks on root folder" },
{ "capability", 'c', 0, G_OPTION_ARG_STRING, &option_capability,
"Sepcify capability file", "FILE" },
{ "tty", 't', 0, G_OPTION_ARG_STRING, &option_devnode,
@@ -266,27 +269,29 @@ int main(int argc, char *argv[])
if (option_opp == TRUE) {
services |= OBEX_OPP;
bluetooth_init(OBEX_OPP, "Object Push server", option_root,
- OPP_CHANNEL, FALSE, option_autoaccept, NULL);
+ OPP_CHANNEL, FALSE, option_autoaccept,
+ option_symlinks, NULL);
}
if (option_ftp == TRUE) {
services |= OBEX_FTP;
bluetooth_init(OBEX_FTP, "File Transfer server", option_root,
FTP_CHANNEL, TRUE, option_autoaccept,
- option_capability);
+ option_symlinks, option_capability);
}
if (option_pbap == TRUE) {
services |= OBEX_PBAP;
bluetooth_init(OBEX_PBAP, "Phonebook Access server", NULL,
- PBAP_CHANNEL, TRUE, FALSE, NULL);
+ PBAP_CHANNEL, TRUE, FALSE, FALSE, NULL);
}
if (option_pcsuite == TRUE) {
services |= OBEX_PCSUITE;
bluetooth_init(OBEX_PCSUITE, "Nokia OBEX PC Suite Services",
option_root, PCSUITE_CHANNEL, TRUE,
- option_autoaccept, option_capability);
+ option_autoaccept, option_symlinks,
+ option_capability);
}
if (option_devnode)
diff --git a/src/obex.h b/src/obex.h
index 28dfdbc..b13219d 100644
--- a/src/obex.h
+++ b/src/obex.h
@@ -52,6 +52,7 @@ struct server {
gboolean auto_accept;
gchar *name;
gchar *folder;
+ gboolean symlinks;
gchar *capability;
guint32 handle;
uint8_t channel;