Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/process.cpp

1/*
2 * shell_process.cpp
3 *
4 * Created by Rekursor on 1/17/2010.
5 *
6 */
7
8#include "process.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//----------------------------------------------------------------
89const std::vector<PartitionInfo>&
90PartitionExtractor::extractPartitions(const char* szHide, const char* szRenamed)
91{
92const char * const diskTag = "/dev/disk";
93const char * const nameTag = "NAME";
94const char * const sizeTag = "SIZE";
95
96PartitionInfo partInfo;
97
98char line[1024]="";
99char label[32]="", fsType[32]="" ;
100size_t len=0;
101int disk =0, part=0;
102int label_pos=0, size_pos=0;
103char * p=0,*q=0;
104int skipwhite=0;
105
106_partList.clear();
107if (szHide) hidePartitions(szHide);
108if (szRenamed) renamedPartitions(szRenamed);
109this->open("diskutil list");
110
111while(get_line(line, sizeof(line)-1))
112{
113// printf("%s\n",line);
114len = strlen(line);
115for(skipwhite=0; line[skipwhite]==' ';skipwhite++);
116
117const char * sdisk = strstr(line, diskTag);
118const char * sName = strstr(line, nameTag);
119const char * sSize = strstr(line, sizeTag);
120
121if (sdisk)
122{
123// extract disk number
124disk= sdisk[strlen(diskTag)]-'0';
125if (disk>=0 && disk <MAX_HD)
126disk = _hdRedirTable[disk];
127}
128else if (len && line[skipwhite]=='#' && line[skipwhite+1]==':')
129{
130label_pos = sName ? (sName - line) : 0;
131size_pos = sSize ? (sSize - line) : 0;
132}
133else if (len && line[skipwhite+1]==':' && isdigit(line[skipwhite]))
134{
135for (p=&line[skipwhite+2], q=fsType; *p && p < &line[label_pos-1]; p++,q++) *q=*p;
136for (p=&line[label_pos], q=label; *p && p < &line[size_pos]; p++,q++) *q=*p;
137
138*q='\0';
139part = line[skipwhite]-'0';
140partInfo.fsType(fsType);
141partInfo.disk(disk);
142partInfo.partition(part);
143partInfo.label(checkForRename(label, partInfo.toHdStr().c_str()));
144size_t len = partInfo.label().length();
145// filter useless partitions:
146if ( len > 0 &&
147partInfo.clabel()[len-1] !='*' &&
148partInfo.fsType()!="EFI" &&
149partInfo.fsType()!="Apple_partition_scheme" &&
150partInfo.fsType()!="Apple_partition_map" &&
151partInfo.fsType()!="Apple_Free"
152)
153{
154std::string DiskLabel(label), UnixPath, WinPath;
155DiskLabel.erase( DiskLabel.find_last_not_of(" ") + 1);
156bool found=false;
157
158// early bail out if we found what we need:
159if (fileExists((UnixPath = "/Volumes/" + DiskLabel + "/usr/bin/man")))
160found=true;
161else if ((strstr(label,"System Reserved") ) || // don't filter system reserved windows 7 boot parts
162 fileExists((WinPath="/Volumes/" + DiskLabel + "/Windows/system.ini")))
163found=true;
164else if (strstr(fsType,"Linux") && !strstr(fsType, "Linux_Swap"))
165found=true; // Added Linux case
166if (found)
167{ //check if one of them exists
168if (partInfo.label().size()==0) partInfo.label("Untitled");
169if(_hiddenParts.length()==0 ||
170 _hiddenParts.find(partInfo.toHdStr()) == std::string::npos)
171_partList.push_back(partInfo);
172}
173}
174}
175}
176close();
177
178sort(_partList.begin(), _partList.end(), isDiskIndexInf);
179return _partList;
180}
181
182/**
183 * Get the index in the internal partlist of the hd(n,m) partition specified by the input string
184 * return -1 if no match, >=0 if a match happens
185 */
186int PartitionExtractor::getIndexFromHdStringSpec(const char* inHDStr)
187{
188PartitionInfo info;
189
190if (info.fromPartitionHdString(inHDStr)) // try decode the partition disk and part infos
191{
192for (int i=0; i<_partList.size(); i++)
193{
194if (_partList[i].disk() == info.disk() && _partList[i].partition() == info.partition())
195return i;
196}
197}
198
199return -1;
200}
201

Archive Download this file

Revision: 44