Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Applications/Preferences/Modules/Expert/Expert.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
id privateWindowServerBtn;
id privateSoundServerBtn;

id permissionsView;

OSEDefaults *defaults;
NSImage *image;
}
Expand Down
84 changes: 84 additions & 0 deletions Applications/Preferences/Modules/Expert/Expert.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,27 @@
//

#import <AppKit/AppKit.h>
#import <Foundation/NSDistributedNotificationCenter.h>
#import <SystemKit/OSEFileManager.h>

#import <sys/types.h>
#import <sys/stat.h>

#import "Expert.h"
#import "WMPermissions.h"

// Global defaults key holding the file-creation umask (octal), e.g. 022.
// The value is the POSIX umask -- the complement of the permission bits
// granted to newly created files and folders. Workspace (the session
// leader) applies it with umask() at startup and again, live, whenever
// this module posts FileCreationMaskDidChangeNotification, so the setting
// takes effect immediately without re-logging in.
static NSString * const FileCreationMaskKey = @"NXFileCreationMask";

// Posted (distributed) when the user edits the mask so Workspace re-applies
// it to the running session. Mirrors the Font module's live-apply pattern.
static NSString * const FileCreationMaskDidChangeNotification =
@"NXFileCreationMaskDidChangeNotification";

@implementation Expert

Expand Down Expand Up @@ -62,6 +80,57 @@ - (void)awakeFromNib
selectItemWithTag:[[OSEFileManager defaultManager] sortFilesBy]];
[showHiddenFilesBtn
setState:[[OSEFileManager defaultManager] isShowHiddenFiles]];

// The "File Creation Mask" control is a WMPermissions custom view placed
// in the NIB. It is not wired to a Gorm connection, so locate it in the
// loaded view hierarchy and finish its setup here.
permissionsView = [self permissionsViewInView:view];
if (permissionsView != nil) {
unsigned long grantedMode;
mode_t mask;

// Show all three permission rows (Read/Write/Execute) to match the
// Owner/Group/Others x Read/Write/Execute layout of the panel.
[permissionsView setDisplaysExecute:YES];
[permissionsView setEditable:YES];
[permissionsView setTarget:self];
[permissionsView setAction:@selector(setFileCreationMask:)];

// Seed the matrix from the saved default; fall back to the current
// process umask when the key is absent (objectForKey: nil-check, since
// a "default present" semantics cannot be expressed with boolForKey:).
if ([defaults objectForKey:FileCreationMaskKey] != nil) {
mask = (mode_t)[defaults integerForKey:FileCreationMaskKey];
} else {
mask = umask(0); // read current umask ...
umask(mask); // ... and restore it immediately
}
// WMPermissions displays *granted* permission bits, i.e. the complement
// of the umask, limited to the rwxrwxrwx (0777) range.
grantedMode = (~mask) & 0777;
[permissionsView setMode:grantedMode];
}
}

// Depth-first search for the WMPermissions view loaded from the NIB.
- (id)permissionsViewInView:(NSView *)aView
{
NSArray *subviews = [aView subviews];
NSUInteger i, count = [subviews count];

for (i = 0; i < count; i++) {
NSView *subview = [subviews objectAtIndex:i];
id found;

if ([subview isKindOfClass:[WMPermissions class]]) {
return subview;
}
found = [self permissionsViewInView:subview];
if (found != nil) {
return found;
}
}
return nil;
}

- (NSView *)view
Expand Down Expand Up @@ -102,5 +171,20 @@ - (void)setShowHiddenFiles:(id)sender
[[OSEFileManager defaultManager] setShowHiddenFiles:[sender state]];
}

- (void)setFileCreationMask:(id)sender
{
unsigned long grantedMode = [(WMPermissions *)sender mode] & 0777;
mode_t mask = (mode_t)((~grantedMode) & 0777);

// Persist as the POSIX umask, then notify Workspace so it re-applies the
// mask to the running session immediately (no re-login required).
[defaults setInteger:(NSInteger)mask forKey:FileCreationMaskKey];
[defaults synchronize];

[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:FileCreationMaskDidChangeNotification
object:@"Preferences"];
}

@end

5 changes: 4 additions & 1 deletion Applications/Preferences/Modules/Expert/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ $(BUNDLE_NAME)_HEADERS= \

$(BUNDLE_NAME)_RESOURCE_FILES = \
Resources/Expert.tiff \
Resources/bundle.registry
Resources/bundle.registry \
Resources/PermYes.tiff \
Resources/PermNo.tiff \
Resources/PermNoChange.tiff

$(BUNDLE_NAME)_LANGUAGES = \
English
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
30 changes: 30 additions & 0 deletions Applications/Workspace/Controller.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
#import <errno.h>
#import <string.h>
#import <sys/utsname.h>
#import <sys/stat.h>

#import <GNUstepGUI/GSDisplayServer.h>
#import <X11/Xlib.h>
#import <Foundation/NSDistributedNotificationCenter.h>

#include <core/log_utils.h>
#include <core/string_utils.h>
Expand Down Expand Up @@ -674,6 +676,34 @@ - (void)applicationWillFinishLaunching:(NSNotification *)notif
selector:@selector(applicationDidChangeScreenParameters:)
name:NSApplicationDidChangeScreenParametersNotification
object:NSApp];

// File creation mask (umask): apply the saved value to this session leader
// now, and re-apply it live whenever the Preferences Expert module changes
// it, so the setting takes effect without re-logging in.
[self applyFileCreationMask];
[[NSDistributedNotificationCenter defaultCenter]
addObserver:self
selector:@selector(fileCreationMaskDidChange:)
name:@"NXFileCreationMaskDidChangeNotification"
object:@"Preferences"];
}

// Read the saved file-creation umask from the global defaults and apply it to
// the Workspace process. Folders/files created by the File Viewer and every
// application Workspace launches afterwards inherit this umask. Already
// running applications keep the umask they inherited at their own launch.
- (void)applyFileCreationMask
{
OSEDefaults *defs = [OSEDefaults globalUserDefaults];

if ([defs objectForKey:@"NXFileCreationMask"] != nil) {
umask((mode_t)[defs integerForKey:@"NXFileCreationMask"]);
}
}

- (void)fileCreationMaskDidChange:(NSNotification *)aNotif
{
[self applyFileCreationMask];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notif
Expand Down
Loading