Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

CS 214: Systems Programming, Spring 2017 Assignment 3: Wherefore Art Thou, File?

ID: 3828510 • Letter: C

Question

CS 214: Systems Programming, Spring 2017 Assignment 3: Wherefore Art Thou, File? In this project you will write a remote file server that is mostly transparent to the user. You must first complete the base program'segment below, but you are then free to choose which other extensions you implement, one proviso; you can not implement extension Dunless you also with implement extension C.If you complete all parts, you will receive 160% credit. Base Program: (+80% You will be providing an interface much like the standard file system calls to allow easy use of files across the network. You should write netopen'. metread. netwrite and All of these calls should use the same symtax and have the same overall functionality as their local counterparts (except where expressly exempted. but they will ship their parameters your file server where the actual file operations will happen. To your client code, it will look like open and netopen, read and netread, write and netwrite and close and netclose work almost identically, except your net commands are working on files on another machine. netopen(const char pathname, int flags) The argument flags must include one of the following access modes: O RDONLY. O WRONLY. or O RDWR These request opening the file read-only, write-only, or read write, respectively. RETURN VALUE netopen0 retums the new file descriptor, or-1in the callers contenxt if error occurred (in an which case, crmo is set appropriately) In order to avoid error and disambiguate your file descriptors from the system's make your file descriptors negative (but not-19. ERRORS (check open manpage for definition) reqiured: EINTR. EISDIR. ENOENT EROFS optional (you may wantinced) ENFILE EWOULDBLOCK. EPERM

Explanation / Answer

main.c

#include "libnetfiles.h"


int main()
{
   socklen_t client;
   int socketFD;
   int newSocketFD;
   int n;
   char buffer[256];
   int portNum = 42942;

   struct sockaddr_in serverAddressInfo;
   struct sockaddr_in clientAddressInfo;

   socketFD = socket(AF_INET, SOCK_STREAM, 0);
   if (setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0)
   {
        printf("setsockopt(SO_REUSEADDR) failed");
   }

   if(socketFD < 0)
   {
       printf("Can't open FD ");
       return -1;
   }

   // clean out buffer
   bzero((char *) &serverAddressInfo, sizeof(serverAddressInfo));

   //what the hell is htons? is it changing the int to a network int?
   serverAddressInfo.sin_port = htons(portNum);

   // not sure what this does.
   serverAddressInfo.sin_family = AF_INET;

   // not sure what this does.
   serverAddressInfo.sin_addr.s_addr = INADDR_ANY;

   if(bind(socketFD, (struct sockaddr *) &serverAddressInfo, sizeof(serverAddressInfo)) < 0)
   {
       printf("can't bind socket ");
       return -1;
   }


   while(1)
   {
       listen(socketFD, 5);

       client = sizeof(clientAddressInfo);
       newSocketFD = accept(socketFD, (struct sockaddr *) &clientAddressInfo, &client);

       if(newSocketFD < 0)
       {
           printf("coudln't accept connection ");
       }

       bzero(buffer, 256);
       n = read(newSocketFD, buffer, 255);

       if(n < 0)
       {
           printf("couldn't read from socket ");
           return -1;
       }
///////////////////////////////////////////////////////////////
       // printf("%d ", strlen(buffer));
       if(strlen(buffer) > 4 && strncmp("open", buffer, 4) == 0)
       {
           int FD = nopen(buffer);
           int fdLen = intLen(FD);
           char * writeString = (char*)malloc(fdLen+1);
           sprintf(writeString,"%d",FD);
           n = write(newSocketFD, writeString, strlen(writeString));
       }

///////////////////////////////////////////////////////////////

       else
       {
           printf("Message: %s ", buffer);

           n = write(newSocketFD, "Message recieved", 18);

           if(n < 0)
           {
               printf("couldn't write out to new socket ");
               return -1;
           }
       }
   }


   return 0;
}

int nopen(char * buffer)
{
   nLink * head = NULL;
   head = argPull(buffer, head);
   printf("%s ", head->arg);
   head = head->next;
   printf("%s ", head->arg);
   int returnFD = open(head->arg, O_RDONLY);
   printf("%d ", errno);
   return returnFD;
}

nLink * createLink(char * arg)
{
   nLink * temp = (nLink*)malloc(sizeof(nLink));
   temp->arg = strdup(arg);
   temp->next = NULL;
   return temp;
}

nLink * addToLL(nLink * head, nLink * newnLink)
{
   // Hit the end of the list, simply add the node
   /////////////////
   if(head == NULL)
   {
       head = newnLink;
       return head;
   }

   else
   {
       head->next = addToLL(head->next, newnLink);
       return head;
   }
}

nLink * argPull(char * buffer, nLink * head)
{
   char * tempString;
   nLink * tempnLink;
   int startingPos = -1, endingPos = 0, sizeOfString = 0, len = 0, i = 0;
   len = strlen(buffer);

   for(i = 0; i <= len; i++)
   {
       // Check if current character isalpha and then
       // makes some decisions based on that.
       ///////////////////
       if(buffer[i] == ',' || buffer[i] == '')
       {
           // Nothing to do if current string is empty
           ///////////////////
           if(sizeOfString == 0)
           {
               continue;
           }
           // Grabs the current string from input and puts it into the tree.
           ///////////////////
           else
           {
               endingPos = i;
               tempString = pullString(startingPos, endingPos, sizeOfString, buffer);
               tempnLink = createLink(tempString);
               head = addToLL(head, tempnLink);
               free(tempString);
               startingPos = -1;
               sizeOfString = 0;  

               // endingPos = i;

               // tempString = pullString(startingPos, endingPos, sizeOfString, inputString);
               // tempNode = createNode(tempString);

               // tempLink = createLinkNode(currentFile);

               // head = addToTree(head, tempNode, tempLink);
               // free(tempString);
               // startingPos = -1;
               // sizeOfString = 0;
           }
       }
       // Book keeping for current string.
       ///////////////////
       else
       {
           if(startingPos == -1)
           {
               startingPos = i;
               sizeOfString++;
           }
           else
           {
               sizeOfString++;

           }
       }
   }

   return head;
}

char * pullString(int start, int end, int size, char * originalString)
{
   int x, y;
   char * temp = (char*)calloc(size + 1, sizeof(char));
   for(x = 0, y = start; y < end; x++, y++)
   {
       temp[x] = originalString[y];
   }

   return temp;
}

int intLen(int x)
{  
   int toReturn = 0;
   while(x > 0)
   {
       toReturn++;
       x /= 10;
   }

   return toReturn;
}

void destroyList(nLink * head)
{
   if(head == NULL)
   {
       return;
   }
   else
   {
       destroyList(head->next);
       free(head);
   }
}

libnetfiles.c

#include "libnetfiles.h"

static const int portNum = 42942;

int netopen(char * path)
{
   struct sockaddr_in serverAddressInfo;
   struct hostent *serverIPAddress = gethostbyname("grep.cs.rutgers.edu");

   char sendBuffer[256];
  
   if(serverIPAddress == NULL)
   {
       fprintf(stderr, "Can't find host ");
       return -1;
   }
  
   int socketFD;
   int n;
   int toReturn;
   socketFD = socket(AF_INET, SOCK_STREAM, 0);
  
   if(socketFD < 0)
   {
       fprintf(stderr, "Couldn't make a socket. ");
       return -1;
   }

   bzero((char *) &serverAddressInfo, sizeof(serverAddressInfo));

   serverAddressInfo.sin_family = AF_INET;
   serverAddressInfo.sin_port = htons(portNum);

   bcopy((char *) serverIPAddress->h_addr, (char *)&serverAddressInfo.sin_addr.s_addr, serverIPAddress->h_length);

   if(connect(socketFD, (struct sockaddr *)&serverAddressInfo, sizeof(serverAddressInfo)) < 0)
   {
       fprintf(stderr, "Couldn't connect to socket. ");
       return -1;
   }

   bzero(sendBuffer, 256);
   // fgets(sendBuffer, 255, stdin);
   ///////////////////////////////////////////////////////////
   sprintf(sendBuffer, "open,%s,", path);
   //////////////////////////////////////////////////////////
  
   n = write(socketFD, sendBuffer, strlen(sendBuffer));

   if(n < 0)
   {
       fprintf(stderr, "Couldn't write to socket. ");
       return -1;
   }

   bzero(sendBuffer,256);

   n = read(socketFD, sendBuffer, 255);


   if(n < 0)
   {
       fprintf(stderr, "Couldn't read from socket. ");
       return -1;
   }

  
   toReturn = atoi(sendBuffer);
   return toReturn;
}

libnetfiles.h

#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

typedef struct nLink
{
   char * arg;
   struct nLink * next;
}nLink;

// int open(const char *pathname, int flags);
int nopen(char * buffer);
int intLen(int x);
char * pullString(int start, int end, int size, char * originalString);
nLink * createLink(char * arg);
nLink * addToLL(nLink * head, nLink * newnLink);
nLink * argPull(char * buffer, nLink * head);
int netopen(char * path);