• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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