Something went wrong. Try again.
🎥 Command line media player
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156/* * Original author: M. Tourne * * This file is part of mpv. * * mpv 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 3 of the License, or * (at your option) any later version. * * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>. */
#include "config.h"
#include <libsmbclient.h>#include <unistd.h>#include <pthread.h>
#include "common/msg.h"#include "stream.h"#include "options/m_option.h"
#include "config.h"#if !HAVE_GPL#error GPL only#endif
static pthread_mutex_t smb_lock = PTHREAD_MUTEX_INITIALIZER;
struct priv { int fd;};
static void smb_auth_fn(const char *server, const char *share, char *workgroup, int wgmaxlen, char *username, int unmaxlen, char *password, int pwmaxlen){ strncpy(workgroup, "LAN", wgmaxlen - 1); workgroup[wgmaxlen - 1] = '\0';}
static int64_t get_size(stream_t *s) { struct priv *p = s->priv; pthread_mutex_lock(&smb_lock); off_t size = smbc_lseek(p->fd,0,SEEK_END); smbc_lseek(p->fd,s->pos,SEEK_SET); pthread_mutex_unlock(&smb_lock); return size;}
static int seek(stream_t *s,int64_t newpos) { struct priv *p = s->priv; pthread_mutex_lock(&smb_lock); off_t size = smbc_lseek(p->fd,newpos,SEEK_SET); pthread_mutex_unlock(&smb_lock); if(size<0) { return 0; } return 1;}
static int fill_buffer(stream_t *s, void *buffer, int max_len){ struct priv *p = s->priv; pthread_mutex_lock(&smb_lock); int r = smbc_read(p->fd,buffer,max_len); pthread_mutex_unlock(&smb_lock); return (r <= 0) ? -1 : r;}
static int write_buffer(stream_t *s, void *buffer, int len) { struct priv *p = s->priv; int wr; pthread_mutex_lock(&smb_lock); wr = smbc_write(p->fd,buffer,len); pthread_mutex_unlock(&smb_lock); return wr;}
static void close_f(stream_t *s){ struct priv *p = s->priv; pthread_mutex_lock(&smb_lock); smbc_close(p->fd); pthread_mutex_unlock(&smb_lock);}
static int open_f (stream_t *stream){ char *filename; int64_t len; int fd, err;
struct priv *priv = talloc_zero(stream, struct priv); stream->priv = priv;
filename = stream->url;
bool write = stream->mode == STREAM_WRITE; mode_t m = write ? O_RDWR|O_CREAT|O_TRUNC : O_RDONLY;
if(!filename) { MP_ERR(stream, "[smb] Bad url\n"); return STREAM_ERROR; }
pthread_mutex_lock(&smb_lock); err = smbc_init(smb_auth_fn, 1); pthread_mutex_unlock(&smb_lock); if (err < 0) { MP_ERR(stream, "Cannot init the libsmbclient library: %d\n",err); return STREAM_ERROR; }
pthread_mutex_lock(&smb_lock); fd = smbc_open(filename, m,0644); pthread_mutex_unlock(&smb_lock); if (fd < 0) { MP_ERR(stream, "Could not open from LAN: '%s'\n", filename); return STREAM_ERROR; }
len = 0; if(!write) { pthread_mutex_lock(&smb_lock); len = smbc_lseek(fd,0,SEEK_END); smbc_lseek (fd, 0, SEEK_SET); pthread_mutex_unlock(&smb_lock); } if(len > 0 || write) { stream->seekable = true; stream->seek = seek; } priv->fd = fd; stream->fill_buffer = fill_buffer; stream->write_buffer = write_buffer; stream->close = close_f; stream->get_size = get_size; stream->streaming = true;
return STREAM_OK;}
const stream_info_t stream_info_smb = { .name = "smb", .open = open_f, .protocols = (const char*const[]){"smb", NULL}, .can_write = true, //who's gonna do that? .stream_origin = STREAM_ORIGIN_FS,};