#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
/* #include <fnmatch.h> */
#include <errno.h>
#include "connap.h"
#include "connect.h"
#include "message.h"
#include "shared.h"
#include "mp3info.h"
#include "util.h"
SHARED *shared_files = NULL;
SHAREDDIR *shared_dirs = NULL;
static char *init_dir = NULL;
#if 0
static char *map_shared_name(String name)
{
static String mappedName = NULL;
String p;
if (mappedName)
XtFree(mappedName);
mappedName = XtMalloc(strlen(name) + 5);
sprintf(mappedName, "C:%s", name);
for (p = (mappedName + 2); *p; p++) {
if ((*p) == '/')
(*p) = '\\';
}
return mappedName;
}
static void NotifySharedFile(SHARED *shared)
{
String tmp;
if (! srvConn)
return;
tmp = XtMalloc(512);
sprintf(tmp, "\"%s\" 00000000000000000000000000000000 %d %d %d %d",
MapSharedName(shared->fileName), shared->size,
shared->bitRate, shared->freq, shared->sec);
if (SendMsg(MSG_CLIENT_ADD_FILE, tmp))
Disconnect(strerror(errno));
XtFree(tmp);
}
void NotifySharedFiles(void)
{
SHARED *shared;
if (! sharedFiles)
return;
SimpleMsg("Notifying shared files...");
for (shared = sharedFiles; shared; shared = shared->next) {
NotifySharedFile(shared);
}
SimpleMsgRemove();
}
static void AddSharedFile(String name, int size)
{
SHARED *newShared, *rec;
MP3INFO *info;
info = MP3Info(name);
if (! info) {
ErrMsg("Error reading MP3 info");
return;
}
newShared = XtNew(SHARED);
newShared->fileName = XtNewString(name);
newShared->size = size;
newShared->bitRate = info->bitrate;
newShared->freq = info->freq;
newShared->sec = info->seconds;
newShared->next = NULL;
if (! sharedFiles) {
sharedFiles = newShared;
} else {
for (rec = sharedFiles; rec->next; rec = rec->next);
rec->next = newShared;
}
if (srvConn)
NotifySharedFile(newShared);
}
void RemoveSharedFile(String name)
{
SHARED *shared, *prevShared = NULL;
for (shared = sharedFiles; shared; shared = shared->next) {
if (! strcmp(shared->fileName, name))
break;
prevShared = shared;
}
if (! shared)
return;
if (prevShared)
prevShared->next = shared->next;
else
sharedFiles = sharedFiles->next;
if (srvConn) {
if (SendMsg(MSG_CLIENT_REMOVE_FILE,
MapSharedName(shared->fileName)))
Disconnect(strerror(errno));
}
XtFree(shared->fileName);
XtFree((char*)shared);
}
static void AddSharedDir(String name)
{
SHAREDDIR *newDir, *dirPtr, *prevPtr = NULL;
newDir = XtNew(SHAREDDIR);
newDir->dirName = XtNewString(name);
for (dirPtr = sharedDirs; dirPtr; dirPtr = dirPtr->next) {
if (strcasecmp(dirPtr->dirName, newDir->dirName) > 0)
break;
prevPtr = dirPtr;
}
if (prevPtr) {
newDir->next = prevPtr->next;
prevPtr->next = newDir;
} else {
newDir->next = sharedDirs;
sharedDirs = newDir;
}
}
int RemoveSharedDir(String name)
{
SHAREDDIR *dir, *prevDir = NULL;
SHARED *shared;
String tmp;
for (dir = sharedDirs; dir; dir = dir->next) {
if (! strcmp(dir->dirName, name))
break;
prevDir = dir;
}
if (! dir) {
ErrMsg("Directory is not shared");
return 0;
}
tmp = XtMalloc(PATH_MAX + 2);
sprintf(tmp, "%s*", name);
for (shared = sharedFiles; shared; shared = shared->next) {
if (! fnmatch(tmp, shared->fileName, 0))
RemoveSharedFile(shared->fileName);
}
XtFree(tmp);
if (prevDir)
prevDir->next = dir->next;
else
sharedDirs = sharedDirs->next;
XtFree(dir->dirName);
XtFree((char*)dir);
return 1;
}
static void RecurseDir(String dir)
{
struct stat st;
String tmp = XtMalloc(4096);
SHARED *shared;
int match;
FILE *fd;
sprintf(tmp, "find '%s' -type f -name '*.[mM][pP]3' 2>/dev/null", dir);
if (! (fd = popen(tmp, "r"))) {
ErrMsg("popen failed");
return;
}
while (fgets(tmp, 4096, fd)) {
tmp[strlen(tmp) - 1] = 0;
if (stat(tmp, &st) == -1)
continue;
if (strchr(tmp, '\"'))
continue;
match = 0;
for (shared = sharedFiles, match = 0; shared;
shared = shared->next) {
if (! strcmp(shared->fileName, tmp)) {
match = 1;
break;
}
}
if (match)
continue;
AddSharedFile(tmp, st.st_size);
}
pclose(fd);
XtFree(tmp);
}
int AddSharedFiles2(String dir)
{
SHAREDDIR *sharedDir;
SHARED *shared;
String tmp;
int newDir = 1, sameDir = 0;
FILE *fd;
tmp = XtMalloc(PATH_MAX + 2);
for (sharedDir = sharedDirs; sharedDir; sharedDir = sharedDir->next) {
sprintf(tmp, "%s*", sharedDir->dirName);
if (! fnmatch(tmp, dir, 0)) {
newDir = 0;
if (! strcmp(sharedDir->dirName, dir))
sameDir = 1;
break;
} else {
sprintf(tmp, "%s*", dir);
if (! fnmatch(tmp, sharedDir->dirName, 0)) {
newDir = -1;
break;
}
}
}
XtFree(tmp);
if (newDir == -1) {
ErrMsg("Please remove the children directories first");
return 0;
} else if (newDir) {
AddSharedDir(dir);
} else if (! sameDir) {
ErrMsg("A shared parent directory already exists");
return 0;
}
SimpleMsg("Updating File List");
if (! newDir) {
for (shared = sharedFiles; shared; shared = shared->next) {
if (! (fd = fopen(shared->fileName, "r"))) {
RemoveSharedFile(shared->fileName);
} else
fclose(fd);
}
}
RecurseDir(dir);
SimpleMsgRemove();
return 1;
}
int AddSharedFiles(void)
{
String dir;
if (! initDir)
initDir = XtNewString(".");
dir = ChooseSharedDir(initDir);
if (! strlen(dir))
return 0;
if (*(dir + 1))
*(strrchr(dir, '/')) = 0;
XtFree(initDir);
initDir = XtNewString(dir);
if (! AddSharedFiles2(dir))
return 0;
return 1;
}
int RemoveSharedFiles(String dir)
{
if(! RemoveSharedDir(dir))
return 0;
return 1;
}
static void AddSharedListFile(String s)
{
SHARED *newShared, *rec;
String p;
newShared = XtNew(SHARED);
p = strtok(s, "\"");
newShared->fileName = XtNewString(p);
newShared->size = atoi(strtok(NULL, " "));
newShared->bitRate = atoi(strtok(NULL, " "));
newShared->freq = atoi(strtok(NULL, " "));
newShared->sec = atoi(strtok(NULL, " "));
newShared->next = NULL;
if (! sharedFiles) {
sharedFiles = newShared;
} else {
for (rec = sharedFiles; rec->next; rec = rec->next);
rec->next = newShared;
}
}
void ReadFileList(FILE *fd)
{
String line;
int i, numFiles;
fscanf(fd, "%d\n", &numFiles);
if (! numFiles)
return;
line = XtMalloc(512);
for (i = 0; i < numFiles; i++) {
fgets(line, 512, fd);
line[strlen(line) - 1] = 0;
AddSharedListFile(line);
}
XtFree(line);
}
void SaveFileList(FILE *fd)
{
SHARED *shared;
int i;
for (shared = sharedFiles, i = 0; shared;
shared = shared->next, i++);
fprintf(fd, "%d\n", i);
if (! i)
return;
for (shared = sharedFiles; shared; shared = shared->next) {
fprintf(fd, "\"%s\" %d %d %d %d\n",
shared->fileName, shared->size, shared->bitRate,
shared->freq, shared->sec);
}
}
#endif