diff options
author | Carl Fürstenberg <azatoth@gmail.com> | 2011-04-04 21:38:27 +0400 |
---|---|---|
committer | Carl Fürstenberg <azatoth@gmail.com> | 2011-04-05 01:13:31 +0400 |
commit | 8b51f511f8f08123146923e02f03f8e840d0529b (patch) | |
tree | 7190ffdaa0ae06fd6bd28aba61fee45e33ef819e | |
parent | 0922cc147cf811c36e2a39e8f7dddd1043e0e784 (diff) |
cygwinhiero_transcode_plus
-rw-r--r-- | getifaddr.c | 48 | ||||
-rw-r--r-- | inotify.c | 332 | ||||
-rw-r--r-- | minidlna.c | 47 | ||||
-rw-r--r-- | upnpglobalvars.c | 7 | ||||
-rw-r--r-- | upnphttp.c | 92 | ||||
-rw-r--r-- | utils.c | 5 | ||||
-rw-r--r-- | uuid.c | 11 |
7 files changed, 541 insertions, 1 deletions
diff --git a/getifaddr.c b/getifaddr.c index ab8da71..52569c3 100644 --- a/getifaddr.c +++ b/getifaddr.c @@ -43,6 +43,7 @@ #include <sys/sockio.h> #endif +#include "config.h" #include "getifaddr.h" #include "log.h" @@ -86,18 +87,65 @@ getsysaddr(char * buf, int len) int s = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; struct ifreq ifr; +#ifdef cygwin + struct ifconf ifc; + char *ptr; + int result; + char buffer[1024]; +#endif int ret = -1; +#ifdef cygwin + ifc.ifc_buf = buffer; + ifc.ifc_len = (sizeof(buffer)/sizeof(buffer[0])); + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + DPRINTF(E_ERROR, L_GENERAL, "Couldn't open socket\n"); + return -1; + } + + result = ioctl(s, SIOCGIFCONF, &ifc); + + ptr = buffer; +#endif + +#ifndef cygwin for (i=1; i > 0; i++) +#else /* cygwin */ + for (i=1; i > 0; i++, ptr += sizeof(struct ifreq)) +#endif /* cygwin */ { ifr.ifr_ifindex = i; +#ifndef cygwin if( ioctl(s, SIOCGIFNAME, &ifr) < 0 ) break; if(ioctl(s, SIOCGIFADDR, &ifr, sizeof(struct ifreq)) < 0) continue; +#else /* cygwin */ + if (ptr >= buf + ifc.ifc_len) + break; + memcpy(&ifr, ptr, sizeof(ifr)); + result = ioctl(s, SIOCGIFADDR, &ifr, sizeof(struct ifreq)); + if (ifr.ifr_addr.sa_family != AF_INET) + continue; +#endif /* cygwin */ memcpy(&addr, &ifr.ifr_addr, sizeof(addr)); +#ifndef cygwin if(strncmp(inet_ntoa(addr.sin_addr), "127.", 4) == 0) continue; +#else /* cygwin */ + if( (strncmp(inet_ntoa(addr.sin_addr), "127.", 4) == 0) + || (strncmp(inet_ntoa(addr.sin_addr), "169.", 4) == 0) ) + { + //DPRINTF(E_ERROR, L_GENERAL, "found address #%d= %s : Not used\n", i, inet_ntoa(addr.sin_addr)); + printf("found address #%d= %s : Not used\n", i, inet_ntoa(addr.sin_addr)); + continue; + } + else + //DPRINTF(E_ERROR, L_GENERAL, "found address #%d= %s : used\n", i, inet_ntoa(addr.sin_addr)); + printf("found address #%d= %s : used\n", i, inet_ntoa(addr.sin_addr)); +#endif /* cygwin */ if(!inet_ntop(AF_INET, &addr.sin_addr, buf, len)) { DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno)); @@ -31,11 +31,14 @@ #include <sys/time.h> #include <sys/resource.h> #include <poll.h> +#include "config.h" #ifdef HAVE_INOTIFY_H #include <sys/inotify.h> #else +#ifndef cygwin #include "linux/inotify.h" #include "linux/inotify-syscalls.h" +#endif /* cygwin */ #endif #include "upnpglobalvars.h" @@ -48,6 +51,14 @@ #include "playlist.h" #include "log.h" +#ifdef cygwin + +#include <sys/cygwin.h> +#define PATH_BUF_SIZE PATH_MAX +static time_t next_pl_fill = 0; + +#else /* cygwin */ + #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) #define DESIRED_WATCH_LIMIT 65536 @@ -274,6 +285,7 @@ int add_dir_watch(int fd, char * path, char * filename) return(i); } +#endif /* cygwin */ int inotify_insert_file(char * name, const char * path) @@ -419,6 +431,9 @@ inotify_insert_file(char * name, const char * path) if( !depth ) { //DEBUG DPRINTF(E_DEBUG, L_INOTIFY, "Inserting %s\n", name); +#ifdef cygwin + DPRINTF(E_DEBUG, L_INOTIFY, "Inserting %s:%s\n", name, path); +#endif /* cygwin */ insert_file(name, path, id+2, get_next_available_id("OBJECTS", id)); free(id); if( (is_audio(path) || is_playlist(path)) && next_pl_fill != 1 ) @@ -438,7 +453,9 @@ inotify_insert_directory(int fd, char *name, const char * path) char * sql; char **result; char *id=NULL, *path_buf, *parent_buf, *esc_name; +#ifndef cygwin int wd; +#endif /* cygwin */ int rows; enum file_types type = TYPE_UNKNOWN; enum media_types dir_type = ALL_MEDIA; @@ -457,6 +474,7 @@ inotify_insert_directory(int fd, char *name, const char * path) free(parent_buf); sqlite3_free(sql); +#ifndef cygwin wd = add_watch(fd, path); if( wd == -1 ) { @@ -466,6 +484,7 @@ inotify_insert_directory(int fd, char *name, const char * path) { DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", path, wd); } +#endif /* cygwin */ media_path = media_dirs; while( media_path ) @@ -608,7 +627,9 @@ inotify_remove_directory(int fd, const char * path) sqlite_int64 detailID = 0; int rows, i, ret = 1; +#ifndef cygwin remove_watch(fd, path); +#endif /* cygwin */ sql = sqlite3_mprintf("SELECT ID from DETAILS where PATH glob '%q/*'" " UNION ALL SELECT ID from DETAILS where PATH = '%q'", path, path); if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) ) @@ -632,6 +653,7 @@ inotify_remove_directory(int fd, const char * path) return ret; } +#ifndef cygwin void * start_inotify() { @@ -746,3 +768,313 @@ quitting: return 0; } + +#else /* cygwin */ + + +#include <windows.h> +//#include <dirent.h> // for opendir() +#include <unistd.h> // for stat() + +#define BUFF_SIZE (128*1024) + +#define WATCH_LIMIT 16 + +// Required parameters for ReadDirectoryChangesW(). +static FILE_NOTIFY_INFORMATION *m_Buffer[WATCH_LIMIT]; +static HANDLE m_hDirectory[WATCH_LIMIT]; +static OVERLAPPED m_Overlapped[WATCH_LIMIT]; +static char *search_path_win[WATCH_LIMIT]; + + +static VOID +insert_to_delete_from_db(int searchNo) +{ + FILE_NOTIFY_INFORMATION *m_BufferTmp; + + int NextOff, FileNumLenMB; + char path_buf[PATH_BUF_SIZE], fullPath[PATH_BUF_SIZE]; + //DIR *dp; + int fd=0; + char * esc_name = NULL; + struct stat file_stat; + + m_BufferTmp = m_Buffer[searchNo]; + do { +#if 0 + char *Action[] = { + "FILE_ACTION_ADDED", + "FILE_ACTION_REMOVED", + "FILE_ACTION_MODIFIED", + "FILE_ACTION_RENAMED_OLD_NAME", + "FILE_ACTION_RENAMED_NEW_NAME" + }; + + printf ("NextEntryOffset = %d\n", m_BufferTmp->NextEntryOffset); + printf ("Action = %08x : %s\n", m_BufferTmp->Action, Action[m_BufferTmp->Action-1]); + printf ("FileNameLength = %d byte(s)\n", m_BufferTmp->FileNameLength); + FileNumLenMB = WideCharToMultiByte (CP_UTF8, 0, &(m_BufferTmp->FileName[0]), m_BufferTmp->FileNameLength/2, path_buf, PATH_BUF_SIZE, NULL, NULL); + path_buf[FileNumLenMB] = '\0'; + sprintf(fullPath, "%s\\%s", search_path_win[searchNo], path_buf); + cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, fullPath, path_buf, PATH_BUF_SIZE); + + //dp = opendir(path_buf); // check whether fullPath is directory + stat(path_buf, &file_stat); + //if (dp == NULL) { + if (!S_ISDIR(file_stat.st_mode)) { // file + printf ("FileName = %s\n\n", path_buf); + } else { + printf ("FileName = %s : directory\n\n", path_buf); + //closedir(dp); + } +#else + FileNumLenMB = WideCharToMultiByte (CP_UTF8, 0, &(m_BufferTmp->FileName[0]), m_BufferTmp->FileNameLength/2, path_buf, PATH_BUF_SIZE, NULL, NULL); + path_buf[FileNumLenMB] = '\0'; + sprintf(fullPath, "%s\\%s", search_path_win[searchNo], path_buf); + cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, fullPath, path_buf, PATH_BUF_SIZE); + + //DPRINTF(E_DEBUG, L_INOTIFY, "path_buf:%s, rindex:%s\n", path_buf, rindex(path_buf, '/')+1); + esc_name = modifyString(strdup(rindex(path_buf, '/')+1), "&", "&amp;", 0); + //DPRINTF(E_DEBUG, L_INOTIFY, "esc_name %s\n", esc_name); + + if (m_BufferTmp->Action == FILE_ACTION_REMOVED) { // there is no way to distinguish file/dir in case delete. + // so try to delete both file and directory. it looks work + DPRINTF(E_DEBUG, L_INOTIFY, "The file/directory %s was deleted.\n", path_buf); + inotify_remove_file(path_buf); + inotify_remove_directory(fd, path_buf); + } + else { + //dp = opendir(path_buf); // check whether fullPath is directory + stat(path_buf, &file_stat); + //if (dp == NULL) { // file + if (!S_ISDIR(file_stat.st_mode)) { // file + if ( (m_BufferTmp->Action == FILE_ACTION_ADDED) + || (m_BufferTmp->Action == FILE_ACTION_MODIFIED) + || (m_BufferTmp->Action == FILE_ACTION_RENAMED_NEW_NAME)) { + DPRINTF(E_DEBUG, L_INOTIFY, "The file %s was %s.\n", + path_buf, m_BufferTmp->Action == FILE_ACTION_MODIFIED ? "changed" : "moved here"); + inotify_insert_file(esc_name, path_buf); + } else + if ( (m_BufferTmp->Action == FILE_ACTION_REMOVED) + || (m_BufferTmp->Action == FILE_ACTION_RENAMED_OLD_NAME)) { + DPRINTF(E_DEBUG, L_INOTIFY, "The file %s was %s.\n", + path_buf, m_BufferTmp->Action == FILE_ACTION_RENAMED_OLD_NAME ? "moved away" : "deleted"); + inotify_remove_file(path_buf); + } + } + else { // directory + //closedir(dp); + if ( (m_BufferTmp->Action == FILE_ACTION_ADDED) + || (m_BufferTmp->Action == FILE_ACTION_RENAMED_NEW_NAME)) { + DPRINTF(E_DEBUG, L_INOTIFY, "The directory %s was %s.\n", + path_buf, m_BufferTmp->Action == FILE_ACTION_RENAMED_NEW_NAME ? "moved here" : "created"); + inotify_insert_directory(fd, esc_name, path_buf); + } else + if ( (m_BufferTmp->Action == FILE_ACTION_REMOVED) + || (m_BufferTmp->Action == FILE_ACTION_RENAMED_OLD_NAME)) { + DPRINTF(E_DEBUG, L_INOTIFY, "The directory %s was %s.\n", + path_buf, m_BufferTmp->Action == FILE_ACTION_RENAMED_OLD_NAME ? "moved away" : "deleted"); + inotify_remove_directory(fd, path_buf); + } + } + } + free(esc_name); +#endif + NextOff = m_BufferTmp->NextEntryOffset; + m_BufferTmp = (FILE_NOTIFY_INFORMATION *)((char *)m_BufferTmp + NextOff); + } while (NextOff != 0); + +} + + +HANDLE +add_watch(char *path) +{ + HANDLE hret; + + hret = CreateFile( + path, // pointer to the file name + FILE_LIST_DIRECTORY, // access (read/write) mode + FILE_SHARE_READ // share mode + | FILE_SHARE_WRITE + | FILE_SHARE_DELETE, + NULL, // security descriptor + OPEN_EXISTING, // how to create + FILE_FLAG_BACKUP_SEMANTICS // file attributes + | FILE_FLAG_OVERLAPPED, + NULL); // file with attributes to copy + + if (hret == INVALID_HANDLE_VALUE) + { + DPRINTF(E_ERROR, L_HTTP, "can not open directory : %s\n", path); + } + + return hret; +} + + +BOOL +registerReadDirChg_block(HANDLE hDirectory, FILE_NOTIFY_INFORMATION *buf, OVERLAPPED *overlapped) +{ + BOOL success; + DWORD dwBytes; + BOOL m_bChildren = 1; + + // This call needs to be reissued after every APC. + success = ReadDirectoryChangesW( + hDirectory, // handle to directory + buf, // read results buffer + BUFF_SIZE, // length of buffer + m_bChildren, // monitoring option + FILE_NOTIFY_CHANGE_LAST_WRITE + |FILE_NOTIFY_CHANGE_CREATION + |FILE_NOTIFY_CHANGE_SIZE + |FILE_NOTIFY_CHANGE_DIR_NAME + |FILE_NOTIFY_CHANGE_FILE_NAME, // filter conditions + &dwBytes, // bytes returned + overlapped, // overlapped buffer + NULL); // completion routine : Not used + + return success; +} + + +int +inotify_create_watches() +{ + struct media_dir_s * media_path; + HANDLE hret; + int num_watches=0; + + media_path = media_dirs; + for (num_watches = 0 ; media_path && (num_watches < WATCH_LIMIT) ; num_watches++) + { + char path_win_style[PATH_BUF_SIZE]; + cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, media_path->path, path_win_style, PATH_BUF_SIZE); + hret = add_watch(path_win_style); + if (hret == INVALID_HANDLE_VALUE) break; + m_hDirectory[num_watches] = hret; + if ((m_Buffer[num_watches] = (FILE_NOTIFY_INFORMATION *)malloc(BUFF_SIZE)) == NULL) { + DPRINTF(E_ERROR, L_HTTP, "can not malloc for inotify\n\n"); + break; + } + if ((search_path_win[num_watches] = (char *)malloc(PATH_BUF_SIZE)) == NULL) { + DPRINTF(E_ERROR, L_HTTP, "can not malloc for inotify\n\n"); + break; + } + strcpy(search_path_win[num_watches], path_win_style); + DPRINTF(E_INFO, L_INOTIFY, "add directry : %s : %s\n", media_path->path, path_win_style); + media_path = media_path->next; + } + + return num_watches; +} + + +void * +start_inotify() +{ + HANDLE hEvents[WATCH_LIMIT]; + BOOL bResult; + DWORD dwError, dwResult; + int i, eventNo; + DWORD dwBytes=0; + DWORD timeout = 1000; + int num_watches=0; + + while( scanning ) + { + if( quitting ) + goto quitting; + sleep(1); + } + + num_watches = inotify_create_watches(); + if (!num_watches) { + DPRINTF(E_WARN, L_INOTIFY, "Failed to create watch\n"); + return 0; + } + + if (setpriority(PRIO_PROCESS, 0, 19) == -1) + DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n"); +////////////return 0; + + for (i=0 ; i<num_watches ; i++) { + // Fill OVERLAPPED structure + memset(&m_Overlapped[i], 0, sizeof(OVERLAPPED)); + + m_Overlapped[i].hEvent = CreateEvent( + NULL, // security attributes + TRUE, // manually reset + FALSE, // unsignaled + NULL); // name + + hEvents[i] = m_Overlapped[i].hEvent; + + bResult = registerReadDirChg_block(m_hDirectory[i], m_Buffer[i], &m_Overlapped[i]); + dwError = GetLastError(); + } + + while( !quitting ) + { + // Wait for overlapped result and for stop event + //DPRINTF(E_DEBUG, L_INOTIFY, "Wait for %d overlapped result and for stop event\n", num_watches); + dwResult = WaitForMultipleObjects(num_watches, hEvents, FALSE, timeout); + dwError = GetLastError(); + //DPRINTF(E_DEBUG, L_INOTIFY, "event occured WAIT_OBJECT_0+%d\n", dwResult - WAIT_OBJECT_0); + if( dwResult == WAIT_TIMEOUT ) + { + if( next_pl_fill && (time(NULL) >= next_pl_fill) ) + { + fill_playlists(); + next_pl_fill = 0; + } + continue; + } + else if( (WAIT_OBJECT_0 <= dwResult) && (dwResult < (WAIT_OBJECT_0 + num_watches)) ) { + // overlapped operation finished + eventNo = dwResult - WAIT_OBJECT_0; + bResult = GetOverlappedResult( m_hDirectory[eventNo], &m_Overlapped[eventNo], &dwBytes, TRUE ); + dwError = GetLastError(); + + if ( ! bResult ) + { + DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); + } + else + { + // handle results of asynchronous operation + insert_to_delete_from_db(eventNo); + // It is better to call registerReadDirChg_block() then NotificationCompletion() + // in order to avoid miss catch the events, but ... + // Get the new read issued as fast as possible. The documentation + // says that the original OVERLAPPED structure will not be used + // again once the completion routine is called. + bResult = registerReadDirChg_block(m_hDirectory[eventNo], m_Buffer[eventNo], &m_Overlapped[eventNo]); + dwError = GetLastError(); + } + continue; + } + else if( dwResult == WAIT_FAILED) + { + //if( (errno == EINTR) || (errno == EAGAIN) ) + // continue; + //else + DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); + break; + } + else { + DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); + break; + } + } + for (i=0 ; i<num_watches ; i++) { + CloseHandle(m_hDirectory[i]); + free(m_Buffer[i]); + free(search_path_win[i]); + } +quitting: + + return 0; +} +#endif /* cygwin */ @@ -98,6 +98,9 @@ #include "tivo_beacon.h" #include "tivo_utils.h" #endif +#ifdef cygwin +#include <sys/cygwin.h> +#endif /* cygwin */ #if SQLITE_VERSION_NUMBER < 3005001 # warning "Your SQLite3 library appears to be too old! Please use 3.5.1 or newer." @@ -352,6 +355,10 @@ init(int argc, char * * argv) char * path; char real_path[PATH_MAX]; char ext_ip_addr[INET_ADDRSTRLEN] = {'\0'}; +#ifdef cygwin + ssize_t ret; + char cygwin_path[PATH_MAX]; +#endif /* cygwin */ #ifdef ENABLE_TRANSCODE int transcode_video_options_len = 0; int transcode_audio_ffmpeg_options_len = 0; @@ -397,6 +404,7 @@ init(int argc, char * * argv) { switch(ary_options[i].id) { +#ifndef cygwin case UPNPIFNAME: if(getifaddr(ary_options[i].value, ext_ip_addr, INET_ADDRSTRLEN) >= 0) { @@ -406,6 +414,7 @@ init(int argc, char * * argv) else fprintf(stderr, "Interface %s not found, ignoring.\n", ary_options[i].value); break; +#endif /* cygwin */ case UPNPLISTENING_IP: if(n_lan_addr < MAX_LAN_ADDR) { @@ -461,7 +470,25 @@ init(int argc, char * * argv) case 'p': if( ary_options[i].value[0] == 'P' || ary_options[i].value[0] == 'p' ) type = IMAGES_ONLY; +#ifndef cygwin myval = index(ary_options[i].value, '/'); +#else /* cygwin */ + case 'M': + case 'm': + myval = index(ary_options[i].value, '/'); + if (!myval) { + myval = index(ary_options[i].value, '\\'); + if (myval) { + ret = cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, &ary_options[i].value[2], cygwin_path, PATH_MAX); + if (ret == 0) + myval = cygwin_path; + else { + myval = NULL; + fprintf(stderr, "invalid path : %s\n", &ary_options[i].value[2]); + } + } + } +#endif /* cygwin */ case '/': path = realpath(myval ? myval:ary_options[i].value, real_path); if( !path ) @@ -801,7 +828,11 @@ init(int argc, char * * argv) else { #ifdef USE_DAEMON +#ifndef cygwin if(daemon(0, 0)<0) { +#else + if(daemon(1, 0)<0) { // keep cuurend cwd +#endif /* cygwin */ perror("daemon()"); } pid = getpid(); @@ -900,6 +931,18 @@ main(int argc, char * * argv) textdomain("minidlna"); #endif +#ifdef cygwin + { + char *localappdata; + if ((localappdata = getenv("LOCALAPPDATA")) == NULL) // Windows7, Vista + localappdata = getenv("APPDATA"); // Windows XP + if (localappdata != NULL) + //cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, localappdata, db_path, PATH_MAX); + //strcat(db_path, "/minidlna"); + sprintf(db_path, "%s\\minidlna", localappdata); + } +#endif /* cygwin */ + if(init(argc, argv) != 0) return 1; @@ -921,6 +964,10 @@ main(int argc, char * * argv) #endif LIST_INIT(&upnphttphead); +#ifdef cygwin + DPRINTF(E_INFO, L_GENERAL, "db_path = %s\n", db_path); +#endif /* cygwin */ + new_db = open_db(); if( !new_db ) { diff --git a/upnpglobalvars.c b/upnpglobalvars.c index 0c71f42..bc64076 100644 --- a/upnpglobalvars.c +++ b/upnpglobalvars.c @@ -48,13 +48,18 @@ */ #include <sys/types.h> #include <netinet/in.h> -#include <linux/limits.h> +//#include <linux/limits.h> #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include "upnpglobalvars.h" #include "upnpdescstrings.h" +#ifndef cygwin +#include <linux/limits.h> +#else +#include <sys/cygwin.h> +#endif /* cygwin */ /* LAN address */ /*const char * listen_addr = 0;*/ @@ -67,7 +67,9 @@ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> +#ifndef cygwin #include <sys/sendfile.h> +#endif /* cygwin */ #include <arpa/inet.h> #include "upnpglobalvars.h" @@ -81,9 +83,18 @@ #include "tivo_utils.h" #include "tivo_commands.h" #endif +#ifndef cygwin //#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much? #define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much? #define MIN_BUFFER_SIZE 65536 +#else +#define MAX_BUFFER_SIZE 4194304 // 4MB for Cygwin +#define MIN_BUFFER_SIZE 65536 +#define MSG_MORE 0 +#include <sys/cygwin.h> +#include<io.h> +#include <string.h> +#endif #ifdef ENABLE_TRANSCODE #define MAX_BUFFER_SIZE_TRANSCODE 1048576 // 1MB @@ -1176,10 +1187,20 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset) off_t send_size; off_t ret; char *buf = NULL; +#ifndef cygwin int try_sendfile = 1; +#else /* cygwin */ + if (EOF == setmode(sendfd, O_BINARY)) + DPRINTF(E_INFO, L_HTTP, "cannot set BINARY mode for pipe"); + if (EOF == setmode(h->socket, O_BINARY)) + DPRINTF(E_INFO, L_HTTP, "cannot set BINARY mode for socket"); + + DPRINTF(E_INFO, L_HTTP, "start sendfile, offset=%lld, end=%lld\n", offset, end_offset); +#endif /* cygwin */ while( offset < end_offset ) { +#ifndef cygwin if( try_sendfile ) { send_size = ( ((end_offset - offset) < MAX_BUFFER_SIZE) ? (end_offset - offset + 1) : MAX_BUFFER_SIZE); @@ -1199,6 +1220,7 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset) continue; } } +#endif /* cygwin */ /* Fall back to regular I/O */ if( !buf ) buf = malloc(MIN_BUFFER_SIZE); @@ -1225,6 +1247,12 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset) #ifdef ENABLE_TRANSCODE +#ifdef cygwin +#ifdef LINK_FFMPEG +int ffmpeg_main(int argc, char **argv); +#endif // LINK_FFMPEG +#endif /* cygwin */ + /* options for transcode specified in .conf file */ enum transcode_audio_enable transcode_audio = TRANSCODE_AUDIO_PCM; enum transcode_video_transcoder transcode_video = TRANSCODE_VIDEO_MENCODER; @@ -1266,6 +1294,15 @@ int exec_transcode(char *source_path, int *fd_r, int transcodeAV, int offset, in char *pDst, *pSrc, *pTmp; int options=0; +#ifndef cygwin +#else /* cygwin */ + int numOfArg; + char *args[60], *ptr; + char source_path_win[PATH_MAX]; + cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, source_path, source_path_win, 1024); + //DPRINTF(E_INFO, L_HTTP, "filename converterd to windows path =%s\n", source_path_win); +#endif /* cygwin */ + sprintf(position, "%d.%d", offset/1000, offset%1000); sprintf(duration, "%d.%d", (end_offset - offset + 1)/1000, (end_offset - offset + 1)%1000); //DPRINTF(E_DEBUG, L_HTTP, "position=%s, duration=%s\n", position, duration); @@ -1302,8 +1339,13 @@ int exec_transcode(char *source_path, int *fd_r, int transcodeAV, int offset, in options |= DURATION_DONE; } else if (strncmp(pSrc, "$SOURCE", 7) == 0) { pSrc += 7; +#ifndef cygwin ret = sprintf(pDst, "\"%s\" ", source_path); pDst += ret; +#else /* cygwin */ + *pDst = '\0'; + pDst = options_tmp2; +#endif /* cygwin */ options |= SOURCE_DONE; } else pSrc++; @@ -1318,8 +1360,25 @@ int exec_transcode(char *source_path, int *fd_r, int transcodeAV, int offset, in //printf("%s %s \n", transcoder, options_tmp); +#ifndef cygwin sprintf(cmd, "%s %s", transcoder, options_tmp); DPRINTF(E_INFO, L_HTTP, "exec %s as following:\n%s\n", transcoder, cmd); +#else + sprintf(cmd, "%s.exe %s", transcoder, options_tmp); + DPRINTF(E_INFO, L_HTTP, "exec %s as following:\n%s \"%s\" %s\n", transcoder, cmd, strstr(transcoder, "ffmpeg") ? source_path : source_path_win, options_tmp2); + + for (numOfArg= 0 ; numOfArg < 60 ; numOfArg++ ) { + ptr = strtok( numOfArg==0 ? cmd : NULL, " " ); + if (ptr == NULL) break; + args[numOfArg] = ptr; + } + args[numOfArg++] = strstr(transcoder, "ffmpeg") ? source_path : source_path_win; + for ( ; numOfArg < 60 ; numOfArg++ ) { + ptr = strtok( ptr==NULL ? options_tmp2 : NULL, " " ); + args[numOfArg] = ptr; + if (ptr == NULL) break; + } +#endif /* cygwin */ /* Create a pipe. */ if(pipe(pipe_c2p)<0) { @@ -1338,8 +1397,33 @@ int exec_transcode(char *source_path, int *fd_r, int transcodeAV, int offset, in close(pipe_c2p[R]); dup2(pipe_c2p[W],1); close(pipe_c2p[W]); +#ifndef cygwin ret = execlp("sh", "sh", "-c", cmd, NULL); //ret = execlp("cmd", "cmd", "/c", cmd, NULL); +#else +#if 0 + for (numOfArg= 0 ; numOfArg < 60 ; numOfArg++ ) { + ptr = strtok( numOfArg==0 ? cmd : NULL, " " ); + if (ptr == NULL) break; + args[numOfArg] = ptr; + } + args[numOfArg++] = strstr(transcoder, "ffmpeg") ? source_path : source_path_win; + for ( ; numOfArg < 60 ; numOfArg++ ) { + ptr = strtok( ptr==NULL ? options34 : NULL, " " ); + args[numOfArg] = ptr; + if (ptr == NULL) break; + } +#endif +#ifdef LINK_FFMPEG + if (strstr(transcoder, "ffmpeg")) + { + ffmpeg_main(numOfArg, args); + exit(0); + } + else +#endif // LINK_FFMPEG + ret = execvp(args[0], args); +#endif if (ret < 0) { perror("exec_transcode"); close(pipe_c2p[W]); @@ -1376,6 +1460,14 @@ send_file_transcode(struct upnphttp * h, int sendfd, int offset, int end_offset, total_byte_read=0; total_byte_send=0; +#if 0 +//#ifdef cygwin + if (EOF == setmode(fd_r, O_BINARY)) + DPRINTF(E_INFO, L_HTTP, "cannot set BINARY mode for pipe"); + if (EOF == setmode(h->socket, O_BINARY)) + DPRINTF(E_INFO, L_HTTP, "cannot set BINARY mode for socket"); +#endif + while(1) { read_stream_size = read(fd_r, buf, MAX_BUFFER_SIZE_TRANSCODE); // read from PIPE @@ -19,7 +19,12 @@ #include <ctype.h> #include <string.h> #include <stdlib.h> +#include "config.h" +#ifndef cygwin #include <linux/limits.h> +#else +#include <sys/cygwin.h> +#endif /* cygwin */ #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> @@ -28,7 +28,10 @@ #include <time.h> #include <fcntl.h> #include <unistd.h> +#include "config.h" +#ifndef cygwin #include <sys/syscall.h> +#endif /* cygwin */ #include <string.h> #include <net/if.h> #include <sys/ioctl.h> @@ -51,7 +54,11 @@ monotonic_us(void) { struct timespec ts; +#ifndef cygwin syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts); +#else + clock_gettime(CLOCK_MONOTONIC, &ts); +#endif //cygwin return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000; } @@ -162,7 +169,11 @@ generate_uuid(unsigned char uuid_out[16]) * nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of * Gregorian reform to the Christian calendar). */ +#ifndef cygwin syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts); +#else + clock_gettime(CLOCK_REALTIME, &ts); +#endif //cygwin time_all = ((u_int64_t)ts.tv_sec) * (NSEC_PER_SEC / 100); time_all += ts.tv_nsec / 100; |