else if (strcmp(token, "add-if") == 0) { action = new AddIfFile(); } else if (strcmp(token, "patch-if") == 0) { action = new PatchIfFile(); }
int DoUpdate(){  char manifest[MAXPATHLEN];  snprintf(manifest, MAXPATHLEN, "%s/update.manifest", gSourcePath);  // extract the manifest  int rv = gArchiveReader.ExtractFile("update.manifest", manifest);  if (rv)    return rv;  AutoFD mfd = open(manifest, O_RDONLY | _O_BINARY);  if (mfd < 0)    return -1;  struct stat ms;  rv = fstat(mfd, &ms);  if (rv)    return IO_ERROR;  char *mbuf = (char*) malloc(ms.st_size + 1);  if (!mbuf)    return BSP_ERROR_NOMEM;  int r = ms.st_size;  char *rb = mbuf;  while (r) {    int c = read(mfd, rb, mmin(SSIZE_MAX,r));    if (c < 0)      return IO_ERROR;    r -= c;    rb += c;    if (c == 0 && r)      return BSP_ERROR_CORRUPT;  }  mbuf[ms.st_size] = '\0';  ActionList list;  rb = mbuf;  char *line;  while((line = mstrtok(kNL, &rb)) != 0) {    // skip comments    if (*line == '#')      continue;    char *token = mstrtok(kWhitespace, &line);    if (!token)      return PARSE_ERROR;    Action *action = NULL;    if (strcmp(token, "remove") == 0) {      action = new RemoveFile();    }    else if (strcmp(token, "add") == 0) {      action = new AddFile();    }    else if (strcmp(token, "patch") == 0) {      action = new PatchFile();    }    else {      return PARSE_ERROR;    }    if (!action)      return BSP_ERROR_NOMEM;    rv = action->Parse(line);    if (rv)      return rv;    list.Append(action);  }  rv = list.Prepare();  if (rv)    return rv;  rv = list.Execute();  list.Finish(rv);  return rv;}