Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/diebuche/ChameleonPrefPane/Sources/ShellProcess.cpp

1/*
2 * shell_process.cpp
3 *
4 * Created by Rekursor on 1/17/2010.
5 *
6 */
7
8#include "ShellProcess.h"
9#include <string.h>
10#include <sys/stat.h>
11#include <string_util.h>
12
13PartitionExtractor* PartitionExtractor::_instance = NULL;
14
15//----------------------------------------------------------------
16// portable open process:
17FILE * ShellProcess::open(const char *cmd, const char *mode) {
18_fpt=::popen(cmd,mode);
19return _fpt;
20}
21
22//----------------------------------------------------------------
23int ShellProcess::close() {
24int ret = ::pclose(_fpt);
25_fpt=NULL;
26return ret;
27}
28
29//----------------------------------------------------------------
30void PartitionInfo::removeSpaces(std::string &str)
31{
32if (!str.size()) return;
33int posl=0,posr=0;
34for (posl=0; posl<str.size()-1 && str[posl]==' '; posl++);
35for (posr=str.size()-1; posr>0 && str[posr]==' '; posr--);
36str = (posl>posr) ? "" : str.substr(posl, posr-posl+1);
37}
38//----------------------------------------------------------------
39/**
40 * return the image index corresponding to a fs:
41 */
42int PartitionInfo::imageIndexFromFs() const
43{
44if (_fsType.find("Apple")!=std::string::npos ||
45_fsType.find("HFS")!=std::string::npos)
46return 0; // Windows
47else if (_fsType.find("Windows")!=std::string::npos ||
48 _fsType.find("Microsoft")!=std::string::npos ||
49 _fsType.find("NTFS")!=std::string::npos ||
50 _fsType.find("FAT")!=std::string::npos)
51return 1; // Windows
52else if (_fsType.find("Linux")!=std::string::npos)
53return 2; // Unknown
54return 10; //Unknown
55
56}
57//----------------------------------------------------------------
58bool PartitionInfo::fromPartitionHdString(const char * inHdStr)
59{
60if (!inHdStr || !(*inHdStr) ||
61strlen(inHdStr)<7 || !strstr(inHdStr,"hd(")) return false;
62
63// enhance me here: should not assume that we have less than 10 partitions per disk/ disks
64_disk = inHdStr[3]-'0';
65_part = inHdStr[5]-'0';
66return true;
67}
68//----------------------------------------------------------------
69const char * PartitionExtractor::checkForRename(const char * label, const char *szHd)
70{
71const int MAX_ALIAS_SIZE=31;
72static char szAlias[MAX_ALIAS_SIZE+1];
73char *q=szAlias;
74const char* szAliases = _renamedParts.c_str();
75
76if (!szHd || !*szHd || !szAliases || !*szAliases) return label; // no renaming wanted
77
78const char * p = strstr(szAliases, szHd);
79if(!p || !(*p)) return label; // this volume must not be renamed, or option is malformed
80
81p+= strlen(szHd); // skip the "hd(n,m) " field
82// multiple aliases can be found separated by a semi-column
83while(*p && *p != ';' && q<(szAlias+MAX_ALIAS_SIZE)) *q++=*p++;
84*q='\0';
85
86return szAlias;
87
88}
89
90// set to 1 the following line for debugging with a fake diskutil file named /diskutil.txt
91// for the debug to be accurate you need to alias (ln -s ...) the user to debug with your real disks
92#define DEBUG_DISKUTIL 0
93
94//----------------------------------------------------------------
95const std::vector<PartitionInfo>&
96PartitionExtractor::extractPartitions(const char* szHide, const char* szRenamed)
97{
98const char * const diskTag = "/dev/disk";
99const char * const nameTag = "NAME";
100const char * const sizeTag = "SIZE";
101
102PartitionInfo partInfo;
103
104char line[1024]="";
105char label[32]="", fsType[32]="" ;
106size_t len=0;
107int disk =0, part=0;
108int label_pos=0, size_pos=0;
109char * p=0,*q=0;
110int skipwhite=0;
111
112_partList.clear();
113if (szHide) hidePartitions(szHide);
114if (szRenamed) renamedPartitions(szRenamed);
115
116#if DEBUG_DISKUTIL
117this->open("cat /diskutil.txt");
118#else
119this->open("diskutil list");
120#endif
121
122while(get_line(line, sizeof(line)-1))
123{
124// printf("%s\n",line);
125len = strlen(line);
126for(skipwhite=0; line[skipwhite]==' ';skipwhite++);
127
128const char * sdisk = strstr(line, diskTag);
129const char * sName = strstr(line, nameTag);
130const char * sSize = strstr(line, sizeTag);
131
132if (sdisk)
133{
134// extract disk number
135sscanf(&sdisk[strlen(diskTag)],"%d", &disk);
136if (disk>=0 && disk <MAX_HD)
137disk = _hdRedirTable[disk];
138}
139else if (len && line[skipwhite]=='#' && line[skipwhite+1]==':')
140{
141label_pos = sName ? (sName - line) : 0;
142size_pos = sSize ? (sSize - line) : 0;
143}
144else if (len && line[skipwhite+1]==':' && isdigit(line[skipwhite]))
145{
146for (p=&line[skipwhite+2], q=fsType; *p && p < &line[label_pos-1]; p++,q++) *q=*p;
147for (p=&line[label_pos], q=label; *p && p < &line[size_pos]; p++,q++) *q=*p;
148
149*q='\0';
150part = line[skipwhite]-'0';
151partInfo.fsType(fsType);
152partInfo.disk(disk);
153partInfo.partition(part);
154partInfo.label(checkForRename(label, partInfo.toHdStr().c_str()));
155size_t len = partInfo.label().length();
156if(len==0){
157strncpy(label, "Untitled", sizeof(label));
158partInfo.label(label);
159}
160
161// filter useless partitions:
162if (partInfo.clabel()[len-1] !='*' &&
163partInfo.fsType()!="EFI" &&
164partInfo.fsType()!="Apple_partition_scheme" &&
165partInfo.fsType()!="Apple_partition_map" &&
166partInfo.fsType()!="Apple_Free"
167)
168{
169std::string diskLabel(trim(label));
170bool found=false;
171// early bail out if we found what we need: DON't make any assumption
172// that Windows is the name of WIN32 bootable disk dir ...
173if (
174fileExists("/Volumes/" + diskLabel + "/boot") ||
175fileExists("/Volumes/" + diskLabel + "/System/Library/Extensions") ||
176fileExists("/Volumes/" + diskLabel + "/ntldr") ||
177fileExists("/Volumes/" + diskLabel + "/bootmgr") ||
178fileExists("/Volumes/" + diskLabel + "/Boot") ||
179fileExists("/Volumes/" + diskLabel + "/pagefile.sys") ||
180fileExists("/Volumes/" + diskLabel + "/hiberfil.sys")
181)
182found=true;
183else if ((strstr(fsType,"Linux") ) && !strstr(fsType, "Linux_Swap"))
184found=true; // Added Linux case
185if (found)
186{ //check if one of them exists
187if (partInfo.label().size()==0) partInfo.label("Untitled");
188if(_hiddenParts.length()==0 ||
189 _hiddenParts.find(partInfo.toHdStr()) == std::string::npos)
190_partList.push_back(partInfo);
191}
192}
193}
194}
195close();
196
197sort(_partList.begin(), _partList.end(), isDiskIndexInf);
198return _partList;
199}
200
201/**
202 * Get the index in the internal partlist of the hd(n,m) partition specified by the input string
203 * return -1 if no match, >=0 if a match happens
204 */
205int PartitionExtractor::getIndexFromHdStringSpec(const char* inHDStr)
206{
207PartitionInfo info;
208
209if (info.fromPartitionHdString(inHDStr)) // try decode the partition disk and part infos
210{
211for (int i=0; i<_partList.size(); i++)
212{
213if (_partList[i].disk() == info.disk() && _partList[i].partition() == info.partition())
214return i;
215}
216}
217
218return -1;
219}
220

Archive Download this file

Revision: 82