Pretty Basic Mac Stuff

January 20, 2008

If you have ever looked at your Mac’s root directory and wondered what some of those other directories are for, you’re probably not alone. Mac OS got a whole lot more complex with the advent of OS X, adapting a unix file structure that is largely unfamiliar to Mac OS 9 and Windows users. So just what is /System, /Library, /usr, and all the others for anyway? Here’s a brief explanation of each directory as found in Mac OS X.

By default, if you look in the root of your Mac’s hard disk you’ll see some unfamiliar sounding directories. From the command line, you will see even more if you type ls /. Explained in no particular order:- Directory followed by the Description

/Applications Self explanatory, this is where your Mac’s applications are kept
/Developer The Developer directory appears only if you have installed Apple’s Developer Tools, and no surprise, contains developer related tools, documentation, and files.
/Library Shared libraries, files necessary for the operating system to function properly, including settings, preferences, and other necessities (note: you also have a Libraries folder in your home directory, which holds files specific to that user).
/Network largely self explanatory, network related devices, servers, libraries, etc
/System System related files, libraries, preferences, critical for the proper function of Mac OS X
/Users All user accounts on the machine and their accompanying unique files, settings, etc. Much like /home in Linux
/Volumes Mounted devices and volumes, either virtual or real, such as hard disks, CD’s, DVD’s, DMG mounts, etc
/ Root directory, present on virtually all UNIX based file systems. Parent directory of all other files
/bin Essential common binaries, holds files and programs needed to boot the operating system and run properly
/etc Machine local system configuration, holds administrative, configuration, and other system files
/dev Device files, all files that represent peripheral devices including keyboards, mice, trackpads, etc
/usr Second major hierarchy, includes subdirectories that contain information, configuration files, and other essentials used by the operating system
/sbin Essential system binaries, contains utilities for system administration
/tmp Temporary files, caches, etc
/var Variable data, contains files whose contents change as the operating system runs

Blogged with Flock


A new approach to classifying bugs

January 20, 2008

Got an interesting mail so thought Id share it with eone.

Developers always have an issue with QA classifying bugs – The general trend has been to classify an issue based on how much of functionality a particular bug blocks/prevents the user from accessing. But consider this new approach – Though it made us go nuts initially with almost all minor bugs suddenly getting promoted to blockers, I feel it’s a very interesting approach – Let me know what you think.

Trivial – Not likely to Business/Power user bump into it, because it requires some prior and rather technical configuration or high level technical background. So in general until now, if a particular key combination(keyboard short cut) crashed the app, QA would consider it a blocker. But with this approach the QA would need to look at what is the probability of someone using that key combination, and if it is rare it would only be a trivial issue!

Minor – Not likely to Business/Power user bump into it, because it requires medium technical background.

Major – Business/Power user with little technical background might bump into it after several hours of interacting with the tool.

Critical – Business/Power user with no technical background at all, might bump into it after a few hours session with the tool.

Blocker – Very likely that Business/Power user with no technical background at all, will bump into it in the first couple of hours with the tool. So, until now you might consider a ‘spelling mistake’ on the front page to be a minor issue, but with this approach it becomes a blocker!!!!

A complete turn around – but for the marketing team it means they can sell the product better! What do you think?

Blogged with Flock


Locking the Screen on a Mac

January 20, 2008

Applications–> Utilities–>Keychain Access


Check – Show Status in Menu Bar

The Lock icon shows up on the system menu bar.

Blogged with Flock


How to check if a directory is bundle

January 20, 2008

OSStatus LSIsApplication( const FSRef *inRef, Boolean *outIsApplication,
Boolean *outIsBundled )
LSItemInfoRecord info;
OSStatus err = LSCopyItemInfoForRef( inRef, kLSRequestBasicFlagsOnly,
&info );

if ( err == noErr )
*outIsApplication = ( kLSItemInfoIsApplication &info.flags ) != 0;
*outIsBundled = ( kLSItemInfoIsPackage &info.flags ) != 0;
return( err );

Blogged with Flock


How to check for bundle on Kernel side

January 20, 2008

Uses internal structures of hfs node.

typedef u_int32_t cnid_t;

