5 // Created by David Botsch on
10/23/07.
6 // Further developed by Toby Blake
, April
-May
2008
9 #import "afscellPane.h"
11 @implementation afscellPane
13 #pragma mark string constants
14 NSString
*fileReadThisCell
=@"
/private
/var
/db
/openafs
/etc
/ThisCell"
;
15 NSString
*fileReadCellAlias
=@"
/private
/var
/db
/openafs
/etc
/CellAlias"
;
16 NSString
*fileWriteThisCell
=@"
/private
/tmp
/org.OpenAFS.Install.ThisCell"
;
17 NSString
*fileWriteCellAlias
=@"
/private
/tmp
/org.OpenAFS.Install.CellAlias"
;
19 #pragma mark private methods
20 /* check line of CellAlias provided for Cell name, if matches, returns alias in third parameter */
21 - (BOOL
)_cellInCellAliasLine
:(NSString
*)line cellName
:(NSString
*)cell intoAlias
:(NSString
**)alias
23 NSMutableCharacterSet
*alphaNum
= [[NSCharacterSet alphanumericCharacterSet
] mutableCopy
];
24 [alphaNum addCharactersInString
:@"
-"
];
26 NSScanner
*cellScanner
= [NSScanner scannerWithString
:line];
27 if (![cellScanner scanUpToString
:cell intoString
:nil
])
29 [cellScanner scanString
:cell intoString
:nil
];
30 /* need to make sure cell name is followed by whitespace */
31 if (![cellScanner scanUpToCharactersFromSet
:alphaNum intoString
:nil
])
34 /* get rest of string */
35 [cellScanner scanUpToCharactersFromSet
:[NSCharacterSet whitespaceAndNewlineCharacterSet
] intoString
:alias
];
42 /* writes supplied line (plus newline) to string */
43 - (void
)_appendCellAliasLine
:(NSString
*)line toString
:(NSMutableString
*)outString
45 [outString appendString
:line];
46 [outString appendFormat
:@"
\n"
];
49 /* writes supplied cell and alias, separated by space (plus newline at end) to string */
50 - (void
)_appendNewCellAliasLine
:(NSString
*)cell aliasName
:(NSString
*)alias toString
:(NSMutableString
*)outString
52 [outString appendString
:cell];
53 [outString appendFormat
:@" "
];
54 [outString appendString
:alias
];
55 [outString appendFormat
:@"
\n"
];
58 /* displays (slightly) customisable alert */
59 /* we don't use this method any more, but I'll leave it in just in case */
60 - (BOOL
) _continueAlert
:(NSString
*)message cancel
:(BOOL
)cancelButton
62 BOOL returnValue
= NO
;
63 NSAlert
*alert
= [[NSAlert alloc
] init
];
64 [alert addButtonWithTitle
:@"OK"
];
65 (cancelButton
) && [alert addButtonWithTitle
:@"Cancel"
];
66 [alert setMessageText
:message
];
67 [alert setAlertStyle
:NSWarningAlertStyle
];
69 if ([alert runModal
] == NSAlertFirstButtonReturn
)
77 /* displays (slightly) customisable alert as a more attractive panel than _continueAlert above*/
78 - (BOOL
) _continueAlertPanel
:(NSString
*)message titleText
:(NSString
*)title firstButtonText
:(NSString
*)button1 secondButtonText
:(NSString
*)button2
80 if (NSRunInformationalAlertPanel
(title, message
, button1
, button2
, nil
)
81 == NSAlertDefaultReturn
)
88 - (BOOL
) _validateStringWord
:(NSString
*)aString
90 /* basic string validation to check it's got something in it, doesn't have whitespace or newline */
91 if (aString
== nil ||
[aString
length] == 0)
96 if (([aString rangeOfString
:@"
\n"
].location
!= NSNotFound
) ||
97 ([aString rangeOfString
:@"
\t"
].location
!= NSNotFound
) ||
98 ([aString rangeOfString
:@" "
].location
!= NSNotFound
))
105 - (BOOL
) _validateCellString
:(NSString
*)cellString
107 if (![self _validateStringWord
:cellString
])
112 /* make sure it's in internet domain style, i.e. alphanum.alphanum */
113 NSMutableCharacterSet
*alphaNum
= [[NSCharacterSet alphanumericCharacterSet
] mutableCopy
];
114 [alphaNum addCharactersInString
:@"
-"
];
115 NSScanner
*cellScanner
= [NSScanner scannerWithString
:cellString
];
118 if (![cellScanner scanCharactersFromSet
:alphaNum intoString
:nil
])
123 /* anything that follows must be iteration of '.word' */
124 while (![cellScanner isAtEnd
])
126 if (![cellScanner scanString
:@"." intoString
:nil
])
130 if (![cellScanner scanCharactersFromSet
:alphaNum intoString
:nil
])
139 - (BOOL
) _validateAliasString
:(NSString
*)aliasString
141 if (![self _validateStringWord
:aliasString
])
146 /* make sure it's alpha-numeric */
147 NSMutableCharacterSet
*alphaNum
= [[NSCharacterSet alphanumericCharacterSet
] mutableCopy
];
148 [alphaNum addCharactersInString
:@"
-"
];
149 NSScanner
*aliasScanner
= [NSScanner scannerWithString
:aliasString
];
151 if (![aliasScanner scanCharactersFromSet
:alphaNum intoString
:nil
])
155 /* if there's nothing but alpha-numeric, we should be at end */
156 if (![aliasScanner isAtEnd
])
164 #pragma mark InstallerPane overrides
167 return [[NSBundle bundleForClass
:[self
class]] localizedStringForKey
:@"PaneTitle" value
:nil table
:nil
];
171 /* called when user enters pane */
172 - (void
)didEnterPane
:(InstallerSectionDirection
)dir
174 /* get any existing values from ThisCell and CellAlias files */
175 NSString
*readStrCellFile
= [NSString stringWithContentsOfFile
:fileReadThisCell encoding
:NSASCIIStringEncoding
error:nil
];
176 NSString
*readStrAliasFile
= [NSString stringWithContentsOfFile
:fileReadCellAlias encoding
:NSASCIIStringEncoding
error:nil
];
178 /* drop out now if no ThisCell */
179 if (readStrCellFile
== nil
)
184 NSString
*cellString
= @""
;
185 NSString
*aliasString
= @""
;
187 /* we only want the first line from ThisCell */
188 NSScanner
*cellFileScanner
= [NSScanner scannerWithString
:readStrCellFile
];
190 /* get value, removing any trailing whitespace */
191 [cellFileScanner scanUpToCharactersFromSet
:[NSCharacterSet whitespaceAndNewlineCharacterSet
] intoString
:&cellString
];
193 /* set Cell value in pane */
194 [ThisCell setStringValue
:cellString
];
196 /* drop out now if no CellAlias file */
197 if (readStrAliasFile
== nil
)
202 /* now find our local cell in the alias file */
203 NSScanner
*lineScanner
= [NSScanner scannerWithString
:readStrAliasFile
];
206 /* get a line at a time, and check for Cell name */
207 while([lineScanner scanUpToString
:@"
\n" intoString
:&line])
209 [self _cellInCellAliasLine
:line cellName
:cellString intoAlias
:&aliasString
];
210 [lineScanner scanString
:@"
\n" intoString
:nil
];
213 /* set Alias value in pane */
214 [CellAlias setStringValue
:aliasString
];
219 /* called when user clicks "Continue" -- return value indicates if application should exit pane */
220 - (BOOL
)shouldExitPane
:(InstallerSectionDirection
)dir
222 if(InstallerDirectionForward
== dir)
224 NSString
* userName
= NSUserName
();
226 /* Update ThisCell and CellAlias files with input */
227 NSString
* newStrCell
= [ThisCell stringValue
];
228 NSString
* newStrAlias
= [CellAlias stringValue
];
230 if ([newStrCell
length] == 0)
232 return [self _continueAlertPanel
:@"No local
cell value specified. Proceed with empty value?" titleText
:@"No Local
Cell" firstButtonText
:@"Continue" secondButtonText
:@"Cancel"
];
235 /* do some validation on cell string */
236 if (![self _validateCellString
:newStrCell
])
238 [self _continueAlertPanel
:@"Invalid local
cell name
: value should be a complete Internet domain
-style name
(for example
, \"example.com
\")" titleText
:@"Invalid
Cell Name" firstButtonText
:@"OK" secondButtonText
:nil
];
242 /* write value to ThisCell file */
244 /* add username to file name */
245 NSMutableString
* fileWriteThisCellUname
= [NSMutableString stringWithCapacity
:0];
246 [fileWriteThisCellUname appendString
:fileWriteThisCell
];
247 [fileWriteThisCellUname appendFormat
:@"."
];
248 [fileWriteThisCellUname appendString
:userName
];
250 NSMutableString
* errorString
= [NSMutableString stringWithCapacity
:0];
252 NSMutableString
* cellString
= [NSMutableString stringWithCapacity
:0];
253 [cellString appendString
:newStrCell
];
254 [cellString appendFormat
:@"
\n"
];
255 if (![cellString writeToFile
:fileWriteThisCellUname atomically
:YES encoding
:NSASCIIStringEncoding
error:nil
])
257 [errorString setString
:@"Could not write file
: "
];
258 [errorString appendString
:fileWriteThisCellUname
];
259 [errorString appendFormat
:@" Continue?"
];
260 if (![self _continueAlertPanel
:errorString titleText
:@"File
Error" firstButtonText
:@"Continue" secondButtonText
:@"Cancel"
])
266 if ([newStrAlias
length] != 0)
268 /* do some validation on alias string */
269 if (![self _validateAliasString
:newStrAlias
])
271 [self _continueAlertPanel
:@"Invalid alias
: value should be alpha
-numeric string" titleText
:@"Invalid Alias" firstButtonText
:@"OK" secondButtonText
:nil
];
275 BOOL processedAlias
= NO
;
277 /* read in alias file */
278 NSString
*readStrAliasFile
= [NSString stringWithContentsOfFile
:fileReadCellAlias encoding
:NSASCIIStringEncoding
error:nil
];
280 /* string to build up for writing out to file */
281 NSMutableString
* aliasString
= [NSMutableString stringWithCapacity
:0];
283 if (readStrAliasFile
!= nil
)
285 /* read in a line at a time */
286 NSScanner
*lineScanner
= [NSScanner scannerWithString
:readStrAliasFile
];
288 NSString
*alias
= @""
;
290 while([lineScanner scanUpToString
:@"
\n" intoString
:&line])
292 /* check to see if we already have an alias for local cell */
293 if ([self _cellInCellAliasLine
:line cellName
:newStrCell intoAlias
:&alias
])
295 /* we have a match */
296 if ([alias isEqualToString
:newStrAlias
])
298 /* write line as-is */
299 [self _appendCellAliasLine
:line toString
:aliasString
];
303 /* write new cell-alias entry in place */
304 [self _appendNewCellAliasLine
:newStrCell aliasName
:newStrAlias toString
:aliasString
];
306 processedAlias
= YES
;
310 /* write line as-is */
311 [self _appendCellAliasLine
:line toString
:aliasString
];
313 [lineScanner scanString
:@"
\n" intoString
:nil
];
318 /* if we haven't written our line yet, append to end */
319 [self _appendNewCellAliasLine
:newStrCell aliasName
:newStrAlias toString
:aliasString
];
322 /* add username to file name */
323 NSMutableString
* fileWriteCellAliasUname
= [NSMutableString stringWithCapacity
:0];
324 [fileWriteCellAliasUname appendString
:fileWriteCellAlias
];
325 [fileWriteCellAliasUname appendFormat
:@"."
];
326 [fileWriteCellAliasUname appendString
:userName
];
328 if (![aliasString writeToFile
:fileWriteCellAliasUname atomically
:YES encoding
:NSASCIIStringEncoding
error:nil
])
330 [errorString setString
:@"Could not write file
: "
];
331 [errorString appendString
:fileWriteCellAliasUname
];
332 [errorString appendFormat
:@" Continue?"
];
333 if (![self _continueAlertPanel
:errorString titleText
:@"File
Error" firstButtonText
:@"Continue" secondButtonText
:@"Cancel"
])