#include #include #include #include #include #include #include #include #include #include #include #define FALSE 0 #define FILE_BUFF 4096 #define TRUE 1 struct NODE { int inode; long size; struct NODE *next; }; int main() { /* * totalsize takes in a list of filenames on its stdin and adds up the * total size of those files (using stat) and prints the results as * either bytes or kilobytes. It checks the UNITS environment variable to * know whether to print in bytes or kilobytes. It checks the TSTALL * environment variable for an integer to use as a delay before checking * for files. It also checks the TMOM environment variable for the * process ID of a parent process to send a SIGUSR1 signal to. * * totalsize builds a linked list out of the entered filenames and then * goes through the unique, regular files and uses stat() to grab * information about those files (inode, size). */ char *envar = NULL; char filename[FILE_BUFF]; int inList = FALSE; int sigPID; int sleepTime; long long byteSum = 0; struct NODE *currentNode = NULL; struct NODE *head = NULL; struct NODE *newNode = NULL; struct stat statData; // Check TSTALL for time delay errno = 0; if ((envar = getenv("TSTALL")) != NULL && (sleepTime = strtol(envar, NULL, 10)) > 0 && errno == 0) { sleep(sleepTime); } // Take in standard input and build linked list. while (scanf(" %s", filename) == 1) { if (stat(filename, &statData) == 0 && S_ISREG(statData.st_mode)) { inList = FALSE; for (currentNode = head; currentNode != NULL; currentNode = currentNode->next) { if (currentNode->inode == statData.st_ino) { inList = TRUE; } } if (!inList) { newNode = (struct NODE *) malloc(sizeof(struct NODE)); newNode->inode = statData.st_ino; newNode->size = statData.st_size; newNode->next = head; head = newNode; } } // Check TSTALL for time delay errno = 0; if ((envar = getenv("TSTALL")) != NULL && (sleepTime = strtol(envar, NULL, 10)) > 0 && errno == 0) { sleep(sleepTime); } } // Add up the number of bytes and print out the results byteSum = 0; for (currentNode = head; currentNode != NULL; currentNode = currentNode->next) { byteSum += currentNode->size; } if ((envar = getenv("UNITS")) != NULL && (envar[0] == 'k' || envar[0] == 'K') && envar[1] == '\0') { byteSum /= 1024; printf("%lldkB\n", byteSum); } else { printf("%lld\n", byteSum); } // Free list while (currentNode != NULL) { currentNode = head; head = head->next; free(currentNode); } errno = 0; // Send SIGNUSR1 signal to calling parent if ((envar = getenv("TMOM")) != NULL && (sigPID = strtol(envar, NULL, 10)) > 0 && errno == 0) { kill(sigPID, SIGUSR1); } exit(0); }