Chameleon Applications

Chameleon Applications Svn Source Tree

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

Archive Download this file

Revision: 62