logoISU  

CS456 - Systems Programming

Spring 2023

Displaying ./code/h3/lsfunctions.c

#include "myls.h"

/*
	this function will process the command line arguments
	
	this does the following 
		- which arg is the options (if any)
		- which arg is the filename
			-or if a filename is not specified, use current directory
		
	then we will store these values in opt and fi using strcpy.

*/
void processArgs(int argc, char **argv, char *opt, char *fi){

	if(argc >= 2){ //options and-or filename were specified
		//were options specified?
		if(argv[1][0] == '-'){ //yes, an option was specified
			strcpy(opt, argv[1]);

			//was a filename specified too?
			if(argc < 3)
				strcpy(fi, ".");
			else
				strcpy(fi, argv[2]);
		} else { //no, there weren't any options specified
			strcpy(fi, argv[1]);
		}

	} else { // only "myls" was typed in
		strcpy(fi, ".");
	}

}

/*

	the function "flags" processes the options string

	this uses bit operations to set a specified bit in a 32 bit integer
	to 1. each bit corresponds to a possible option. if the program sees
	that a particular bit is set, then it will do that option

*/

int flags(char *options){

	if(options == NULL)  //no options were entered
		return 0;

	int rt = 0;			//variable for the return value

	char *h, *l, *a, *c;    //char pointers to check for options

	//calling strchr 3 times to check options string to see if a certain option is present
	h = strchr(options, 'h');
	l = strchr(options, 'l');
	a = strchr(options, 'a');
	c = strchr(options, 'c');

	//What would strchr return if it did NOT find the character?

	//if an h appears anywhere, run printHelp function
		// then return -1
	if(h != NULL){
		printHelp();
		return -1;  
	}

	//doing if statements to check for l and a
		// if a certain option exists, specified bit will be set to 1

	if(l != NULL)   //user specified a -l
		rt = setBit(rt, L); // setting 0th (L) bit to 1 
	
	if(a != NULL) //user specified an -a
		rt = setBit(rt, A); // setting 1st bit (A) to 1

	if(c != NULL)
		rt= setBit(rt, C); // setting 2nd bit to 1

	//note that L and A are defined in myls.h

	//after everything is checked, return whatever rt is
	return rt;
}

//checks the filename to see if it's a hidden file
int isHiddenFile(char *filename){

	//a hidden file will always have a '.' as the first character

	//check first character in filename for a period
		// return 1 if yes
		// return 0 if no
	if(filename[0] == '.')
		return 1;
	else
		return 0;

}

//checking if the hidden files option is enabled
int isHiddenOption(int opt){

	if(checkBit(opt, A))
		return 1;
	else
		return 0;

}


int isCount(int opt){

	if(checkBit(opt, C))
		return 1;
	else
		return 0;

}



// takes an integer and a bit position as arguments
// if bit at specified position is 0, change it to 1
// otherwise leave it unchanged
int setBit(int n, int bit){

	return (n | (1 << bit));

}


//returns the binary bit of a number at a given position
int checkBit(int n, int bit){

	if(n & (1 << bit)) 
		return 1;
	else
		return 0;
}

// prints a help message
void printHelp(void){
	fprintf(stderr, "Usage: myls [-OPTIONS] FILENAME\n");
	fprintf(stderr, "\t h : help\n");
	fprintf(stderr, "\t a : print hidden files\n");
	fprintf(stderr, "\t l : print long format\n");
	fprintf(stderr, "\t c : print number of files\n");
}

// tests to see if the bit we set aside for enabling the 
// long format is enabled (did user enter -l?)
int isLongFormat(int opt){

	if(checkBit(opt, L))
		return 1;
	else
		return 0;

}

//prints out the stuff for the long format
void printLongFormat(STAT s){

	PASSWD   *pw;  // the password struct
	GROUP    *gp;  // the group struct

	pw = getpwuid(s.st_uid);
	gp = getgrgid(s.st_gid); 
	

	//print the following things in this function
		printPermissions(s);//permissions (call the function provided)
		printf("%ld ", s.st_nlink);//links
		printf("%s ", pw->pw_name);//user id
		printf("%s ", gp->gr_name);//group_id
		printf("%ld ", s.st_size);//filesize
		printTime(s);//mtime
		printf(" ");

}

//prints the file permissions like ls -l does
void printPermissions(STAT s){

	printf( (S_ISDIR(s.st_mode))  ? "d" : "-");
    printf( (s.st_mode & S_IRUSR) ? "r" : "-");
    printf( (s.st_mode & S_IWUSR) ? "w" : "-");
    printf( (s.st_mode & S_IXUSR) ? "x" : "-");
    printf( (s.st_mode & S_IRGRP) ? "r" : "-");
    printf( (s.st_mode & S_IWGRP) ? "w" : "-");
    printf( (s.st_mode & S_IXGRP) ? "x" : "-");
    printf( (s.st_mode & S_IROTH) ? "r" : "-");
    printf( (s.st_mode & S_IWOTH) ? "w" : "-");
    printf( (s.st_mode & S_IXOTH) ? "x" : "-");
	printf(" ");

}

//prints the time
void printTime(STAT s){

	char *c;

	c = ctime(&s.st_mtime);

	for(int i = 4; i <=15; i++)
		printf("%c", c[i]);


}