diff options
Diffstat (limited to 'src/input/input_smb.c')
-rw-r--r-- | src/input/input_smb.c | 137 |
1 files changed, 66 insertions, 71 deletions
diff --git a/src/input/input_smb.c b/src/input/input_smb.c index 7da9c1454..5d97d7518 100644 --- a/src/input/input_smb.c +++ b/src/input/input_smb.c @@ -1,18 +1,18 @@ /* - * Copyright (C) 2004 the xine project - * + * Copyright (C) 2008 the xine project + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -41,7 +41,7 @@ typedef struct { input_class_t input_class; xine_t *xine; - + int mrls_allocated_entries; xine_mrl_t **mrls; } smb_input_class_t; @@ -51,7 +51,7 @@ typedef struct { xine_stream_t *stream; /* File */ - char *mrl; + const char *mrl; int fd; } smb_input_t; @@ -69,6 +69,8 @@ smb_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) smb_input_t *this = (smb_input_t *) this_gen; off_t n, num_bytes; + if (len < 0) + return -1; num_bytes = 0; while (num_bytes < len) @@ -89,6 +91,13 @@ smb_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + if (todo > buf->max_size) + todo = buf->max_size; + if (todo < 0) { + buf->free_buffer (buf); + return NULL; + } + buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -129,7 +138,7 @@ smb_plugin_get_length (input_plugin_t *this_gen) int e; struct stat st; - + if (this->fd>=0) e = smbc_fstat(this->fd,&st); else e = smbc_stat(this->mrl,&st); @@ -138,7 +147,7 @@ smb_plugin_get_length (input_plugin_t *this_gen) return st.st_size; } -static char* +static const char* smb_plugin_get_mrl (input_plugin_t *this_gen) { smb_input_t *this = (smb_input_t *) this_gen; @@ -150,7 +159,7 @@ static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) { return 0; } -static char +static const char *smb_class_get_description (input_class_t *this_gen) { return _("CIFS/SMB input plugin based on libsmbclient"); @@ -209,20 +218,20 @@ static int _strverscmp(const char *s1, const char *s2) { c2 = *p2++; state |= (c1 == '0') + (ISDIGIT(c1) != 0); } - + state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))]; - + switch(state) { case CMP: return diff; - + case LEN: while(ISDIGIT(*p1++)) if(!ISDIGIT(*p2++)) return 1; - + return ISDIGIT(*p2) ? -1 : diff; - + default: return state; } @@ -236,9 +245,9 @@ static int _sortfiles_default(const xine_mrl_t *s1, const xine_mrl_t *s2) { } -static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, +static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { - + smb_input_class_t *this = (smb_input_class_t *) this_gen; int (*func) () = _sortfiles_default; int dir; @@ -254,38 +263,33 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, snprintf(current_path, XINE_PATH_MAX, "smb:/"); snprintf(current_path_smb, XINE_PATH_MAX, "smb://"); } - + if ((dir = smbc_opendir(current_path_smb)) >= 0){ - xine_mrl_t *dir_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES); - xine_mrl_t *norm_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES); - int num_dir_files=0; + xine_mrl_t *dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); + xine_mrl_t *norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); + int num_dir_files=0; int num_norm_files=0; while ((pdirent = smbc_readdir(dir)) != NULL){ if (pdirent->smbc_type == SMBC_WORKGROUP){ dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); - dir_files[num_dir_files].mrl = (char *) xine_xmalloc( - strlen(current_path) + 1 + strlen(pdirent->name) + 1); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; - }else if (pdirent->smbc_type == SMBC_SERVER){ + }else if (pdirent->smbc_type == SMBC_SERVER){ if (num_dir_files == 0) { dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup("smb:/"); - dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen("smb:/") + 4); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", ".."); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", ".."); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup("smb:/"); - dir_files[num_dir_files].mrl = - (char *) xine_xmalloc(strlen("smb:/") + 1 + strlen(pdirent->name) + 1); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", pdirent->name); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } else if (pdirent->smbc_type == SMBC_FILE_SHARE){ @@ -293,9 +297,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); - dir_files[num_dir_files].mrl = (char *) xine_xmalloc( - strlen(current_path) + 3); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, ".."); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, ".."); dir_files[num_dir_files].type |= mrl_file_directory; dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; @@ -304,28 +306,22 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); - dir_files[num_dir_files].mrl = (char *) xine_xmalloc( - strlen(current_path) + 1 + strlen(pdirent->name) + 1); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; - } + } } else if (pdirent->smbc_type == SMBC_DIR){ dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); - dir_files[num_dir_files].mrl = - (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; }else if (pdirent->smbc_type == SMBC_FILE){ norm_files[num_norm_files].link = NULL; norm_files[num_norm_files].type = mrl_file | mrl_file_normal; norm_files[num_norm_files].origin = strdup(current_path); - norm_files[num_norm_files].mrl = - (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1); - sprintf(norm_files[num_norm_files].mrl, "%s/%s", current_path, pdirent->name); + asprintf(&(norm_files[num_norm_files].mrl), "%s/%s", current_path, pdirent->name); norm_files[num_norm_files].size = pdirent->dirlen; num_norm_files ++; } @@ -335,8 +331,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, if (num_dir_files == 0) { dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].origin = strdup(current_path); - dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen(current_path) + 4); - sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, ".."); + asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, ".."); dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].size = 0; num_dir_files ++; @@ -347,49 +342,49 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, */ if(num_dir_files) qsort(dir_files, num_dir_files, sizeof(xine_mrl_t), func); - + if(num_norm_files) qsort(norm_files, num_norm_files, sizeof(xine_mrl_t), func); - + /* * Add directories entries */ for(i = 0; i < num_dir_files; i++) { if (num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; - this->mrls = realloc(this->mrls, + this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); - this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t)); + this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); }else memset(this->mrls[num_files], 0, sizeof(xine_mrl_t)); - - MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]); + + MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]); num_files++; } - - /* + + /* * Add other files entries */ for(i = 0; i < num_norm_files; i++) { if(num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; - this->mrls = realloc(this->mrls, + this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); - this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t)); + this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); }else memset(this->mrls[num_files], 0, sizeof(xine_mrl_t)); - MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]); + MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]); num_files++; } - + /* Some cleanups before leaving */ for(i = num_dir_files; i == 0; i--) MRL_ZERO(&dir_files[i]); free(dir_files); - + for(i = num_norm_files; i == 0; i--) MRL_ZERO(&norm_files[i]); free(norm_files); @@ -399,13 +394,13 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, current_path, errno, strerror(errno)); *nFiles = 0; return NULL; - } - + } + /* * Inform caller about files found number. */ *nFiles = num_files; - + /* * Freeing exceeded mrls if exists. */ @@ -413,7 +408,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]); free(this->mrls[this->mrls_allocated_entries--]); } - + /* * This is useful to let UI know where it should stops ;-). */ @@ -423,7 +418,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, } static int -smb_plugin_get_optional_data (input_plugin_t *this_gen, +smb_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { return INPUT_OPTIONAL_UNSUPPORTED; @@ -437,7 +432,7 @@ smb_plugin_dispose (input_plugin_t *this_gen ) if (this->fd>=0) smbc_close(this->fd); if (this->mrl) - free (this->mrl); + free ((char *)this->mrl); free (this); } @@ -448,8 +443,8 @@ smb_plugin_open (input_plugin_t *this_gen ) smb_input_class_t *class = (smb_input_class_t *) this_gen->input_class; this->fd = smbc_open(this->mrl,O_RDONLY,0); - xprintf(class->xine, XINE_VERBOSITY_DEBUG, - "input_smb: open failed for %s: %s\n", + xprintf(class->xine, XINE_VERBOSITY_DEBUG, + "input_smb: open failed for %s: %s\n", this->mrl, strerror(errno)); if (this->fd<0) return 0; @@ -469,13 +464,13 @@ smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *mrl) { smb_input_t *this; - + if (mrl == NULL) return NULL; if (strncmp (mrl, "smb://",6)) return NULL; - this = (smb_input_t *)xine_xmalloc(sizeof(smb_input_t)); + this = calloc(1, sizeof(smb_input_t)); this->stream = stream; this->mrl = strdup (mrl); this->fd = -1; @@ -513,8 +508,8 @@ static void if (smbc_init(smb_auth,(xine->verbosity >= XINE_VERBOSITY_DEBUG))) goto _exit_error; - - this = (smb_input_class_t *) xine_xmalloc(sizeof(smb_input_class_t)); + + this = calloc(1, sizeof(smb_input_class_t)); this->xine = xine; this->input_class.get_instance = smb_class_get_instance; @@ -531,7 +526,7 @@ static void setlocale(LC_MESSAGES, lcl); free(lcl); #endif - + return (input_class_t *) this; } |