1 /**
2 * \file pathutils.c
3 *
4 * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
5 * Copyright (C) 2006 Chris A. Debenham <chris@adebenham.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22 #include "common.h"
23 #include "pathutils.h"
24 #include <stdlib.h>
25 #include <limits.h>
26 #include <string.h>
27 #include <libgen.h>
28
29 /* Find the folder_id of a given path
30 * Runs by walking through folders structure */
31 static uint32_t
lookup_folder_id(LIBMTP_folder_t * folder,char * path,char * parent)32 lookup_folder_id (LIBMTP_folder_t * folder, char * path, char * parent)
33 {
34 char * current;
35 uint32_t ret = (uint32_t) -1;
36
37 if (strcmp(path,"/")==0)
38 return 0;
39
40 if (folder == NULL) {
41 return ret;
42 }
43
44 current = malloc (strlen(parent) + strlen(folder->name) + 2);
45 sprintf(current,"%s/%s",parent,folder->name);
46 if (strcasecmp (path, current) == 0) {
47 free (current);
48 return folder->folder_id;
49 }
50 if (strncasecmp (path, current, strlen (current)) == 0) {
51 ret = lookup_folder_id (folder->child, path, current);
52 }
53 free (current);
54 if (ret != (uint32_t) (-1)) {
55 return ret;
56 }
57 ret = lookup_folder_id (folder->sibling, path, parent);
58 return ret;
59 }
60
61 /* Parses a string to find item_id */
62 int
parse_path(char * path,LIBMTP_file_t * files,LIBMTP_folder_t * folders)63 parse_path (char * path, LIBMTP_file_t * files, LIBMTP_folder_t * folders)
64 {
65 char *rest;
66 uint32_t item_id;
67
68 // Check if path is an item_id
69 if (*path != '/') {
70 item_id = strtoul(path, &rest, 0);
71 // really should check contents of "rest" here...
72 /* if not number, assume a file name */
73 if (item_id == 0) {
74 LIBMTP_file_t * file = files;
75
76 /* search for matching name */
77 while (file != NULL) {
78 if (strcasecmp (file->filename, path) == 0) {
79 return file->item_id;
80 }
81 file = file->next;
82 }
83 }
84 return item_id;
85 }
86 // Check if path is a folder
87 item_id = lookup_folder_id(folders,path,"");
88 if (item_id == (uint32_t) -1) {
89 char * dirc = strdup(path);
90 char * basec = strdup(path);
91 char * parent = dirname(dirc);
92 char * filename = basename(basec);
93 uint32_t parent_id = lookup_folder_id(folders,parent,"");
94 LIBMTP_file_t * file;
95
96 file = files;
97 while (file != NULL) {
98 if (file->parent_id == parent_id) {
99 if (strcasecmp (file->filename, filename) == 0) {
100 free(dirc);
101 free(basec);
102 return file->item_id;
103 }
104 }
105 file = file->next;
106 }
107 free(dirc);
108 free(basec);
109 } else {
110 return item_id;
111 }
112
113 return -1;
114 }
115
progress(const uint64_t sent,const uint64_t total,void const * const data)116 int progress (const uint64_t sent, const uint64_t total, void const * const data)
117 {
118 int percent = (sent*100)/total;
119 #ifdef __WIN32__
120 printf("Progress: %I64u of %I64u (%d%%)\r", sent, total, percent);
121 #else
122 printf("Progress: %llu of %llu (%d%%)\r", sent, total, percent);
123 #endif
124 fflush(stdout);
125 return 0;
126 }
127
128 /* Find the file type based on extension */
129 LIBMTP_filetype_t
find_filetype(const char * filename)130 find_filetype (const char * filename)
131 {
132 char *ptype;
133 LIBMTP_filetype_t filetype;
134
135 #ifdef __WIN32__
136 ptype = strrchr(filename, '.');
137 #else
138 ptype = rindex(filename,'.');
139 #endif
140 // This accounts for the case with a filename without any "." (period).
141 if (!ptype) {
142 ptype = "";
143 } else {
144 ++ptype;
145 }
146
147 /* This need to be kept constantly updated as new file types arrive. */
148 if (!strcasecmp (ptype, "wav")) {
149 filetype = LIBMTP_FILETYPE_WAV;
150 } else if (!strcasecmp (ptype, "mp3")) {
151 filetype = LIBMTP_FILETYPE_MP3;
152 } else if (!strcasecmp (ptype, "wma")) {
153 filetype = LIBMTP_FILETYPE_WMA;
154 } else if (!strcasecmp (ptype, "ogg")) {
155 filetype = LIBMTP_FILETYPE_OGG;
156 } else if (!strcasecmp (ptype, "mp4")) {
157 filetype = LIBMTP_FILETYPE_MP4;
158 } else if (!strcasecmp (ptype, "wmv")) {
159 filetype = LIBMTP_FILETYPE_WMV;
160 } else if (!strcasecmp (ptype, "avi")) {
161 filetype = LIBMTP_FILETYPE_AVI;
162 } else if (!strcasecmp (ptype, "mpeg") || !strcasecmp (ptype, "mpg")) {
163 filetype = LIBMTP_FILETYPE_MPEG;
164 } else if (!strcasecmp (ptype, "asf")) {
165 filetype = LIBMTP_FILETYPE_ASF;
166 } else if (!strcasecmp (ptype, "qt") || !strcasecmp (ptype, "mov")) {
167 filetype = LIBMTP_FILETYPE_QT;
168 } else if (!strcasecmp (ptype, "wma")) {
169 filetype = LIBMTP_FILETYPE_WMA;
170 } else if (!strcasecmp (ptype, "jpg") || !strcasecmp (ptype, "jpeg")) {
171 filetype = LIBMTP_FILETYPE_JPEG;
172 } else if (!strcasecmp (ptype, "jfif")) {
173 filetype = LIBMTP_FILETYPE_JFIF;
174 } else if (!strcasecmp (ptype, "tif") || !strcasecmp (ptype, "tiff")) {
175 filetype = LIBMTP_FILETYPE_TIFF;
176 } else if (!strcasecmp (ptype, "bmp")) {
177 filetype = LIBMTP_FILETYPE_BMP;
178 } else if (!strcasecmp (ptype, "gif")) {
179 filetype = LIBMTP_FILETYPE_GIF;
180 } else if (!strcasecmp (ptype, "pic") || !strcasecmp (ptype, "pict")) {
181 filetype = LIBMTP_FILETYPE_PICT;
182 } else if (!strcasecmp (ptype, "png")) {
183 filetype = LIBMTP_FILETYPE_PNG;
184 } else if (!strcasecmp (ptype, "wmf")) {
185 filetype = LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT;
186 } else if (!strcasecmp (ptype, "ics")) {
187 filetype = LIBMTP_FILETYPE_VCALENDAR2;
188 } else if (!strcasecmp (ptype, "exe") || !strcasecmp (ptype, "com") ||
189 !strcasecmp (ptype, "bat") || !strcasecmp (ptype, "dll") ||
190 !strcasecmp (ptype, "sys")) {
191 filetype = LIBMTP_FILETYPE_WINEXEC;
192 } else if (!strcasecmp (ptype, "aac")) {
193 filetype = LIBMTP_FILETYPE_AAC;
194 } else if (!strcasecmp (ptype, "mp2")) {
195 filetype = LIBMTP_FILETYPE_MP2;
196 } else if (!strcasecmp (ptype, "flac")) {
197 filetype = LIBMTP_FILETYPE_FLAC;
198 } else if (!strcasecmp (ptype, "m4a")) {
199 filetype = LIBMTP_FILETYPE_M4A;
200 } else if (!strcasecmp (ptype, "doc")) {
201 filetype = LIBMTP_FILETYPE_DOC;
202 } else if (!strcasecmp (ptype, "xml")) {
203 filetype = LIBMTP_FILETYPE_XML;
204 } else if (!strcasecmp (ptype, "xls")) {
205 filetype = LIBMTP_FILETYPE_XLS;
206 } else if (!strcasecmp (ptype, "ppt")) {
207 filetype = LIBMTP_FILETYPE_PPT;
208 } else if (!strcasecmp (ptype, "mht")) {
209 filetype = LIBMTP_FILETYPE_MHT;
210 } else if (!strcasecmp (ptype, "jp2")) {
211 filetype = LIBMTP_FILETYPE_JP2;
212 } else if (!strcasecmp (ptype, "jpx")) {
213 filetype = LIBMTP_FILETYPE_JPX;
214 } else if (!strcasecmp (ptype, "bin")) {
215 filetype = LIBMTP_FILETYPE_FIRMWARE;
216 } else if (!strcasecmp (ptype, "vcf")) {
217 filetype = LIBMTP_FILETYPE_VCARD3;
218 } else {
219 /* Tagging as unknown file type */
220 filetype = LIBMTP_FILETYPE_UNKNOWN;
221 }
222 printf("type: %s, %d\n", ptype, filetype);
223 return filetype;
224 }
225
226 /* Function that compensate for missing libgen.h on Windows */
227 #ifndef HAVE_LIBGEN_H
basename(char * in)228 static char *basename(char *in) {
229 char *p;
230
231 if (in == NULL)
232 return NULL;
233 p = in + strlen(in) - 1;
234 while (*p != '\\' && *p != '/' && *p != ':')
235 { p--; }
236 return ++p;
237 }
238 #endif
239