summaryrefslogtreecommitdiff
path: root/pgm3/totalsize.c
diff options
context:
space:
mode:
Diffstat (limited to 'pgm3/totalsize.c')
-rw-r--r--pgm3/totalsize.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/pgm3/totalsize.c b/pgm3/totalsize.c
new file mode 100644
index 0000000..c15a72d
--- /dev/null
+++ b/pgm3/totalsize.c
@@ -0,0 +1,126 @@
+#include <errno.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <time.h>
+#include <unistd.h>
+
+#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);
+}