static int Open(vlc_object_t *object) { access_t *access = (access_t *)object; input_thread_t *input = access->p_input; if (!input) return VLC_EGENERIC; access_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; if (input_Control(input, INPUT_GET_ATTACHMENT, &sys->attachment, access->psz_location)) sys->attachment = NULL; if (sys->attachment == NULL) { msg_Err(access, "Failed to find the attachment '%s'", access->psz_location); free(sys); return VLC_EGENERIC; } sys->offset = 0; /* */ access_InitFields(access); access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access->p_sys = sys; return VLC_SUCCESS; }
int AccessOpen( vlc_object_t *obj ) { access_t *access = (access_t *)obj; /* Only when selected */ if( *access->psz_access == '\0' ) return VLC_EGENERIC; access_InitFields( access ); demux_sys_t *sys = calloc( 1, sizeof( demux_sys_t )); if( unlikely(sys == NULL) ) return VLC_ENOMEM; access->p_sys = (access_sys_t *)sys; ParseMRL( obj, access->psz_location ); sys->i_fd = OpenVideo( obj, sys, false ); if( sys->i_fd == -1 ) { free( sys ); return VLC_EGENERIC; } if( sys->io == IO_METHOD_READ ) access->pf_read = AccessReadStream; else access->pf_block = AccessRead; access->pf_seek = NULL; access->pf_control = AccessControl; return VLC_SUCCESS; }
static int Open(vlc_object_t *object) { access_t *access = (access_t*)object; if (!strchr(access->psz_location, '|')) return VLC_EGENERIC; char *base = strdup(access->psz_location); if (!base) return VLC_EGENERIC; char *name = strchr(base, '|'); *name++ = '\0'; decode_URI(base); stream_t *s = stream_UrlNew(access, base); if (!s) goto error; int count; rar_file_t **files; if (RarProbe(s) || RarParse(s, &count, &files) || count <= 0) goto error; rar_file_t *file = NULL; for (int i = 0; i < count; i++) { if (!file && !strcmp(files[i]->name, name)) file = files[i]; else RarFileDelete(files[i]); } free(files); if (!file) goto error; access_sys_t *sys = access->p_sys = malloc(sizeof(*sys)); sys->s = s; sys->file = file; access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access_InitFields(access); access->info.i_size = file->size; rar_file_chunk_t dummy = { .mrl = base, }; sys->chunk = &dummy; Seek(access, 0); free(base); return VLC_SUCCESS; error: if (s) stream_Delete(s); free(base); return VLC_EGENERIC; }
int DirInit (access_t *p_access, DIR *handle) { access_sys_t *p_sys = malloc (sizeof (*p_sys)); if (unlikely(p_sys == NULL)) goto error; char *uri; if (!strcmp (p_access->psz_access, "fd")) { if (asprintf (&uri, "fd://%s", p_access->psz_location) == -1) uri = NULL; } else uri = make_URI (p_access->psz_filepath, "file"); if (unlikely(uri == NULL)) goto error; p_access->p_sys = p_sys; p_sys->current = NULL; p_sys->handle = handle; p_sys->uri = uri; p_sys->ignored_exts = var_InheritString (p_access, "ignore-filetypes"); p_sys->i_item_count = 0; p_sys->psz_xspf_extension = strdup( "" ); /* Handle mode */ char *psz = var_InheritString (p_access, "recursive"); if (psz == NULL || !strcasecmp (psz, "none")) p_sys->mode = MODE_NONE; else if( !strcasecmp( psz, "collapse" ) ) p_sys->mode = MODE_COLLAPSE; else p_sys->mode = MODE_EXPAND; free( psz ); access_InitFields(p_access); p_access->pf_read = NULL; p_access->pf_block = DirBlock; p_access->pf_seek = NULL; p_access->pf_control= DirControl; free (p_access->psz_demux); p_access->psz_demux = strdup ("xspf-open"); return VLC_SUCCESS; error: closedir (handle); free (p_sys); return VLC_EGENERIC; }
/***************************************************************************** * access_New: *****************************************************************************/ access_t *access_New( vlc_object_t *p_obj, input_thread_t *p_parent_input, const char *psz_access, const char *psz_demux, const char *psz_location ) { access_t *p_access = vlc_custom_create( p_obj, sizeof (*p_access), "access" ); if( p_access == NULL ) return NULL; /* */ p_access->p_input = p_parent_input; p_access->psz_access = strdup( psz_access ); p_access->psz_location = strdup( psz_location ); p_access->psz_filepath = get_path( psz_location ); p_access->psz_demux = strdup( psz_demux ); if( p_access->psz_access == NULL || p_access->psz_location == NULL || p_access->psz_demux == NULL ) goto error; msg_Dbg( p_obj, "creating access '%s' location='%s', path='%s'", psz_access, psz_location, p_access->psz_filepath ? p_access->psz_filepath : "(null)" ); p_access->pf_read = NULL; p_access->pf_block = NULL; p_access->pf_seek = NULL; p_access->pf_control = NULL; p_access->p_sys = NULL; access_InitFields( p_access ); p_access->p_module = module_need( p_access, "access", psz_access, true ); if( p_access->p_module == NULL ) goto error; return p_access; error: free( p_access->psz_access ); free( p_access->psz_location ); free( p_access->psz_filepath ); free( p_access->psz_demux ); vlc_object_release( p_access ); return NULL; }
static int Open(vlc_object_t* p_this) { auto p_access = (access_t*) p_this; try { auto r = open(p_access); if (r != VLC_SUCCESS) delete p_access->p_sys; else access_InitFields(p_access); return r; } catch (std::bad_alloc& e) { delete p_access->p_sys; return VLC_ENOMEM; } }
static int Open(vlc_object_t *object) { access_t *access = (access_t *)object; access_sys_t *sys; input_thread_t *input = access_GetParentInput(access); if (!input) return VLC_EGENERIC; input_attachment_t *a; if (input_Control(input, INPUT_GET_ATTACHMENT, &a, access->psz_location)) a = NULL; vlc_object_release(input); if (!a) { msg_Err(access, "Failed to find the attachment '%s'", access->psz_location); return VLC_EGENERIC; } /* */ access->p_sys = sys = malloc(sizeof(*sys)); if (!sys) { vlc_input_attachment_Delete(a); return VLC_ENOMEM; } sys->a = a; /* */ access_InitFields(access); access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; return VLC_SUCCESS; }
int AccessOpen( vlc_object_t *obj ) { access_t *access = (access_t *)obj; access_InitFields( access ); access_sys_t *sys = calloc (1, sizeof (*sys)); if( unlikely(sys == NULL) ) return VLC_ENOMEM; access->p_sys = sys; ParseMRL( obj, access->psz_location ); char *path = var_InheritString (obj, CFG_PREFIX"dev"); if (unlikely(path == NULL)) goto error; /* probably OOM */ uint32_t caps; int fd = OpenDevice (obj, path, &caps); free (path); if (fd == -1) goto error; sys->fd = fd; if (InitVideo (access, fd, caps)) { v4l2_close (fd); goto error; } sys->controls = ControlsInit (VLC_OBJECT(access), fd); access->pf_seek = NULL; access->pf_control = AccessControl; return VLC_SUCCESS; error: free (sys); return VLC_EGENERIC; }
/** * It opens an imem access. */ static int OpenAccess(vlc_object_t *object) { access_t *access = (access_t *)object; imem_sys_t *sys; if (OpenCommon(object, &sys, access->psz_path)) return VLC_EGENERIC; if (var_InheritInteger(object, "imem-cat") != 4) { CloseCommon(sys); return VLC_EGENERIC; } /* */ access_InitFields(access); access->pf_control = ControlAccess; access->pf_read = NULL; access->pf_block = Block; access->pf_seek = NULL; access->p_sys = (access_sys_t*)sys; access->info.i_size = var_InheritInteger(object, "imem-size"); return VLC_SUCCESS; }
/***************************************************************************** * Open: open the file *****************************************************************************/ static int Open( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; struct raw1394_portinfo port_inf[ 16 ]; msg_Dbg( p_access, "opening device" ); /* Set up p_access */ access_InitFields( p_access ); ACCESS_SET_CALLBACKS( NULL, Block, Control, NULL ); p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) ); if( !p_sys ) return VLC_EGENERIC; p_sys->i_cards = 0; p_sys->i_node = 0; p_sys->i_port = 0; p_sys->i_guid = 0; p_sys->i_channel = 63; p_sys->p_raw1394 = NULL; p_sys->p_avc1394 = NULL; p_sys->p_frame = NULL; p_sys->p_ev = NULL; vlc_mutex_init( &p_sys->lock ); p_sys->i_node = DiscoverAVC( p_access, &p_sys->i_port, p_sys->i_guid ); if( p_sys->i_node < 0 ) { msg_Err( p_access, "failed to open a Firewire (IEEE1394) connection" ); Close( p_this ); return VLC_EGENERIC; } p_sys->p_avc1394 = AVCOpen( p_access, p_sys->i_port ); if( !p_sys->p_avc1394 ) { msg_Err( p_access, "no Digital Video Control device found" ); Close( p_this ); return VLC_EGENERIC; } p_sys->p_raw1394 = raw1394_new_handle(); if( !p_sys->p_raw1394 ) { msg_Err( p_access, "no Digital Video device found" ); Close( p_this ); return VLC_EGENERIC; } p_sys->i_cards = raw1394_get_port_info( p_sys->p_raw1394, port_inf, 16 ); if( p_sys->i_cards < 0 ) { msg_Err( p_access, "failed to get port info" ); Close( p_this ); return VLC_EGENERIC; } if( raw1394_set_port( p_sys->p_raw1394, p_sys->i_port ) < 0 ) { msg_Err( p_access, "failed to set port info" ); Close( p_this ); return VLC_EGENERIC; } if ( raw1394_iso_recv_init( p_sys->p_raw1394, Raw1394Handler, ISOCHRONOUS_QUEUE_LENGTH, ISOCHRONOUS_MAX_PACKET_SIZE, p_sys->i_channel, RAW1394_DMA_PACKET_PER_BUFFER, -1 ) < 0 ) { msg_Err( p_access, "failed to init isochronous recv" ); Close( p_this ); return VLC_EGENERIC; } raw1394_set_userdata( p_sys->p_raw1394, p_access ); raw1394_iso_recv_start( p_sys->p_raw1394, -1, -1, 0 ); p_sys->raw1394_poll.fd = raw1394_get_fd( p_sys->p_raw1394 ); p_sys->raw1394_poll.events = POLLIN | POLLPRI; /* Now create our event thread catcher */ p_sys->p_ev = calloc( 1, sizeof( *p_sys->p_ev ) ); if( !p_sys->p_ev ) { msg_Err( p_access, "failed to create event thread struct" ); Close( p_this ); return VLC_ENOMEM; } p_sys->p_ev->p_frame = NULL; p_sys->p_ev->pp_last = &p_sys->p_ev->p_frame; p_sys->p_ev->p_access = p_access; vlc_mutex_init( &p_sys->p_ev->lock ); if( vlc_clone( &p_sys->p_ev->thread, Raw1394EventThread, p_sys->p_ev, VLC_THREAD_PRIORITY_OUTPUT ) ) { msg_Err( p_access, "failed to clone event thread" ); Close( p_this ); return VLC_EGENERIC; } return VLC_SUCCESS; }
static int Open(vlc_object_t *obj) { access_t *access = (access_t *)obj; char *list = var_CreateGetNonEmptyString(access, "concat-list"); if (list == NULL) return VLC_EGENERIC; access_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) { free(list); return VLC_ENOMEM; } var_SetString(access, "concat-list", ""); /* prevent recursion */ bool read_cb = true; sys->access = NULL; sys->can_seek = true; sys->can_seek_fast = true; sys->can_pause = true; sys->can_control_pace = true; sys->size = 0; sys->caching = 0; struct access_entry **pp = &sys->first; for (char *buf, *mrl = strtok_r(list, ",", &buf); mrl != NULL; mrl = strtok_r(NULL, ",", &buf)) { size_t mlen = strlen(mrl); struct access_entry *e = malloc(sizeof (*e) + mlen); if (unlikely(e == NULL)) break; access_t *a = vlc_access_NewMRL(obj, mrl); if (a == NULL) { msg_Err(access, "cannot concatenate location %s", mrl); free(e); continue; } if (a->pf_read == NULL) { if (a->pf_block == NULL) { msg_Err(access, "cannot concatenate directory %s", mrl); vlc_access_Delete(a); free(e); continue; } read_cb = false; } *pp = e; e->next = NULL; memcpy(e->mrl, mrl, mlen + 1); if (sys->can_seek) access_Control(a, ACCESS_CAN_SEEK, &sys->can_seek); if (sys->can_seek_fast) access_Control(a, ACCESS_CAN_FASTSEEK, &sys->can_seek_fast); if (sys->can_pause) access_Control(a, ACCESS_CAN_PAUSE, &sys->can_pause); if (sys->can_control_pace) access_Control(a, ACCESS_CAN_CONTROL_PACE, &sys->can_control_pace); if (sys->size != UINT64_MAX) { uint64_t size; if (access_GetSize(a, &size)) sys->size = UINT64_MAX; else sys->size += size; } int64_t caching; access_Control(a, ACCESS_GET_PTS_DELAY, &caching); if (caching > sys->caching) sys->caching = caching; vlc_access_Delete(a); pp = &e->next; } free(list); *pp = NULL; sys->next = sys->first; access_InitFields(access); access->pf_read = read_cb ? Read : NULL; access->pf_block = read_cb ? NULL : Block; access->pf_seek = Seek; access->pf_control = Control; access->p_sys = sys; return VLC_SUCCESS; }
int AccessOpen(vlc_object_t *p_object) { access_t *p_access = (access_t*)p_object; const char *sep = strchr(p_access->psz_location, ARCHIVE_SEP_CHAR); if (sep == NULL) return VLC_EGENERIC; char *psz_base = strdup(p_access->psz_location); if (unlikely(psz_base == NULL)) return VLC_ENOMEM; char *psz_name = psz_base + (sep - p_access->psz_location); *(psz_name++) = '\0'; if (decode_URI(psz_base) == NULL) { free(psz_base); return VLC_EGENERIC; } access_sys_t *p_sys = p_access->p_sys = calloc(1, sizeof(access_sys_t)); p_sys->p_archive = archive_read_new(); if (!p_sys->p_archive) { msg_Err(p_access, "can't create libarchive instance: %s", archive_error_string(p_sys->p_archive)); free(psz_base); goto error; } EnableArchiveFormats(p_sys->p_archive); /* Set up the switch callback for multiple volumes handling */ archive_read_set_switch_callback(p_sys->p_archive, SwitchCallback); /* !Warn: sucks because libarchive can't guess format without reading 1st header * and it can't tell either if volumes are missing neither set following * volumes after the first Open(). * We need to know volumes uri in advance then :/ */ /* Try to list existing volumes */ char **ppsz_files = NULL; unsigned int i_files = 0; FindVolumes(p_access, p_sys->p_archive, psz_base, &ppsz_files, &i_files); p_sys->i_callback_data = 1 + i_files; p_sys->p_callback_data = malloc(sizeof(callback_data_t) * p_sys->i_callback_data); if (!p_sys->p_callback_data) { for(unsigned int i=0; i<i_files; i++) free(ppsz_files[i]); free(ppsz_files); free(psz_base); AccessClose(p_object); return VLC_ENOMEM; } /* set up our callback struct for our main uri */ p_sys->p_callback_data[0].psz_uri = psz_base; p_sys->p_callback_data[0].p_access = p_access; archive_read_append_callback_data(p_sys->p_archive, &p_sys->p_callback_data[0]); /* and register other volumes */ for(unsigned int i=0; i<i_files; i++) { p_sys->p_callback_data[1+i].psz_uri = ppsz_files[i]; p_sys->p_callback_data[1+i].p_access = p_access; archive_read_append_callback_data(p_sys->p_archive, &p_sys->p_callback_data[1+i]); } free(ppsz_files); if (archive_read_open2(p_sys->p_archive, &p_sys->p_callback_data[0], OpenCallback, ReadCallback, SkipCallback, CloseCallback) != ARCHIVE_OK) { msg_Err(p_access, "can't open archive: %s", archive_error_string(p_sys->p_archive)); AccessClose(p_object); return VLC_EGENERIC; } bool b_present = false; while(archive_read_next_header(p_sys->p_archive, &p_sys->p_entry) == ARCHIVE_OK) { if (!strcmp(archive_entry_pathname(p_sys->p_entry), psz_name)) { b_present = true; break; } msg_Dbg(p_access, "skipping entry %s != %s", archive_entry_pathname(p_sys->p_entry), psz_name); } if (!b_present) { msg_Err(p_access, "entry '%s' not found in archive", psz_name); /* entry not found */ goto error; } msg_Dbg(p_access, "reading entry %s %"PRId64, archive_entry_pathname(p_sys->p_entry), archive_entry_size(p_sys->p_entry)); /* try to guess if it is seekable or not (does not depend on backend) */ p_sys->b_seekable = (archive_seek_data(p_sys->p_archive, 0, SEEK_SET) >= 0); p_access->pf_read = Read; p_access->pf_block = NULL; /* libarchive's zerocopy keeps owning block :/ */ p_access->pf_control = Control; p_access->pf_seek = Seek; access_InitFields(p_access); return VLC_SUCCESS; error: AccessClose(p_object); return VLC_EGENERIC; }
/**************************************************************************** * Open: connect to smb server and ask for file ****************************************************************************/ static int Open( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; struct stat filestat; vlc_url_t url; vlc_credential credential; char *psz_decoded_path = NULL, *psz_uri = NULL, *psz_var_domain = NULL; int i_ret; int i_smb; uint64_t i_size; bool b_is_dir = false; #ifndef _WIN32 if( smbc_init( smb_auth, 0 ) ) return VLC_EGENERIC; #endif /* ** some version of glibc defines open as a macro, causing havoc ** with other macros using 'open' under the hood, such as the ** following one: */ #if defined(smbc_open) && defined(open) # undef open #endif vlc_UrlParse( &url, p_access->psz_url ); if( url.psz_path ) { psz_decoded_path = vlc_uri_decode_duplicate( url.psz_path ); if( !psz_decoded_path ) { vlc_UrlClean( &url ); return VLC_EGENERIC; } } vlc_credential_init( &credential, &url ); psz_var_domain = var_InheritString( p_access, "smb-domain" ); credential.psz_realm = psz_var_domain; vlc_credential_get( &credential, p_access, "smb-user", "smb-pwd", NULL, NULL ); for (;;) { if( smb_get_uri( p_access, &psz_uri, credential.psz_realm, credential.psz_username, credential.psz_password, url.psz_host, psz_decoded_path, NULL ) == -1 ) { vlc_credential_clean( &credential ); free(psz_var_domain); free( psz_decoded_path ); vlc_UrlClean( &url ); return VLC_ENOMEM; } if( ( i_ret = smbc_stat( psz_uri, &filestat ) ) && errno == EACCES ) { errno = 0; if( vlc_credential_get( &credential, p_access, "smb-user", "smb-pwd", SMB_LOGIN_DIALOG_TITLE, SMB_LOGIN_DIALOG_TEXT, url.psz_host) ) continue; } /* smbc_stat fails with servers or shares. Assume they are directory */ if( i_ret || S_ISDIR( filestat.st_mode ) ) b_is_dir = true; break; } vlc_credential_store( &credential, p_access ); vlc_credential_clean( &credential ); free(psz_var_domain); free( psz_decoded_path ); /* Init p_access */ access_InitFields( p_access ); p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); if( !p_sys ) { free( psz_uri ); vlc_UrlClean( &url ); return VLC_ENOMEM; } if( b_is_dir ) { #ifdef _WIN32 free( p_sys ); free( psz_uri ); vlc_UrlClean( &url ); return VLC_EGENERIC; #else p_sys->url = url; p_access->pf_readdir = DirRead; p_access->pf_control = DirControl; i_smb = smbc_opendir( psz_uri ); i_size = 0; #endif } else { ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); i_smb = smbc_open( psz_uri, O_RDONLY, 0 ); i_size = filestat.st_size; } free( psz_uri ); if( i_smb < 0 ) { msg_Err( p_access, "open failed for '%s' (%s)", p_access->psz_location, vlc_strerror_c(errno) ); vlc_UrlClean( &p_sys->url ); free( p_sys ); return VLC_EGENERIC; } p_sys->size = i_size; p_sys->i_smb = i_smb; return VLC_SUCCESS; }
int RarAccessOpen(vlc_object_t *object) { access_t *access = (access_t*)object; const char *name = strchr(access->psz_location, '|'); if (name == NULL) return VLC_EGENERIC; char *base = strndup(access->psz_location, name - access->psz_location); if (unlikely(base == NULL)) return VLC_ENOMEM; name++; decode_URI(base); stream_t *s = stream_UrlNew(access, base); if (!s || RarProbe(s)) goto error; struct { int filescount; rar_file_t **files; unsigned int i_nbvols; } newscheme = { 0, NULL, 0 }, oldscheme = { 0, NULL, 0 }, *p_scheme; if (RarParse(s, &newscheme.filescount, &newscheme.files, &newscheme.i_nbvols, false) || newscheme.filescount < 1 || newscheme.i_nbvols < 2 ) { /* We might want to lookup old naming scheme, could be a part1.rar,part1.r00 */ stream_Seek(s, 0); RarParse(s, &oldscheme.filescount, &oldscheme.files, &oldscheme.i_nbvols, true); } if (oldscheme.filescount >= newscheme.filescount && oldscheme.i_nbvols > newscheme.i_nbvols) { for (int i = 0; i < newscheme.filescount; i++) RarFileDelete(newscheme.files[i]); free(newscheme.files); p_scheme = &oldscheme; msg_Dbg(s, "using rar old naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols); } else if (newscheme.filescount) { for (int i = 0; i < oldscheme.filescount; i++) RarFileDelete(oldscheme.files[i]); free(oldscheme.files); p_scheme = &newscheme; msg_Dbg(s, "using rar new naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols); } else { msg_Info(s, "Invalid or unsupported RAR archive"); for (int i = 0; i < oldscheme.filescount; i++) RarFileDelete(oldscheme.files[i]); free(oldscheme.files); for (int i = 0; i < newscheme.filescount; i++) RarFileDelete(newscheme.files[i]); free(newscheme.files); goto error; } rar_file_t *file = NULL; for (int i = 0; i < p_scheme->filescount; i++) { if (!file && !strcmp(p_scheme->files[i]->name, name)) file = p_scheme->files[i]; else RarFileDelete(p_scheme->files[i]); } free(p_scheme->files); if (!file) goto error; access_sys_t *sys = access->p_sys = malloc(sizeof(*sys)); sys->s = s; sys->file = file; access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access_InitFields(access); rar_file_chunk_t dummy = { .mrl = base, }; sys->chunk = &dummy; Seek(access, 0); free(base); return VLC_SUCCESS; error: if (s) stream_Delete(s); free(base); return VLC_EGENERIC; }
/***************************************************************************** * access_New: *****************************************************************************/ static access_t *access_New(vlc_object_t *parent, input_thread_t *input, const char *mrl) { char *redirv[MAX_REDIR]; unsigned redirc = 0; access_t *access = vlc_custom_create(parent, sizeof (*access), "access"); if (unlikely(access == NULL)) return NULL; access->p_input = input; access->psz_access = NULL; access->psz_url = strdup(mrl); access->psz_filepath = NULL; access->pf_read = NULL; access->pf_block = NULL; access->pf_readdir = NULL; access->pf_seek = NULL; access->pf_control = NULL; access->p_sys = NULL; access_InitFields(access); if (unlikely(access->psz_url == NULL)) goto error; while (redirc < MAX_REDIR) { char *url = access->psz_url; msg_Dbg(access, "creating access: %s", url); const char *p = strstr(url, "://"); if (p == NULL) goto error; access->psz_access = strndup(url, p - url); if (unlikely(access->psz_access == NULL)) goto error; access->psz_location = p + 3; access->psz_filepath = get_path(access->psz_location); if (access->psz_filepath != NULL) msg_Dbg(access, " (path: %s)", access->psz_filepath); access->p_module = module_need(access, "access", access->psz_access, true); if (access->p_module != NULL) /* success */ { while (redirc > 0) free(redirv[--redirc]); assert(access->pf_control != NULL); return access; } if (access->psz_url == url) /* failure (no redirection) */ goto error; /* redirection */ msg_Dbg(access, "redirecting to: %s", access->psz_url); redirv[redirc++] = url; for (unsigned j = 0; j < redirc; j++) if (!strcmp(redirv[j], access->psz_url)) { msg_Err(access, "redirection loop"); goto error; } } msg_Err(access, "too many redirections"); error: while (redirc > 0) free(redirv[--redirc]); free(access->psz_filepath); free(access->psz_url); free(access->psz_access); vlc_object_release(access); return NULL; }
/***************************************************************************** * Open: Initialize module's data structures and libdsm *****************************************************************************/ static int Open( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; smb_stat st; /* Init p_access */ access_InitFields( p_access ); p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); if( p_access->p_sys == NULL ) return VLC_ENOMEM; p_sys->p_ns = netbios_ns_new(); if( p_sys->p_ns == NULL ) goto error; p_sys->p_session = smb_session_new(); if( p_sys->p_session == NULL ) goto error; char *psz_decoded_location = vlc_uri_decode_duplicate( p_access->psz_location ); if( psz_decoded_location == NULL ) goto error; vlc_UrlParse( &p_sys->url, psz_decoded_location ); free( psz_decoded_location ); if( get_address( p_access ) != VLC_SUCCESS ) goto error; msg_Dbg( p_access, "Session: Host name = %s, ip = %s", p_sys->netbios_name, inet_ntoa( p_sys->addr ) ); /* Now that we have the required data, let's establish a session */ if( !smb_session_connect( p_sys->p_session, p_sys->netbios_name, p_sys->addr.s_addr, SMB_TRANSPORT_TCP ) ) { msg_Err( p_access, "Unable to connect/negotiate SMB session"); goto error; } get_path( p_access ); if( login( p_access ) != VLC_SUCCESS ) { msg_Err( p_access, "Unable to open file with path %s (in share %s)", p_sys->psz_path, p_sys->psz_share ); goto error; } /* If there is no shares, browse them */ if( !p_sys->psz_share ) return BrowserInit( p_access ); assert(p_sys->i_fd > 0); msg_Dbg( p_access, "Path: Share name = %s, path = %s", p_sys->psz_share, p_sys->psz_path ); st = smb_stat_fd( p_sys->p_session, p_sys->i_fd ); if( smb_stat_get( st, SMB_STAT_ISDIR ) ) { smb_fclose( p_sys->p_session, p_sys->i_fd ); return BrowserInit( p_access ); } msg_Dbg( p_access, "Successfully opened smb://%s", p_access->psz_location ); ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); return VLC_SUCCESS; error: Close( p_this ); return VLC_EGENERIC; }
int DirInit (access_t *p_access, DIR *handle) { access_sys_t *p_sys = malloc (sizeof (*p_sys)); if (unlikely(p_sys == NULL)) goto error; char *uri; if (!strcmp (p_access->psz_access, "fd")) { if (asprintf (&uri, "fd://%s", p_access->psz_location) == -1) uri = NULL; } else uri = vlc_path2uri (p_access->psz_filepath, "file"); if (unlikely(uri == NULL)) goto error; /* "Open" the base directory */ directory_t *root = malloc (sizeof (*root)); if (unlikely(root == NULL)) { free (uri); goto error; } char *psz_sort = var_InheritString (p_access, "directory-sort"); if (!psz_sort) p_sys->compar = collate; else if (!strcasecmp (psz_sort, "version")) p_sys->compar = version; else if (!strcasecmp (psz_sort, "none")) p_sys->compar = NULL; else p_sys->compar = collate; free(psz_sort); root->parent = NULL; root->handle = handle; root->uri = uri; root->filec = vlc_loaddir (handle, &root->filev, visible, p_sys->compar); if (root->filec < 0) root->filev = NULL; root->i = 0; #ifdef HAVE_OPENAT struct stat st; if (fstat (dirfd (handle), &st)) { free (root); free (uri); goto error; } root->device = st.st_dev; root->inode = st.st_ino; #else root->path = strdup (p_access->psz_filepath); #endif p_access->p_sys = p_sys; p_sys->current = root; p_sys->ignored_exts = var_InheritString (p_access, "ignore-filetypes"); p_sys->header = true; p_sys->i_item_count = 0; p_sys->xspf_ext = strdup (""); /* Handle mode */ char *psz = var_InheritString (p_access, "recursive"); if (psz == NULL || !strcasecmp (psz, "none")) p_sys->mode = MODE_NONE; else if( !strcasecmp( psz, "collapse" ) ) p_sys->mode = MODE_COLLAPSE; else p_sys->mode = MODE_EXPAND; free( psz ); access_InitFields(p_access); p_access->pf_read = NULL; p_access->pf_block = DirBlock; p_access->pf_seek = NULL; p_access->pf_control= DirControl; free (p_access->psz_demux); p_access->psz_demux = strdup ("xspf-open"); return VLC_SUCCESS; error: closedir (handle); free (p_sys); return VLC_EGENERIC; }
int OpenAvio(vlc_object_t *object) { access_t *access = (access_t*)object; access_sys_t *sys = malloc(sizeof(*sys)); if (!sys) return VLC_ENOMEM; sys->context = NULL; /* We accept: * - avio://full_url * - url (only a subset of available protocols). */ char *url; if (!strcmp(access->psz_access, "avio")) url = strdup(access->psz_location); else if (asprintf(&url, "%s://%s", access->psz_access, access->psz_location) < 0) url = NULL; if (!url) { free(sys); return VLC_ENOMEM; } /* */ vlc_init_avformat(object); int ret; #if LIBAVFORMAT_VERSION_MAJOR < 54 ret = avio_open(&sys->context, url, AVIO_FLAG_READ); #else AVIOInterruptCB cb = { .callback = UrlInterruptCallback, .opaque = access, }; AVDictionary *options = NULL; char *psz_opts = var_InheritString(access, "avio-options"); if (psz_opts && *psz_opts) { options = vlc_av_get_options(psz_opts); free(psz_opts); } ret = avio_open2(&sys->context, url, AVIO_FLAG_READ, &cb, &options); AVDictionaryEntry *t = NULL; while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) msg_Err( access, "unknown option \"%s\"", t->key ); av_dict_free(&options); #endif if (ret < 0) { errno = AVUNERROR(ret); msg_Err(access, "Failed to open %s: %m", url); free(url); goto error; } free(url); #if LIBAVFORMAT_VERSION_MAJOR < 54 /* We can accept only one active user at any time */ if (SetupAvioCb(VLC_OBJECT(access))) { msg_Err(access, "Module aready in use"); avio_close(sys->context); goto error; } #endif int64_t size = avio_size(sys->context); bool seekable; #if LIBAVFORMAT_VERSION_MAJOR < 54 seekable = !sys->context->is_streamed; #else seekable = sys->context->seekable; #endif msg_Dbg(access, "%sseekable, size=%"PRIi64, seekable ? "" : "not ", size); sys->size = size > 0 ? size : 0; /* */ access_InitFields(access); access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access->p_sys = sys; return VLC_SUCCESS; error: free(sys); return VLC_EGENERIC; }