1/* 2Open Tracker License 3 4Terms and Conditions 5 6Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a copy of 9this software and associated documentation files (the "Software"), to deal in 10the Software without restriction, including without limitation the rights to 11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12of the Software, and to permit persons to whom the Software is furnished to do 13so, subject to the following conditions: 14 15The above copyright notice and this permission notice applies to all licensees 16and shall be included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25Except as contained in this notice, the name of Be Incorporated shall not be 26used in advertising or otherwise to promote the sale, use or other dealings in 27this Software without prior written authorization from Be Incorporated. 28 29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30of Be Incorporated in the United States and other countries. Other brand product 31names are registered trademarks or trademarks of their respective holders. 32All rights reserved. 33*/ 34 35 36#include "FilePermissionsView.h" 37 38#include <stdio.h> 39#include <stdlib.h> 40 41#include <Beep.h> 42#include <Catalog.h> 43#include <Locale.h> 44 45 46const uint32 kPermissionsChanged = 'prch'; 47const uint32 kNewOwnerEntered = 'nwow'; 48const uint32 kNewGroupEntered = 'nwgr'; 49 50 51#undef B_TRANSLATION_CONTEXT 52#define B_TRANSLATION_CONTEXT "FilePermissionsView" 53 54FilePermissionsView::FilePermissionsView(BRect rect, Model* model) 55 : BView(rect, "FilePermissionsView", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW), 56 fModel(model) 57{ 58 // Constants for the column labels: "User", "Group" and "Other". 59 const float kColumnLabelMiddle = 77, kColumnLabelTop = 6, 60 kColumnLabelSpacing = 37, kColumnLabelBottom = 20, 61 kColumnLabelWidth = 35, kAttribFontHeight = 10; 62 63 BStringView* strView; 64 65 strView = new BStringView( 66 BRect(kColumnLabelMiddle - kColumnLabelWidth / 2, 67 kColumnLabelTop, 68 kColumnLabelMiddle + kColumnLabelWidth / 2, 69 kColumnLabelBottom), 70 "", B_TRANSLATE("Owner")); 71 AddChild(strView); 72 strView->SetAlignment(B_ALIGN_CENTER); 73 strView->SetFontSize(kAttribFontHeight); 74 75 strView = new BStringView( 76 BRect(kColumnLabelMiddle - kColumnLabelWidth / 2 77 + kColumnLabelSpacing, 78 kColumnLabelTop, 79 kColumnLabelMiddle + kColumnLabelWidth / 2 + kColumnLabelSpacing, 80 kColumnLabelBottom), 81 "", B_TRANSLATE("Group")); 82 AddChild(strView); 83 strView->SetAlignment(B_ALIGN_CENTER); 84 strView->SetFontSize(kAttribFontHeight); 85 86 strView = new BStringView( 87 BRect(kColumnLabelMiddle - kColumnLabelWidth / 2 88 + 2 * kColumnLabelSpacing, 89 kColumnLabelTop, 90 kColumnLabelMiddle + kColumnLabelWidth / 2 91 + 2 * kColumnLabelSpacing, 92 kColumnLabelBottom), 93 "", B_TRANSLATE("Other")); 94 AddChild(strView); 95 strView->SetAlignment(B_ALIGN_CENTER); 96 strView->SetFontSize(kAttribFontHeight); 97 98 // Constants for the row labels: "Read", "Write" and "Execute". 99 const float kRowLabelLeft = 10, kRowLabelTop = kColumnLabelTop + 15, 100 kRowLabelVerticalSpacing = 18, kRowLabelRight = kColumnLabelMiddle 101 - kColumnLabelWidth / 2 - 5, kRowLabelHeight = 14; 102 103 strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop, 104 kRowLabelRight, kRowLabelTop + kRowLabelHeight), 105 "", B_TRANSLATE("Read")); 106 AddChild(strView); 107 strView->SetAlignment(B_ALIGN_RIGHT); 108 strView->SetFontSize(kAttribFontHeight); 109 110 strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop 111 + kRowLabelVerticalSpacing, kRowLabelRight, kRowLabelTop 112 + kRowLabelVerticalSpacing + kRowLabelHeight), 113 "", B_TRANSLATE("Write")); 114 AddChild(strView); 115 strView->SetAlignment(B_ALIGN_RIGHT); 116 strView->SetFontSize(kAttribFontHeight); 117 118 strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop 119 + 2 * kRowLabelVerticalSpacing, kRowLabelRight, kRowLabelTop 120 + 2 * kRowLabelVerticalSpacing + kRowLabelHeight), 121 "", B_TRANSLATE("Execute")); 122 AddChild(strView); 123 strView->SetAlignment(B_ALIGN_RIGHT); 124 strView->SetFontSize(kAttribFontHeight); 125 126 // Constants for the 3x3 check box array. 127 const float kLeftMargin = kRowLabelRight + 15, 128 kTopMargin = kRowLabelTop - 2, 129 kHorizontalSpacing = kColumnLabelSpacing, 130 kVerticalSpacing = kRowLabelVerticalSpacing, 131 kCheckBoxWidth = 18, kCheckBoxHeight = 18; 132 133 FocusCheckBox** checkBoxArray[3][3] = { 134 { 135 &fReadUserCheckBox, 136 &fReadGroupCheckBox, 137 &fReadOtherCheckBox 138 }, 139 { 140 &fWriteUserCheckBox, 141 &fWriteGroupCheckBox, 142 &fWriteOtherCheckBox 143 }, 144 { 145 &fExecuteUserCheckBox, 146 &fExecuteGroupCheckBox, 147 &fExecuteOtherCheckBox 148 } 149 }; 150 151 for (int32 x = 0; x < 3; x++) { 152 for (int32 y = 0; y < 3; y++) { 153 *checkBoxArray[y][x] = 154 new FocusCheckBox(BRect(kLeftMargin + kHorizontalSpacing * x, 155 kTopMargin + kVerticalSpacing * y, 156 kLeftMargin + kHorizontalSpacing * x + kCheckBoxWidth, 157 kTopMargin + kVerticalSpacing * y + kCheckBoxHeight), 158 "", "", new BMessage(kPermissionsChanged)); 159 AddChild(*checkBoxArray[y][x]); 160 } 161 } 162 163 const float kTextControlLeft = 170, kTextControlRight = 270, 164 kTextControlTop = kColumnLabelTop, kTextControlHeight = 14, 165 kTextControlSpacing = 16; 166 167 strView = new BStringView(BRect(kTextControlLeft, kTextControlTop, 168 kTextControlRight, kTextControlTop + kTextControlHeight), "", 169 B_TRANSLATE("Owner")); 170 strView->SetAlignment(B_ALIGN_CENTER); 171 strView->SetFontSize(kAttribFontHeight); 172 AddChild(strView); 173 174 fOwnerTextControl = new BTextControl( 175 BRect(kTextControlLeft, 176 kTextControlTop - 2 + kTextControlSpacing, 177 kTextControlRight, 178 kTextControlTop + kTextControlHeight - 2 + kTextControlSpacing), 179 "", "", "", new BMessage(kNewOwnerEntered)); 180 fOwnerTextControl->SetDivider(0); 181 AddChild(fOwnerTextControl); 182 183 strView = new BStringView(BRect(kTextControlLeft, 184 kTextControlTop + 5 + 2 * kTextControlSpacing, 185 kTextControlRight, 186 kTextControlTop + 2 + 2 * kTextControlSpacing 187 + kTextControlHeight), 188 "", B_TRANSLATE("Group")); 189 strView->SetAlignment(B_ALIGN_CENTER); 190 strView->SetFontSize(kAttribFontHeight); 191 AddChild(strView); 192 193 fGroupTextControl = new BTextControl(BRect(kTextControlLeft, 194 kTextControlTop + 3 * kTextControlSpacing, 195 kTextControlRight, 196 kTextControlTop + 3 * kTextControlSpacing + kTextControlHeight), 197 "", "", "", new BMessage(kNewGroupEntered)); 198 fGroupTextControl->SetDivider(0); 199 AddChild(fGroupTextControl); 200 201 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 202 203 ModelChanged(model); 204} 205 206 207void 208FilePermissionsView::ModelChanged(Model* model) 209{ 210 fModel = model; 211 212 bool hideCheckBoxes = false; 213 uid_t nodeOwner = 0; 214 gid_t nodeGroup = 0; 215 mode_t perms = 0; 216 217 if (fModel != NULL) { 218 BNode node(fModel->EntryRef()); 219 220 if (node.InitCheck() == B_OK) { 221 if (fReadUserCheckBox->IsHidden()) { 222 fReadUserCheckBox->Show(); 223 fReadGroupCheckBox->Show(); 224 fReadOtherCheckBox->Show(); 225 fWriteUserCheckBox->Show(); 226 fWriteGroupCheckBox->Show(); 227 fWriteOtherCheckBox->Show(); 228 fExecuteUserCheckBox->Show(); 229 fExecuteGroupCheckBox->Show(); 230 fExecuteOtherCheckBox->Show(); 231 } 232 233 if (node.GetPermissions(&perms) == B_OK) { 234 fReadUserCheckBox->SetValue((int32)(perms & S_IRUSR)); 235 fReadGroupCheckBox->SetValue((int32)(perms & S_IRGRP)); 236 fReadOtherCheckBox->SetValue((int32)(perms & S_IROTH)); 237 fWriteUserCheckBox->SetValue((int32)(perms & S_IWUSR)); 238 fWriteGroupCheckBox->SetValue((int32)(perms & S_IWGRP)); 239 fWriteOtherCheckBox->SetValue((int32)(perms & S_IWOTH)); 240 fExecuteUserCheckBox->SetValue((int32)(perms & S_IXUSR)); 241 fExecuteGroupCheckBox->SetValue((int32)(perms & S_IXGRP)); 242 fExecuteOtherCheckBox->SetValue((int32)(perms & S_IXOTH)); 243 } else 244 hideCheckBoxes = true; 245 246 if (node.GetOwner(&nodeOwner) == B_OK) { 247 BString user; 248 if (nodeOwner == 0) 249 if (getenv("USER") != NULL) 250 user << getenv("USER"); 251 else 252 user << "root"; 253 else 254 user << nodeOwner; 255 fOwnerTextControl->SetText(user.String()); 256 } else 257 fOwnerTextControl->SetText(B_TRANSLATE("Unknown")); 258 259 if (node.GetGroup(&nodeGroup) == B_OK) { 260 BString group; 261 if (nodeGroup == 0) 262 if (getenv("GROUP") != NULL) 263 group << getenv("GROUP"); 264 else 265 group << "0"; 266 else 267 group << nodeGroup; 268 fGroupTextControl->SetText(group.String()); 269 } else 270 fGroupTextControl->SetText(B_TRANSLATE("Unknown")); 271 272 // Unless we're root, only allow the owner to transfer the ownership, 273 // i.e. disable text controls if uid:s doesn't match: 274 thread_id thisThread = find_thread(NULL); 275 thread_info threadInfo; 276 get_thread_info(thisThread, &threadInfo); 277 team_info teamInfo; 278 get_team_info(threadInfo.team, &teamInfo); 279 if (teamInfo.uid != 0 && nodeOwner != teamInfo.uid) { 280 fOwnerTextControl->SetEnabled(false); 281 fGroupTextControl->SetEnabled(false); 282 } else { 283 fOwnerTextControl->SetEnabled(true); 284 fGroupTextControl->SetEnabled(true); 285 } 286 } else 287 hideCheckBoxes = true; 288 } else 289 hideCheckBoxes = true; 290 291 if (hideCheckBoxes) { 292 fReadUserCheckBox->Hide(); 293 fReadGroupCheckBox->Hide(); 294 fReadOtherCheckBox->Hide(); 295 fWriteUserCheckBox->Hide(); 296 fWriteGroupCheckBox->Hide(); 297 fWriteOtherCheckBox->Hide(); 298 fExecuteUserCheckBox->Hide(); 299 fExecuteGroupCheckBox->Hide(); 300 fExecuteOtherCheckBox->Hide(); 301 } 302} 303 304 305void 306FilePermissionsView::MessageReceived(BMessage* message) 307{ 308 switch(message->what) { 309 case kPermissionsChanged: 310 if (fModel != NULL) { 311 mode_t newPermissions = 0; 312 newPermissions 313 = (mode_t)((fReadUserCheckBox->Value() ? S_IRUSR : 0) 314 | (fReadGroupCheckBox->Value() ? S_IRGRP : 0) 315 | (fReadOtherCheckBox->Value() ? S_IROTH : 0) 316 317 | (fWriteUserCheckBox->Value() ? S_IWUSR : 0) 318 | (fWriteGroupCheckBox->Value() ? S_IWGRP : 0) 319 | (fWriteOtherCheckBox->Value() ? S_IWOTH : 0) 320 321 | (fExecuteUserCheckBox->Value() ? S_IXUSR : 0) 322 | (fExecuteGroupCheckBox->Value() ? S_IXGRP :0) 323 | (fExecuteOtherCheckBox->Value() ? S_IXOTH : 0)); 324 325 BNode node(fModel->EntryRef()); 326 327 if (node.InitCheck() == B_OK) 328 node.SetPermissions(newPermissions); 329 else { 330 ModelChanged(fModel); 331 beep(); 332 } 333 } 334 break; 335 336 case kNewOwnerEntered: 337 if (fModel != NULL) { 338 uid_t owner; 339 if (sscanf(fOwnerTextControl->Text(), "%d", &owner) == 1) { 340 BNode node(fModel->EntryRef()); 341 if (node.InitCheck() == B_OK) 342 node.SetOwner(owner); 343 else { 344 ModelChanged(fModel); 345 beep(); 346 } 347 } else { 348 ModelChanged(fModel); 349 beep(); 350 } 351 } 352 break; 353 354 case kNewGroupEntered: 355 if (fModel != NULL) { 356 gid_t group; 357 if (sscanf(fGroupTextControl->Text(), "%d", &group) == 1) { 358 BNode node(fModel->EntryRef()); 359 if (node.InitCheck() == B_OK) 360 node.SetGroup(group); 361 else { 362 ModelChanged(fModel); 363 beep(); 364 } 365 } else { 366 ModelChanged(fModel); 367 beep(); 368 } 369 } 370 break; 371 372 default: 373 _inherited::MessageReceived(message); 374 break; 375 } 376} 377 378 379void 380FilePermissionsView::AttachedToWindow() 381{ 382 fReadUserCheckBox->SetTarget(this); 383 fReadGroupCheckBox->SetTarget(this); 384 fReadOtherCheckBox->SetTarget(this); 385 fWriteUserCheckBox->SetTarget(this); 386 fWriteGroupCheckBox->SetTarget(this); 387 fWriteOtherCheckBox->SetTarget(this); 388 fExecuteUserCheckBox->SetTarget(this); 389 fExecuteGroupCheckBox->SetTarget(this); 390 fExecuteOtherCheckBox->SetTarget(this); 391 392 fOwnerTextControl->SetTarget(this); 393 fGroupTextControl->SetTarget(this); 394} 395