Exemple #1
0
int AddPageVar(PageVar *varlist, char *cmd) {
  char *name = strchr(cmd, ':') + 1;
  char *value = strchr(name, ':') + 1;
  char *end = strchr(cmd, ']');
  if (value - name > sizeof(varlist->name)) {
    // Invalid name length
    return -1;
  } 
  PageVar *pagevar = GetPageVar(varlist, name, value -1);
  if (pagevar != NULL) {
    // Special case, variable already exists
    if (pagevar->value != NULL) {
      free(pagevar->value);
    }
  } else {
    // Add new variable to end of list
    pagevar = varlist;
    while (pagevar->next != NULL) {
      pagevar = pagevar->next;
    }
    pagevar->next = calloc(sizeof(PageVar), 1);
    VerifyPointerOrTerminate(pagevar->next, "New PageVar");
    pagevar = pagevar->next;
  }
  cgc_memcpy(pagevar->name, name, value - 1 - name);
  #ifdef PATCHED
  if (end - value <= 0) {
    return -1;
  }
  #endif 
  pagevar->value = calloc(end - value + 1, 1);
  VerifyPointerOrTerminate(pagevar->value, "PageVar->value");
  cgc_memcpy(pagevar->value, value, end - value);
  return 1;
}
Exemple #2
0
// Initializes the server by loading pages into memory
int InitializeTree() {
  TreeNode *ptr;
  for (int i = 0; i < NUM_INITIAL_PAGES; ++i) {
    TreeNode *node = calloc(sizeof(TreeNode), 1);
    VerifyPointerOrTerminate(node, "TreeNode during initialization");
    strncpy(node->name, InitialInfo[i].name, sizeof(node->name));
    node->page_size = strlen(InitialInfo[i].data) + 1;
    node->page = calloc(node->page_size, 1);
    VerifyPointerOrTerminate(node->page, "node->page during initialization");
    memcpy(node->page, InitialInfo[i].data, node->page_size);
    if (InsertNodeInTree(node) != 0) {
      free(node->page);
      free(node);
      return -1;
    } 
  }
  return 0;
}
Exemple #3
0
int InsertNodeInTree(TreeNode *node) {
  if (root == NULL) {
    TreeNode *node = calloc(sizeof(TreeNode), 1);
    VerifyPointerOrTerminate(node, "root TreeNode during insert");
    node->name[0] = '.';
    root = node;
  }
  // Make sure node doesn't exist
  if (LookupNode(node->name) != NULL) {
    printf("ERROR: node already exists\n");
    return -1;
  }
  // Make sure name isn't blank
  if (node->name[0] == '\0') {
    printf("ERROR: Name cannot be blank\n");
    return -1;
  }
   // Lookup parent node
  char local_name[64];
  memcpy(local_name, node->name, sizeof(local_name));
  char *last_part = strrchr(local_name, '.');
  TreeNode *insert_location = root;
  // If no subparts in name, insert as child to root
  if (last_part == NULL) {
    if (insert_location->child == NULL) {
      insert_location->child = node;
    } else {
      insert_location = insert_location->child;
      while (insert_location->peer != NULL) {
        insert_location = insert_location->peer;
      }
      insert_location->peer = node;
    }
    return 0;
  } 
  // Strip leading portion of name
  strncpy(node->name, last_part + 1, sizeof(node->name));  
  last_part[0] = '\0';
  insert_location = LookupNode(local_name);
  if (insert_location == NULL) {
    printf("ERROR: Parent node doesn't exist: @s\n", local_name);
    return -1;
  }
  if (insert_location->child == NULL) {
    insert_location->child = node;
    return 0;
  } else {
    insert_location = insert_location->child;
    while (insert_location->peer != NULL) {
      insert_location = insert_location->peer;
    }
    insert_location->peer = node;
    return 0;
  }
}
Exemple #4
0
// Processes user supplied variable definitions and then serves the requested
// page using those variables. 
// Variable definitions are in the same syntax as those scripted in a page
// eg. [var:name:value][var:name2:value2]
int InteractWithPage(char *page, int page_size, char *override_data) {
#ifdef PATCHED
  if (override_data == NULL) {
    return ServePageWithOverride(page, page_size, NULL);
  }
#endif 
  PageVar *override_list = calloc(sizeof(PageVar), 1);
  VerifyPointerOrTerminate(override_list, "Override_list initialization");
  // Process override variable definitions
  while(*override_data != '\0' && *override_data != ']') {
    // Check for start of var definition
    if (*override_data != '[') { break; }
    // Process var definition
    AddPageVar(override_list, override_data);
    // Locate end of var definition
    char *end_of_var = strchr(override_data, ']');
    if (end_of_var == NULL) { break; }
    // Step over var definition
    override_data = end_of_var + 1;
  }
  // Serve page with overridden variables
  return ServePageWithOverride(page, page_size, override_list);
}
Exemple #5
0
// Serves a page by interpreting command codes, processing script commands,
// and handling variable substitution. Any variables provided in the override_list
// will take precedence over variables of the same name defined in the page. 
int ServePageWithOverride(char *page, int page_size, PageVar *override_list) {
  // Initialize varlist
  PageVar *varlist = calloc(sizeof(PageVar), 1);
  VerifyPointerOrTerminate(varlist, "VarList initialization");
  in_a_box = 0;
  cgc_memset(line, '\0', sizeof(line));
  line_length = 0;
  
  #ifdef PATCHED
  if (page == NULL) {
    goto error;
  }
  #endif

  while ((*page != '\0')&&(page < page + page_size)) {
    if (*page == '~') {
      // Command character, process command
      page++;
      switch (*page) {
        case 't': {
          for (int i=0; i<4; i++) {
            OutputChar(' ');
          }
          break;
        }
        case 'n': {
          FlushOutput();
          break;
        }
        case '[': {
          OutputChar('[');
          break;
        }
        case ']': {
          OutputChar(']');
          break;
        }
        case '~': {
          OutputChar('~');
          break;
        }
        case '#': {
          OutputChar('#');
          break;
        }
        default: {
          printf("ERROR: Invalid control code\n");
          goto error;
        }
      }
      page++;
    } else if (*page == '[') {
      // Script tag, find closing tag and process script
      char *close = ++page;
      while (*close != ']' && *close != '\0') close++;
      if (*close == '\0') {
        goto error;
      }
      // Process script commands
      if (strncmp(page, "line", cgc_strlen("line")) == 0) {
        page += cgc_strlen("line");
        if (*page != ':') {
          goto error;
        }
        char c = *(++page);
        if (*(++page) != ':') {
          goto error;
        }
        int length = atoi(++page);
        for (int i = 0; i < length; i++) {
          OutputChar(c);
        }
        page = close + 1;
      } else if (strncmp(page, "var", cgc_strlen("var")) == 0) {
        AddPageVar(varlist, page);
        page = close + 1;
      } else if (strncmp(page, "box", cgc_strlen("box")) == 0) {
        in_a_box = 1;
        FlushOutput();
        for (int i = 0; i < 80; i++) {
          putc('*');
        }
        printf("\n");
        page += 4;
      } 
    } else if (*page == ']') {
      page++;
      if (in_a_box) {
        in_a_box = 0;
        FlushOutput();
        for (int i = 0; i < 80; i++) {
          putc('*');
        }
        printf("\n");
      } else {
        goto error;
      }
    } else if (*page == '#') {
      // Variable substitution
      char *end = ++page;
      while (*end != '\0' && *end != '#') { end++; }
      if (*end != '#') {
        goto error;
      }
      PageVar *var = NULL;
      // Check for overridden variables
      if (override_list != NULL) {
        var = GetPageVar(override_list, page, end);
      }
      // Fall back to default values if override doesn't exist
      if (var == NULL) {
        var = GetPageVar(varlist, page, end);
      }
      // If a value has been found, output it
      if (var != NULL) {
        OutputStr(var->value);
      }
      page = end + 1;
    } else {
      // Normal character, send to output
      OutputChar(*page);
      page++;
    }
  }
  if (line_length != 0) {
    FlushOutput();
  }
  DestroyVarList(varlist);
  DestroyVarList(override_list);
  return 0;

error:
  printf("ERROR: Invalid syntax\n");
  DestroyVarList(varlist);
  DestroyVarList(override_list);
  return -1;
}