/* * XmNap A Motif napster client * * Copyright (C) 2000 Mats Peterson * * This program 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. * * This program 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Please send any comments/bug reports to * mats_peterson@swipnet.se (Mats Peterson) */ #include #include #include #include #include #include #include #include #include "main.h" #include "connect.h" #include "message.h" #include "shared.h" #include "fsbox.h" #include "mp3info.h" #include "msgbox.h" #include "util.h" SHARED *sharedFiles = NULL; SHAREDDIR *sharedDirs = NULL; static String initDir = NULL; static String MapSharedName(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); } } .