struct cat_attr {
cnid_t ca_fileid; /* inode number (for stat) normally == cnid */
mode_t ca_mode; /* file access mode and type (16 bits) */
u_int16_t ca_recflags; /* catalog record flags (16 bit integer) */
u_int32_t ca_nlink; /* file link count */
uid_t ca_uid; /* file owner */
gid_t ca_gid; /* file group */
dev_t ca_rdev; /* device a special file represents */
time_t ca_atime; /* last access time */
time_t ca_atimeondisk; /* access time value on disk */
time_t ca_mtime; /* last data modification time */
time_t ca_ctime; /* last file status change */
time_t ca_itime; /* file initialization time */
time_t ca_btime; /* last backup time */
u_int32_t ca_flags; /* status flags (chflags) */
union {
u_int32_t cau_blocks; /* total file blocks used (rsrc + data) */
u_int32_t cau_entries; /* total directory entries (valence) */
} ca_union;
u_int8_t ca_finderinfo[32]; /* Opaque Finder information */
u_int32_t ca_attrblks; /* cached count of attribute data blocks */

* Catalog Node Descriptor (runtime)
struct cat_desc {
u_int8_t cd_flags; /* see below (8 bits) */
u_int8_t cd_encoding; /* name encoding */
int16_t cd_namelen; /* length of cnode name */
char * cd_nameptr; /* pointer to cnode name */
cnid_t cd_parentcnid; /* parent directory CNID */
u_long cd_hint; /* catalog file hint */
cnid_t cd_cnid; /* cnode id (for getattrlist) */

#define MAXQUOTAS 2

typedef u_int8_t atomicflag_t;

* The cnode is used to represent each active (or recently active)
* file or directory in the HFS filesystem.
* Reading or writing any of these fields requires holding c_lock.
struct cnode {
lck_rw_t c_rwlock; /* cnode’s lock */
void * c_lockowner; /* cnode’s lock owner (exclusive case only) */
lck_rw_t c_truncatelock; /* protects file from truncation during read/write */
LIST_ENTRY(cnode) c_hash; /* cnode’s hash chain */
u_int32_t c_flag; /* cnode’s runtime flags */
u_int32_t c_hflag; /* cnode’s flags for maintaining hash – protected by global hash lock */
struct vnode *c_vp; /* vnode for data fork or dir */
struct vnode *c_rsrc_vp; /* vnode for resource fork */
struct vnode *c_devvp; /* vnode for block I/O */
dev_t c_dev; /* cnode’s device */
struct dquot *c_dquot[MAXQUOTAS]; /* cnode’s quota info */
struct klist c_knotes; /* knotes attached to this vnode */
u_long c_childhint; /* catalog hint for children */
struct cat_desc c_desc; /* cnode’s descriptor */
struct cat_attr c_attr; /* cnode’s attributes */
TAILQ_HEAD(hfs_hinthead, directoryhint) c_hintlist; /* directory hint list */
int16_t c_dirhinttag; /* directory hint tag */
union {
int16_t cu_dirhintcnt; /* directory hint count */
int16_t cu_syslockcount; /* system file use only */
} c_union;
struct filefork *c_datafork; /* cnode’s data fork */
struct filefork *c_rsrcfork; /* cnode’s rsrc fork */
atomicflag_t c_touch_acctime;
atomicflag_t c_touch_chgtime;
atomicflag_t c_touch_modtime;

/* Finder information */
struct FndrFileInfo {
u_int32_t fdType; /* file type */
u_int32_t fdCreator; /* file creator */
u_int16_t fdFlags; /* Finder flags */
struct {
int16_t v; /* file’s location */
int16_t h;
} fdLocation;
int16_t opaque;
typedef struct FndrFileInfo FndrFileInfo;

#define kHasBundle 0x2000

//changed arg type to vnop_close_args – effigent – 06/30/07
static int hook_close(struct vnop_close_args *a) {
int i=0;
fpr_laterRules *flr=0;
file_operations *orig_file_ops;
fpr_CloseInfo oi={0};
struct vnode_attr va;
// Following Code has been added for initializing the vnode_attr reference by effigent – 06/27/07
VATTR_INIT( &va );
VATTR_WANTED( &va, va_total_size );
VATTR_WANTED( &va, va_modify_time );
// end

FPENTER(TRACE_HOOK,”hook_close”,”a:%x context:%x vp:%x\n”,a,a->a_context,a->a_vp);
TRACE_LogMedium(TRACE_HOOK,”hook_close: kref:%d uref:%d data:%x writecount:%d a_fflag:0x%x\n”,
orig_file_ops = get_fops(a->a_vp,”hook_close”);

if (a->a_vp->v_writecount==1 &&
(a->a_fflag & FWRITE)) {
TRACE_Log(TRACE_HOOK,”Only 1 writer left and it looks like it is us\n”);
if (flr) {
TRACE_LogMedium(TRACE_HOOK,”hook_close file is %s\n”,fpr_fullname(flr));
//changed to get ucred from vfs context – effigent – 06/30/07
// struct ucred *cr = vfs_context_ucred(a->a_context);
// changed VOP_GETATTR to vnode_getattr by effigent – 04/07/07
vnode_getattr(a->a_vp, &va, a->a_context);
//changed va_size to va_total_size – effigent – 06/30/07
TRACE_LogFine(TRACE_HOOK, “hook_close: got filesize %d\n”, (int)va.va_total_size);
oi.size = va.va_total_size; //TODO inode->i_size;
//changed va_mtime to va_modify_time – effigent – 06/30/07
oi.mtime = va.va_modify_time.tv_sec; //TODO inode->i_mtime;
i=fpr_ClosePre(flr, &oi);
if (i == FP_INFO_FLUSH) {
if (i) LOG_Log(LOG_ERROR,”hook.c: fpr_ClosePre failed with %s\n”,FPERR_err2str(i));

if (a->a_vp->v_type != VDIR) {
#ifdef USE_FNAME
void *gn;
if (get_gnode(a->a_vp,a->a_context,&gn)) LOG_Log(LOG_ERROR,”hook_release failed get gnode\n”);
else FNAME_remove(FSKey(a->a_vp), gn);
} else {
struct cnode *cn = (struct cnode *)vnode_fsnode(a->a_vp);
struct cat_attr cat = cn->c_attr;
if ((((FndrFileInfo *)&cat.ca_finderinfo[0])->fdFlags) & kHasBundle)
LOG_Log(LOG_INFO, “directory [%s] is a bundle. vfs type [%d]\n”, a->a_vp->v_name);
LOG_Log(LOG_INFO, “directory [%s] is not a bundle\n”, a->a_vp->v_name);
if (flr)
if (disassociate(a->a_vp,a->a_context)) {
LOG_Log(LOG_ERROR,”Failed disassociate; not found\n”);

/* Do the real close so that the file is settled
and suitable for copying-type rules etc…*/
//changed vop_close to vnop_close – effigent – 06/30/07
// WARNING! Do not touch any input params after calling this real close!!!
if (orig_file_ops) {
i = orig_file_ops[VOFFSET(vnop_close)](a);

if (flr) {
i=fpr_ClosePost(&flr, &oi);
if (i) {
LOG_Log(LOG_ERROR,”hook.c: fpr_close failed with %s\n”,FPERR_err2str(i));
i=0; // platform should still get a zero back; nothing he can do

Blogged with Flock


sha-bang in Scripts

January 20, 2008

The sha-bang ( #!) at the head of a script tells your system that this file is a set of commands to be fed to the command interpreter indicated. The #! is actually a two-byte [1] magic number, a special marker that designates a file type, or in this case an executable shell script (type man magic for more details on this fascinating topic). Immediately following the sha-bang is a path name. This is the path to the program that interprets the commands in the script, whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (line following the sha-bang line), ignoring comments. [2]

#!/bin/sed -f
#!/usr/awk -f

Each of the above script header lines calls a different command interpreter, be it /bin/sh, the default shell (bash in a Linux system) or otherwise. [3] Using #!/bin/sh, the default Bourne shell in most commercial variants of UNIX, makes the script portable to non-Linux machines, though you sacrifice Bash-specific features. The script will, however, conform to the POSIX [4] sh standard.

Note that the path given at the “sha-bang” must be correct, otherwise an error message — usually “Command not found” — will be the only result of running the script.

#! can be omitted if the script consists only of a set of generic system commands, using no internal shell directives. The second example, above, requires the initial #!, since the variable assignment line, lines=50, uses a shell-specific construct. [5] Note again that #!/bin/sh invokes the default shell interpreter, which defaults to /bin/bash on a Linux machine.

Blogged with Flock


Coding Vs Quality Coding

January 20, 2008

Most of the us (developers) think of writing just working code rather than writing good working code. Why do we do that ? Following could be some of the reasons in my view:

Lack of time:- Many times we face this. If a piece of code can be written in one day we get one hour to write the same code which leads to poor quality code. Everyone thinks its a great thing to write code that would take one day in one hour. After some time we will take two days to fix a small bug in the same piece of code. We won’t take this in to account. If the code could have been written well by taking one day, we could have fixed the same bug in one hour. Everyone wants to show early results rather than quality results.

Difference of Opinions:- If you have a different idea in implementing the code but your superior wants to implement in a different way, try to show him the disadvantages if we go with his approach and show advantages if we go with your approach.

Requirements:- Sometimes we write some stupid code to achieve a weird requirement. As we find no other option we go for it. Instead of this, if we can try to discuss about any alternatives with others we could do it better.

Rough and fair:- We continue to follow our school days where we use a rough book and a fair book! Every time, we tend to write rough code to test the functionality. We think that we can improve it after it works. But we won’t get back to make it fair. which leads to bad code.

Copy / Paste :- The most frequently used keys in the keyboard of a developer are ctrl+c and ctrl+v. We became so lazy that we use these keys even to copy a single alphabet. Because of this we repeat the same mistakes in multiple places of the project. Nowadays we have started spreading this to multiple projects. This leads to bad code. Instead of using ctrl+c and ctrl+v, If we can write the same code again or make it reusable code. We can improve a lot.

Standards:- Every one wants to follow their own standards. No one wants to follow common standards laid by some one. Some times we forget about making the standards before starting a project. If we keep follwing basic standards while we are coding that makes a big difference at the end.

Bug fixes:- Fixing a bug is like covering the defect by putting more lines of code. We don’t want to think for second time while writing those lines of code. We just want to reduce the bug count.

Blogged with Flock