xref: /haiku/src/apps/expander/ExpanderRules.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /*****************************************************************************/
2 // Expander
3 // Written by Jérôme Duval
4 //
5 // ExpanderRules.cpp
6 //
7 //
8 // Copyright (c) 2004 OpenBeOS Project
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 /*****************************************************************************/
28 #include "ExpanderRules.h"
29 
30 #include <FindDirectory.h>
31 #include <stdlib.h>
32 #include <Path.h>
33 #include <NodeInfo.h>
34 #include <stdio.h>
35 #include <unistd.h>
36 
37 ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
38 			BString listingCmd, BString expandCmd)
39 	: fMimeType(mimetype.String()),
40 	fFilenameExtension(filenameExtension),
41 	fListingCmd(listingCmd),
42 	fExpandCmd(expandCmd)
43 {
44 
45 }
46 
47 
48 ExpanderRule::ExpanderRule(const char*  mimetype, const char*  filenameExtension,
49 			const char*  listingCmd, const char* expandCmd)
50 	: fMimeType(mimetype),
51 	fFilenameExtension(filenameExtension),
52 	fListingCmd(listingCmd),
53 	fExpandCmd(expandCmd)
54 {
55 
56 }
57 
58 
59 ExpanderRules::ExpanderRules()
60 {
61 	fList.AddItem(new ExpanderRule("", 								".tar.gz", 	"zcat %s | tar -tvf -", 		"zcat %s | tar -xvf -"));
62 	fList.AddItem(new ExpanderRule("", 								".tar.bz2", "bzcat %s | tar -tvf -", 		"bzcat %s | tar -xvf -"));
63 	fList.AddItem(new ExpanderRule("", 								".tar.Z", 	"zcat %s | tar -tvf -", 		"zcat %s | tar -xvf -"));
64 	fList.AddItem(new ExpanderRule("", 								".tgz", 	"zcat %s | tar -tvf -", 		"zcat %s | tar -xvf -"));
65 	fList.AddItem(new ExpanderRule("application/x-tar", 			".tar", 	"tar -tvf %s", 					"tar -xf %s"));
66 	fList.AddItem(new ExpanderRule("application/x-gzip",			".gz", 		"echo %s | sed 's/.gz$//g'", 	"gunzip %s"));
67 	fList.AddItem(new ExpanderRule("application/x-bzip2",				".bz2", 	"echo %s | sed 's/.bz2$//g'", 	"bunzip2 %s"));
68 	fList.AddItem(new ExpanderRule("application/zip", 				".zip", 	"unzip -l %s", 					"unzip -o %s"));
69 	fList.AddItem(new ExpanderRule("application/x-zip-compressed", 	".zip", 	"unzip -l %s", 					"unzip -o %s"));
70 
71 	BFile file;
72 	if (Open(&file) != B_OK)
73 		return;
74 
75 	int fd = file.Dup();
76 	FILE * f = fdopen(fd, "r");
77 
78 	char buffer[1024];
79 	BString strings[4];
80 	while (fgets(buffer, 1024-1, f)!=NULL) {
81 		int32 i=0, j=0;
82 		int32 firstQuote = -1;
83 		while (buffer[i]!= '#' && buffer[i]!= '\n' && j<4) {
84 			if (((j==0)||(j>1))&&(buffer[i] == '"')) {
85 				if (firstQuote >= 0) {
86 					strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
87 					firstQuote = -1;
88 				} else
89 					firstQuote = i;
90 			} else if ((j==1)&&((buffer[i]==' ')||(buffer[i]=='\t'))){
91 				if (firstQuote >= 0) {
92 					if (firstQuote+1!=i) {
93 						strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
94 						firstQuote = -1;
95 					} else
96 						firstQuote = i;
97 				} else
98 					firstQuote = i;
99 			}
100 			i++;
101 		}
102 		if (j==4) {
103 			fList.AddItem(new ExpanderRule(strings[0], strings[1], strings[2], strings[3]));
104 		}
105 	}
106 	fclose(f);
107 	close(fd);
108 }
109 
110 
111 ExpanderRules::~ExpanderRules()
112 {
113 	void *item;
114 	while ((item = fList.RemoveItem((int32)0)))
115 		delete item;
116 }
117 
118 
119 status_t
120 ExpanderRules::Open(BFile *file)
121 {
122 	BPath path;
123 	if (find_directory(B_USER_CONFIG_DIRECTORY, &path) != B_OK)
124 		return B_ERROR;
125 
126 	path.Append("etc/expander.rules");
127 	if (file->SetTo(path.Path(), B_READ_ONLY) == B_OK)
128 		return B_OK;
129 
130 	if (find_directory(B_COMMON_ETC_DIRECTORY, &path) != B_OK)
131 		return B_ERROR;
132 
133 	path.Append("expander.rules");
134 
135 	return file->SetTo(path.Path(), B_READ_ONLY);
136 }
137 
138 
139 ExpanderRule *
140 ExpanderRules::MatchingRule(BString &fileName, const char *filetype)
141 {
142 	int32 count = fList.CountItems();
143 	int32 length = fileName.Length();
144 	for (int32 i=0; i<count; i++) {
145 		ExpanderRule *rule = (ExpanderRule *)fList.ItemAt(i);
146 		if (((!rule->MimeType().IsValid()) || (rule->MimeType()==filetype))
147 			&& (fileName.FindLast(rule->FilenameExtension())==(length-rule->FilenameExtension().Length())))
148 			return rule;
149 	}
150 	return NULL;
151 }
152 
153 
154 ExpanderRule *
155 ExpanderRules::MatchingRule(const entry_ref *ref)
156 {
157 	BEntry entry(ref, true);
158 	BNode node(&entry);
159 	BNodeInfo nodeInfo(&node);
160 	char type[B_MIME_TYPE_LENGTH];
161 	nodeInfo.GetType(type);
162 	BString fileName(ref->name);
163 	return MatchingRule(fileName, type);
164 }
165 
166 
167 RuleRefFilter::RuleRefFilter(ExpanderRules &rules)
168 	: BRefFilter(),
169 	fRules(rules)
170 {
171 }
172 
173 
174 bool
175 RuleRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat *st,
176 	const char *filetype)
177 {
178 	if (node->IsDirectory() || node->IsSymLink())
179 		return true;
180 
181 	BString fileName(ref->name);
182 	return (fRules.MatchingRule(fileName, filetype)!=NULL);
183 }
184