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// uncomment the following line for debug
90#define DEBUG_DISKUTIL 0
91
92//----------------------------------------------------------------
93const std::vector<PartitionInfo>&
94PartitionExtractor::extractPartitions(const char* szHide, const char* szRenamed)
95{
96const char * const diskTag = "/dev/disk";
97const char * const nameTag = "NAME";
98const char * const sizeTag = "SIZE";
99
100PartitionInfo partInfo;
101
102char line[1024]="";
103char label[32]="", fsType[32]="" ;
104size_t len=0;
105int disk =0, part=0;
106int label_pos=0, size_pos=0;
107char * p=0,*q=0;
108int skipwhite=0;
109
110_partList.clear();
111if (szHide) hidePartitions(szHide);
112if (szRenamed) renamedPartitions(szRenamed);
113
114#if DEBUG_DISKUTIL
115this->open("cat /diskutil.txt");
116#else
117this->open("diskutil list");
118#endif
119
120while(get_line(line, sizeof(line)-1))
121{
122// printf("%s\n",line);
123len = strlen(line);
124for(skipwhite=0; line[skipwhite]==' ';skipwhite++);
125
126const char * sdisk = strstr(line, diskTag);
127const char * sName = strstr(line, nameTag);
128const char * sSize = strstr(line, sizeTag);
129
130if (sdisk)
131{
132// extract disk number
133sscanf(&sdisk[strlen(diskTag)],"%d", &disk);
134if (disk>=0 && disk <MAX_HD)
135disk = _hdRedirTable[disk];
136}
137else if (len && line[skipwhite]=='#' && line[skipwhite+1]==':')
138{
139label_pos = sName ? (sName - line) : 0;
140size_pos = sSize ? (sSize - line) : 0;
141}
142else if (len && line[skipwhite+1]==':' && isdigit(line[skipwhite]))
143{
144for (p=&line[skipwhite+2], q=fsType; *p && p < &line[label_pos-1]; p++,q++) *q=*p;
145for (p=&line[label_pos], q=label; *p && p < &line[size_pos]; p++,q++) *q=*p;
146
147*q='\0';
148part = line[skipwhite]-'0';
149partInfo.fsType(fsType);
150partInfo.disk(disk);
151partInfo.partition(part);
152partInfo.label(checkForRename(label, partInfo.toHdStr().c_str()));
153size_t len = partInfo.label().length();
154// filter useless partitions:
155if ( len > 0 &&
156partInfo.clabel()[len-1] !='*' &&
157partInfo.fsType()!="EFI" &&
158partInfo.fsType()!="Apple_partition_scheme" &&
159partInfo.fsType()!="Apple_partition_map" &&
160partInfo.fsType()!="Apple_Free"
161)
162{
163std::string diskLabel(trim(label));
164bool found=false;
165
166// early bail out if we found what we need: DON't make any assumption
167// that Windows is the name of WIN32 bootable disk dir ...
168if (
169fileExists("/Volumes/" + diskLabel + "/boot") ||
170fileExists("/Volumes/" + diskLabel + "/System/Library/Extensions") ||
171fileExists("/Volumes/" + diskLabel + "/ntldr") ||
172fileExists("/Volumes/" + diskLabel + "/bootmgr") ||
173fileExists("/Volumes/" + diskLabel + "/Boot") ||
174fileExists("/Volumes/" + diskLabel + "/pagefile.sys") ||
175fileExists("/Volumes/" + diskLabel + "/hiberfil.sys")
176)
177found=true;
178else if ((strstr(fsType,"Linux") ) && !strstr(fsType, "Linux_Swap"))
179found=true; // Added Linux case
180if (found)
181{ //check if one of them exists
182if (partInfo.label().size()==0) partInfo.label("Untitled");
183if(_hiddenParts.length()==0 ||
184 _hiddenParts.find(partInfo.toHdStr()) == std::string::npos)
185_partList.push_back(partInfo);
186}
187}
188}
189}
190close();
191
192sort(_partList.begin(), _partList.end(), isDiskIndexInf);
193return _partList;
194}
195
196/**
197 * Get the index in the internal partlist of the hd(n,m) partition specified by the input string
198 * return -1 if no match, >=0 if a match happens
199 */
200int PartitionExtractor::getIndexFromHdStringSpec(const char* inHDStr)
201{
202PartitionInfo info;
203
204if (info.fromPartitionHdString(inHDStr)) // try decode the partition disk and part infos
205{
206for (int i=0; i<_partList.size(); i++)
207{
208if (_partList[i].disk() == info.disk() && _partList[i].partition() == info.partition())
209return i;
210}
211}
212
213return -1;
214}
215

Archive Download this file

Revision: 59