/* ARGSUSED */ int apropos_command(int f, int n) { struct buffer *bp; struct list *fnames, *el; char string[32]; if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL) return (ABORT); /* FALSE means we got a 0 character string, which is fine */ bp = bfind("*help*", TRUE); if (bclear(bp) == FALSE) return (FALSE); fnames = complete_function_list(""); for (el = fnames; el != NULL; el = el->l_next) { char buf[32]; if (strstr(el->l_name, string) == NULL) continue; buf[0] = '\0'; findbind(fundamental_map, name_function(el->l_name), buf, sizeof(buf)); if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) { free_file_list(fnames); return (FALSE); } } free_file_list(fnames); return (popbuftop(bp, WNONE)); }
/* Finds and reports all duplicate clusters in each bucket of collected files. */ static void process_clusters(void) { size_t i, j, first, second, index = 1; FileList duplicates; init_file_list(&duplicates); for (i = 0; i < BUCKET_COUNT; i++) { File* files = buckets[i].files; for (first = 0; first < buckets[i].allocated; first++) { if (files[first].status == INVALID || files[first].status == DUPLICATE) { continue; } for (second = first + 1; second < buckets[i].allocated; second++) { if (files[second].status == INVALID || files[second].status == DUPLICATE) { continue; } if (compare_files(&files[first], &files[second]) == 0) { if (duplicates.allocated == 0) { *alloc_file(&duplicates) = files[first]; files[first].status = DUPLICATE; } *alloc_file(&duplicates) = files[second]; files[second].status = DUPLICATE; } else { if (files[first].status == INVALID) break; } } if (duplicates.allocated > 0) { report_cluster(&duplicates, index); empty_file_list(&duplicates); index++; } } for (j = 0; j < buckets[i].allocated; j++) free_file(&files[j]); } free_file_list(&duplicates); }
static void set_file_perms(const int perms[13]) { FILE *f; int origin_perms[13] = { 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 }; int adv_perms[3] = { 0, 0, 0 }; assert_non_null(f = fopen(SANDBOX_PATH "/file", "w")); fclose(f); assert_success(chmod(SANDBOX_PATH "/file", 0777)); if(get_perms(SANDBOX_PATH "/file") != 0777) { assert_success(unlink(SANDBOX_PATH "/file")); return; } strcpy(lwin.curr_dir, SANDBOX_PATH); alloc_file_list(&lwin, "file"); set_perm_string(&lwin, perms, origin_perms, adv_perms); free_file_list(&lwin); assert_int_equal(perms_to_mode(perms), get_perms(SANDBOX_PATH "/file")); assert_success(unlink(SANDBOX_PATH "/file")); }
TEST(reset_executable_bits_from_files_only, IF(not_osx)) { FILE *f; int perms[13] = { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1 }; int adv_perms[3] = { 1, 1, 1 }; int origin_perms[13] = { 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1 }; assert_success(os_mkdir(SANDBOX_PATH "/dir", 0777)); assert_non_null(f = fopen(SANDBOX_PATH "/dir/file", "w")); fclose(f); assert_success(chmod(SANDBOX_PATH "/dir/file", 0777)); if(get_perms(SANDBOX_PATH "/dir") != 0777 || get_perms(SANDBOX_PATH "/dir/file") != 0777) { assert_success(unlink(SANDBOX_PATH "/dir/file")); assert_success(rmdir(SANDBOX_PATH "/dir")); return; } strcpy(lwin.curr_dir, SANDBOX_PATH); alloc_file_list(&lwin, "dir"); set_perm_string(&lwin, perms, origin_perms, adv_perms); free_file_list(&lwin); assert_int_equal(perms_to_mode(perms), get_perms(SANDBOX_PATH "/dir/file")); assert_int_equal(0777, get_perms(SANDBOX_PATH "/dir")); assert_success(unlink(SANDBOX_PATH "/dir/file")); assert_success(rmdir(SANDBOX_PATH "/dir")); }
int list_plugins (char folder[], struct file_list **file) { DIR *directory = opendir(folder); struct dirent *entity; struct file_list *filelist = NULL; if (directory == NULL) return ERROR; while ((entity = readdir(directory)) != NULL) { if (strcmp(entity->d_name, ".") != 0 && strcmp(entity->d_name, "..") != 0) { int len = strlen(entity->d_name); int status = 0; if (len > 3) { status = status + (entity->d_name[len-3] == '.'); status = status + (entity->d_name[len-2] == 's'); status = status + (entity->d_name[len-1] == 'o'); if (status == 3) { filelist = new_file_list(); if (filelist == NULL) return ERROR; if (set_file_list_name(filelist, entity->d_name) != SUCCESS){ free_file_list (&filelist); return ERROR; } if (append_file_list (file, filelist) != SUCCESS){ free_file_list (&filelist); return ERROR; } } } } } closedir(directory); return SUCCESS; }
void remove_files_window (gftp_window_data * wdata) { wdata->show_selected = 0; gtk_clist_freeze (GTK_CLIST (wdata->listbox)); gtk_clist_clear (GTK_CLIST (wdata->listbox)); free_file_list (wdata->files); wdata->files = NULL; gtk_clist_thaw (GTK_CLIST (wdata->listbox)); }
void free_matched_files(struct matched_files *lst) { if(lst != (struct matched_files *)NULL) { free_matched_files(lst->ptr_next); if(lst->nfiles) { free_file_list(lst->first_list); free(lst->first_list); } free(lst); lst = (struct matched_files *)NULL; } }
void free_file_list(struct file_list *lst) { if(lst != (struct file_list *)NULL) { free_file_list(lst->next_file); if(lst->name != (char *)NULL) free(lst->name); if(lst->next_file != (struct file_list *)NULL) free(lst->next_file); } }
void free_file_list(struct file_list **list) { if (*list == NULL) return; if ((*list)->next != NULL) free_file_list ( &((*list)->next) ); free((*list)->filename); free(*list); *list = NULL; }
/********************************************************************************************** void QueryDirContent(int server_fd,char directory[]) func:get contends in current directory ***********************************************************************************************/ void QueryDirContent(int server_fd,char directory[]) { char response_type[20]; char response_argu[20]; int server_data_channel_fd; int nbytes; int item_count = 0; struct file_list * files_head = NULL; struct file_list * pfile = NULL; memset(buffer,'\0',BUF_SIZE); //clear the buffer before use sprintf(buffer,"request;querydircontent;%s%s|",current_directory,directory); if(send(server_fd,buffer,strlen(buffer),0)==-1) { printf("send error\n"); } memset(buffer,'\0',BUF_SIZE); //clear the buffer before use recv(server_fd,buffer,BUF_SIZE,0); response_analysis(buffer,response_type,response_argu); if(strcmp(response_type,"error") == 0) { printf("%s:%s\n",response_type,response_argu); return; } server_data_channel_fd = get_data_connection(); memset(buffer,BUF_SIZE,'\0'); //clear the buffer before use printf("type\tname\t\t\t\tsize\n"); while((nbytes = recv(server_data_channel_fd,buffer,BUF_SIZE,0)) > 0) { buffer[nbytes]='\0'; files_head = get_files_information(buffer); pfile = files_head; while(pfile->next_file != NULL){ item_count++; pfile = pfile->next_file; printf("%s\t%-20s\t\t%-6d\n",pfile->file_type?"dir":"file",pfile->file_name,pfile->file_size); } memset(buffer,BUF_SIZE,'\0'); //clear the buffer before use free_file_list(files_head); } printf("total %d items\n",item_count); close_data_connection(server_data_channel_fd); printf("end of query dir \n"); }
void sc_profile_free(struct sc_profile *profile) { struct auth_info *ai; struct pin_info *pi; sc_macro_t *mi; sc_template_t *ti; if (profile->name) free(profile->name); free_file_list(&profile->ef_list); while ((ai = profile->auth_list) != NULL) { profile->auth_list = ai->next; free(ai); } while ((ti = profile->template_list) != NULL) { profile->template_list = ti->next; if (ti->data) sc_profile_free(ti->data); if (ti->name) free(ti->name); free(ti); } while ((mi = profile->macro_list) != NULL) { profile->macro_list = mi->next; if (mi->name) free(mi->name); free(mi); } while ((pi = profile->pin_list) != NULL) { profile->pin_list = pi->next; if (pi->file_name) free(pi->file_name); free(pi); } if (profile->p15_spec) sc_pkcs15_card_free(profile->p15_spec); memset(profile, 0, sizeof(*profile)); free(profile); }
/* Initializes the driver, processes the specified arguments and reports the * clusters found. */ void process_args(int argc, char** argv) { size_t i; memset(&recorded_dirs, 0, sizeof(DirList)); for (i = 0; i < BUCKET_COUNT; i++) init_file_list(&buckets[i]); if (argc) { /* Read file names from command line */ for (i = 0; i < argc; i++) { kill_trailing_slashes(argv[i]); process_path(argv[i], 0); } } else { char* path; /* Read file names from stdin */ while ((path = read_path(stdin))) { kill_trailing_slashes(path); process_path(path, 0); free(path); } } if (unique_files_flag) process_uniques(); else process_clusters(); for (i = 0; i < BUCKET_COUNT; i++) free_file_list(&buckets[i]); free(recorded_dirs.dirs); memset(&recorded_dirs, 0, sizeof(DirList)); }
/* * List possible function name completions. */ struct list * complete_function_list(const char *fname) { struct funmap *fn; struct list *head, *el; int len; len = strlen(fname); head = NULL; for (fn = funs; fn != NULL; fn = fn->fn_next) { if (memcmp(fname, fn->fn_name, len) == 0) { if ((el = malloc(sizeof(*el))) == NULL) { free_file_list(head); return (NULL); } el->l_name = strdup(fn->fn_name); el->l_next = head; head = el; } } return (head); }
GHashTable *load_workflow_config_data_from_list(GList *wf_names, const char *path) { GList *wfs = wf_names; GHashTable *wf_list = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_workflow ); if (path == NULL) path = WORKFLOWS_DIR; GList *workflow_files = get_file_list(path, "xml"); while(wfs) { load_workflow_config((const char *)wfs->data, workflow_files, wf_list); wfs = g_list_next(wfs); } free_file_list(workflow_files); return wf_list; }
/* * Do completion on a list of objects, listing instead of completing. */ static int complt_list(int flags, char *buf, int cpos) { struct list *lh, *lh2, *lh3; struct list *wholelist = NULL; struct buffer *bp; int i, maxwidth, width; int preflen = 0; int oldrow = ttrow; int oldcol = ttcol; int oldhue = tthue; char *linebuf; size_t linesize, len; char *cp; lh = NULL; ttflush(); /* The results are put into a completion buffer. */ bp = bfind("*Completions*", TRUE); if (bclear(bp) == FALSE) return (FALSE); /* * First get the list of objects. This list may contain only * the ones that complete what has been typed, or may be the * whole list of all objects of this type. They are filtered * later in any case. Set wholelist if the list has been * cons'ed up just for us, so we can free it later. We have * to copy the buffer list for this function even though we * didn't for complt. The sorting code does destructive * changes to the list, which we don't want to happen to the * main buffer list! */ if ((flags & EFBUF) != 0) wholelist = lh = copy_list(&(bheadp->b_list)); else if ((flags & EFFUNC) != 0) { buf[cpos] = '\0'; wholelist = lh = complete_function_list(buf); } else if ((flags & EFFILE) != 0) { buf[cpos] = '\0'; wholelist = lh = make_file_list(buf); /* * We don't want to display stuff up to the / for file * names preflen is the list of a prefix of what the * user typed that should not be displayed. */ cp = strrchr(buf, '/'); if (cp) preflen = cp - buf + 1; } else panic("broken complt call: flags"); /* * Sort the list, since users expect to see it in alphabetic * order. */ lh2 = lh; while (lh2 != NULL) { lh3 = lh2->l_next; while (lh3 != NULL) { if (strcmp(lh2->l_name, lh3->l_name) > 0) { cp = lh2->l_name; lh2->l_name = lh3->l_name; lh3->l_name = cp; } lh3 = lh3->l_next; } lh2 = lh2->l_next; } /* * First find max width of object to be displayed, so we can * put several on a line. */ maxwidth = 0; lh2 = lh; while (lh2 != NULL) { for (i = 0; i < cpos; ++i) { if (buf[i] != lh2->l_name[i]) break; } if (i == cpos) { width = strlen(lh2->l_name); if (width > maxwidth) maxwidth = width; } lh2 = lh2->l_next; } maxwidth += 1 - preflen; /* * Now do the display. Objects are written into linebuf until * it fills, and then put into the help buffer. */ linesize = MAX(ncol, maxwidth) + 1; if ((linebuf = malloc(linesize)) == NULL) { free_file_list(wholelist); return (FALSE); } width = 0; /* * We're going to strlcat() into the buffer, so it has to be * NUL terminated. */ linebuf[0] = '\0'; for (lh2 = lh; lh2 != NULL; lh2 = lh2->l_next) { for (i = 0; i < cpos; ++i) { if (buf[i] != lh2->l_name[i]) break; } /* if we have a match */ if (i == cpos) { /* if it wraps */ if ((width + maxwidth) > ncol) { addline(bp, linebuf); linebuf[0] = '\0'; width = 0; } len = strlcat(linebuf, lh2->l_name + preflen, linesize); width += maxwidth; if (len < width && width < linesize) { /* pad so the objects nicely line up */ memset(linebuf + len, ' ', maxwidth - strlen(lh2->l_name + preflen)); linebuf[width] = '\0'; } } } if (width > 0) addline(bp, linebuf); free(linebuf); /* * Note that we free lists only if they are put in wholelist lists * that were built just for us should be freed. However when we use * the buffer list, obviously we don't want it freed. */ free_file_list(wholelist); popbuftop(bp, WEPHEM); /* split the screen and put up the help * buffer */ update(CMODE); /* needed to make the new stuff actually * appear */ ttmove(oldrow, oldcol); /* update leaves cursor in arbitrary place */ ttcolor(oldhue); /* with arbitrary color */ ttflush(); return (0); }
int main( int argc, char* argv[]) { const SCHAR* const prog_name = argv[0]; if (argc < 2) { fprintf(stderr, "%s: No Command Line Option Specified\n", argv[0]); print_clo(prog_name); return FB_FAILURE; } // Fields initialization b_fil* file_ptr = NULL; b_fil* file_list = NULL; b_fil* prev_file = NULL; SINT64 file_size = -1; gsplit_option sw_replace = IN_SW_SPIT_0; // Initialize in_sw_table table. const Switches switches(spit_in_sw_table, FB_NELEM(spit_in_sw_table), false, false); // validating command line options SLONG ret_cd, file_num = 0; bool file_nm_sw = false; const SCHAR* string = NULL; const SCHAR* const* const end = argv + argc; ++argv; while (argv < end) { string = *argv; if (*string == '-') { argv++; ret_cd = get_function_option(prog_name, &sw_replace, string, switches); if (ret_cd == FB_FAILURE) { free_file_list(file_list); return FB_FAILURE; } } // end of processing (*string == '-') else { // processing function specific command line options switch (sw_replace) { case IN_SW_SPIT_SP: if (!file_nm_sw) { // process file name file_size = 0; file_num = file_num + 1; if (file_num > MAX_NUM_OF_FILES) { fprintf(stderr, "%s: maximum of files is %d\n", prog_name, MAX_NUM_OF_FILES); print_clo(prog_name); free_file_list(file_list); return FB_FAILURE; } if (strlen(string) > MAX_FILE_NM_LEN) { fprintf(stderr, "%s: file name %s is too long\n", prog_name, string); fprintf(stderr, "%s: maximum length of file name is %"SIZEFORMAT" bytes\n", prog_name, MAX_FILE_NM_LEN); print_clo(prog_name); free_file_list(file_list); return FB_FAILURE; } ret_cd = get_file_name(string, file_size, &file_ptr); if (ret_cd == FB_FAILURE) { free_file_list(file_list); return FB_FAILURE; } file_nm_sw = true; file_ptr->b_fil_number = file_num; if (!file_list) file_list = prev_file = file_ptr; else { prev_file->b_fil_next = file_ptr; prev_file = file_ptr; } } // processing file name else { // processing file size file_nm_sw = false; ret_cd = get_file_size(prog_name, string, &file_size); if (ret_cd == FB_FAILURE) { free_file_list(file_list); return FB_FAILURE; } } // end of processing file size specification file_ptr->b_fil_size = file_size; break; case IN_SW_SPIT_JT: ret_cd = get_file_name(string, file_size, &file_ptr); if (ret_cd == FB_FAILURE) { free_file_list(file_list); return FB_FAILURE; } file_num = file_num + 1; file_ptr->b_fil_number = file_num; if (!file_list) file_list = prev_file = file_ptr; else { prev_file->b_fil_next = file_ptr; prev_file = file_ptr; } // end of processing file size specification break; default: fprintf(stderr, "%s: invalid option '%s'\n", prog_name, string); print_clo(prog_name); free_file_list(file_list); return FB_FAILURE; } // end of switch (sw_replace) argv++; } // processing function specific command line options } // while (argv < end) if (!file_list && sw_replace != IN_SW_SPIT_0) { fprintf(stderr, "%s: invalid option '%s', rest of parameters is missing\n", prog_name, string); print_clo(prog_name); free_file_list(file_list); return FB_FAILURE; } FILE_DESC input_file_desc; switch (sw_replace) { case IN_SW_SPIT_SP: input_file_desc = GBAK_STDIN_DESC(); ret_cd = gen_multy_bakup_files(file_list, input_file_desc, file_num); if (ret_cd == FB_FAILURE) { fprintf(stderr, "%s: progam fails to generate multi-volumn back-up files\n", prog_name); free_file_list(file_list); return FB_FAILURE; } break; case IN_SW_SPIT_JT: ret_cd = join_multy_bakup_files(file_list); if (ret_cd == FB_FAILURE) { fprintf(stderr, "%s: progam fails to join multi-volumn back-up files\n", prog_name); free_file_list(file_list); return FB_FAILURE; } break; default: break; } // free all the storage allocated for backup files free_file_list(file_list); return FB_SUCCESS; } // end of main()
/* * Do completion on a list of objects. * c is SPACE, TAB, or CR * return TRUE if matched (or partially matched) * FALSE is result is ambiguous, * ABORT on error. */ static int complt(int flags, int c, char *buf, size_t nbuf, int cpos, int *nx) { struct list *lh, *lh2; struct list *wholelist = NULL; int i, nxtra, nhits, bxtra, msglen, nshown; int wflag = FALSE; char *msg; lh = lh2 = NULL; if ((flags & EFFUNC) != 0) { buf[cpos] = '\0'; wholelist = lh = complete_function_list(buf); } else if ((flags & EFBUF) != 0) { lh = &(bheadp->b_list); } else if ((flags & EFFILE) != 0) { buf[cpos] = '\0'; wholelist = lh = make_file_list(buf); } else panic("broken complt call: flags"); if (c == ' ') wflag = TRUE; else if (c != '\t' && c != CCHR('M')) panic("broken complt call: c"); nhits = 0; nxtra = HUGE; for (; lh != NULL; lh = lh->l_next) { if (memcmp(buf, lh->l_name, cpos) != 0) continue; if (nhits == 0) lh2 = lh; ++nhits; if (lh->l_name[cpos] == '\0') nxtra = -1; /* exact match */ else { bxtra = getxtra(lh, lh2, cpos, wflag); if (bxtra < nxtra) nxtra = bxtra; lh2 = lh; } } if (nhits == 0) msg = " [No match]"; else if (nhits > 1 && nxtra == 0) msg = " [Ambiguous. Ctrl-G to cancel]"; else { /* * Being lazy - ought to check length, but all things * autocompleted have known types/lengths. */ if (nxtra < 0 && nhits > 1 && c == ' ') nxtra = 1; /* ??? */ for (i = 0; i < nxtra && cpos < nbuf; ++i) { buf[cpos] = lh2->l_name[cpos]; eputc(buf[cpos++]); } /* XXX should grow nbuf */ ttflush(); free_file_list(wholelist); *nx = nxtra; if (nxtra < 0 && c != CCHR('M')) /* exact */ *nx = 0; return (TRUE); } /* * wholelist is NULL if we are doing buffers. Want to free lists * that were created for us, but not the buffer list! */ free_file_list(wholelist); /* Set up backspaces, etc., being mindful of echo line limit. */ msglen = strlen(msg); nshown = (ttcol + msglen + 2 > ncol) ? ncol - ttcol - 2 : msglen; eputs(msg); ttcol -= (i = nshown); /* update ttcol! */ while (i--) /* move back before msg */ ttputc('\b'); ttflush(); /* display to user */ i = nshown; while (i--) /* blank out on next flush */ eputc(' '); ttcol -= (i = nshown); /* update ttcol on BS's */ while (i--) ttputc('\b'); /* update ttcol again! */ *nx = nxtra; return ((nhits > 0) ? TRUE : FALSE); }
int main (int argc, char *argv[]) { char *nistfile = NULL; char *tolstr = NULL; int i, err = 0; /* parse option flags */ while (1) { int c = getopt(argc, argv, "avf:t:"); if (c == -1) break; switch (c) { case 'a': use_derivs = 1; break; case 'v': verbose = 1; break; case 'f': nistfile = optarg; break; case 't': tolstr = optarg; break; case ':': case '?': exit(EXIT_FAILURE); break; default: break; } } print_options(argv[0], nistfile, tolstr); if (tolstr != NULL) { toler = atof(tolstr); if (toler <= 0.0) { fprintf(stderr, "Invalid tolerance '%s'\n", tolstr); err = 1; } } if (nistfile != NULL) { nfiles = 1; } else { err = make_file_list(); } if (err) { exit(EXIT_FAILURE); } libgretl_init(); for (i=0; i<nfiles; i++) { char *thisfile; if (nistfile) { thisfile = nistfile; } else { thisfile = file_list[i]; } printf("\nReading %s...\n", thisfile); err = read_nist_nls_data(thisfile); if (!err) { err = run_gretl_nls_check(); } free_Z(Z, datainfo); free_datainfo(datainfo); Z = NULL; datainfo = NULL; } if (nfiles > 1) { print_nls_summary(); free_file_list(); } libgretl_cleanup(); return err; }
static void test_Extract(void) { SESSION session; HRESULT res; struct FILELIST *node; /* native windows crashes if * - invalid parameters are sent in * - you call EXTRACT_EXTRACTFILES without calling * EXTRACT_FILLFILELIST first or at the same time */ /* try to extract all files */ ZeroMemory(&session, sizeof(SESSION)); lstrcpyA(session.Destination, "dest"); session.Operation = EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 4, "Expected 4, got %d\n", session.FileCount); ok(session.Operation == (EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES), "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n"); ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "a.txt", FALSE), "list entry wrong\n"); free_file_list(&session); /* try fill file list operation */ ZeroMemory(&session, sizeof(SESSION)); lstrcpyA(session.Destination, "dest"); session.Operation = EXTRACT_FILLFILELIST; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 4, "Expected 4, got %d\n", session.FileCount); ok(session.Operation == EXTRACT_FILLFILELIST, "Expected EXTRACT_FILLFILELIST, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "b.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "a.txt", TRUE), "list entry wrong\n"); /* try extract files operation once file list is filled */ session.Operation = EXTRACT_EXTRACTFILES; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 4, "Expected 4, got %d\n", session.FileCount); ok(session.Operation == EXTRACT_EXTRACTFILES, "Expected EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n"); ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n"); ok(RemoveDirectoryA("dest"), "Expected dest to exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "a.txt", FALSE), "list entry wrong\n"); /* Extract does not extract files if the dest dir does not exist */ res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 4, "Expected 4, got %d\n", session.FileCount); ok(session.Operation == EXTRACT_EXTRACTFILES, "Expected EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "a.txt", FALSE), "list entry wrong\n"); /* remove two of the files in the list */ node = session.FileList->next; session.FileList->next = session.FileList->next->next; free_file_node(node); free_file_node(session.FileList->next->next); session.FileList->next->next = NULL; session.FilterList = NULL; CreateDirectoryA("dest", NULL); res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 4, "Expected 4, got %d\n", session.FileCount); ok(session.Operation == EXTRACT_EXTRACTFILES, "Expected EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "a.txt", FALSE), "list entry wrong\n"); free_file_list(&session); session.Operation = EXTRACT_FILLFILELIST; session.FileList = NULL; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 8, "Expected 8, got %d\n", session.FileCount); ok(session.Operation == EXTRACT_FILLFILELIST, "Expected EXTRACT_FILLFILELIST, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", TRUE), "list entry wrong\n"); ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "a.txt", FALSE), "list entry wrong\n"); session.Operation = 0; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 8, "Expected 8, got %d\n", session.FileCount); ok(session.Operation == 0, "Expected 0, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n"); ok(check_list(&node, "testdir\\d.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "b.txt", TRUE), "list entry wrong\n"); ok(check_list(&node, "a.txt", TRUE), "list entry wrong\n"); session.Operation = 0; session.FilterList = session.FileList; res = pExtract(&session, "extract.cab"); node = session.FileList; ok(res == S_OK, "Expected S_OK, got %d\n", res); ok(session.FileSize == 40, "Expected 40, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_NONE, "Expected FDIERROR_NONE, got %d\n", session.Error.erfOper); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == FALSE, "Expected FALSE, got %d\n", session.Error.fError); ok(session.FileCount == 8, "Expected 8, got %d\n", session.FileCount); ok(session.Operation == 0, "Expected 0, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n"); ok(DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "a.txt", FALSE), "list entry wrong\n"); node = session.FilterList; ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "a.txt", FALSE), "list entry wrong\n"); free_file_list(&session); /* cabinet does not exist */ ZeroMemory(&session, sizeof(SESSION)); lstrcpyA(session.Destination, "dest"); session.Operation = EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES; res = pExtract(&session, "nonexistent.cab"); node = session.FileList; ok(res == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", res); ok(session.Error.erfOper == FDIERROR_CABINET_NOT_FOUND, "Expected FDIERROR_CABINET_NOT_FOUND, got %d\n", session.Error.erfOper); ok(session.FileSize == 0, "Expected 0, got %d\n", session.FileSize); ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Error.fError == TRUE, "Expected TRUE, got %d\n", session.Error.fError); ok(session.FileCount == 0, "Expected 0, got %d\n", session.FileCount); ok(session.Operation == (EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES), "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!*session.CurrentFile, "Expected empty string, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(!check_list(&node, "testdir\\d.txt", FALSE), "list entry should not exist\n"); ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry should not exist\n"); ok(!check_list(&node, "b.txt", FALSE), "list entry should not exist\n"); ok(!check_list(&node, "a.txt", FALSE), "list entry should not exist\n"); free_file_list(&session); /* first file exists */ createTestFile("dest\\a.txt"); SetFileAttributes("dest\\a.txt", FILE_ATTRIBUTE_READONLY); ZeroMemory(&session, sizeof(SESSION)); lstrcpyA(session.Destination, "dest"); session.Operation = EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES; res = pExtract(&session, "extract.cab"); node = session.FileList; todo_wine { ok(res == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) || res == E_FAIL, "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) or E_FAIL, got %08x\n", res); ok(session.FileSize == 6, "Expected 6, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_USER_ABORT, "Expected FDIERROR_USER_ABORT, got %d\n", session.Error.erfOper); ok(session.Error.fError == TRUE, "Expected TRUE, got %d\n", session.Error.fError); ok(session.FileCount == 1, "Expected 1, got %d\n", session.FileCount); ok(!lstrcmpA(session.CurrentFile, "dest\\a.txt"), "Expected dest\\a.txt, got %s\n", session.CurrentFile); } ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Operation == (EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES), "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); todo_wine { ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(!check_list(&node, "testdir\\d.txt", FALSE), "list entry should not exist\n"); ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry should not exist\n"); ok(!check_list(&node, "b.txt", FALSE), "list entry should not exist\n"); } ok(!check_list(&node, "a.txt", FALSE), "list entry should not exist\n"); free_file_list(&session); SetFileAttributesA("dest\\a.txt", FILE_ATTRIBUTE_NORMAL); DeleteFileA("dest\\a.txt"); /* third file exists */ createTestFile("dest\\testdir\\c.txt"); SetFileAttributes("dest\\testdir\\c.txt", FILE_ATTRIBUTE_READONLY); ZeroMemory(&session, sizeof(SESSION)); lstrcpyA(session.Destination, "dest"); session.Operation = EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES; res = pExtract(&session, "extract.cab"); node = session.FileList; todo_wine { ok(res == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) || res == E_FAIL, "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) or E_FAIL, got %08x\n", res); ok(session.FileSize == 26, "Expected 26, got %d\n", session.FileSize); ok(session.Error.erfOper == FDIERROR_USER_ABORT, "Expected FDIERROR_USER_ABORT, got %d\n", session.Error.erfOper); ok(session.Error.fError == TRUE, "Expected TRUE, got %d\n", session.Error.fError); ok(session.FileCount == 3, "Expected 3, got %d\n", session.FileCount); ok(!lstrcmpA(session.CurrentFile, "dest\\testdir\\c.txt"), "Expected dest\\c.txt, got %s\n", session.CurrentFile); } ok(session.Error.erfType == 0, "Expected 0, got %d\n", session.Error.erfType); ok(session.Operation == (EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES), "Expected EXTRACT_FILLFILELIST | EXTRACT_EXTRACTFILES, got %d\n", session.Operation); ok(!lstrcmpA(session.Destination, "dest"), "Expected dest, got %s\n", session.Destination); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); ok(DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); todo_wine { ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(!check_list(&node, "testdir\\d.txt", FALSE), "list entry should not exist\n"); } ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "b.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "a.txt", TRUE), "list entry wrong\n"); free_file_list(&session); SetFileAttributesA("dest\\testdir\\c.txt", FILE_ATTRIBUTE_NORMAL); DeleteFileA("dest\\testdir\\c.txt"); ok(RemoveDirectoryA("dest\\testdir"), "Expected dest\\testdir to exist\n"); ok(RemoveDirectoryA("dest"), "Expected dest to exist\n"); }
/*********************************************************************** * ExtractFilesA (ADVPACK.@) * * Extracts the specified files from a cab archive into * a destination directory. * * PARAMS * CabName [I] Filename of the cab archive. * ExpandDir [I] Destination directory for the extracted files. * Flags [I] Reserved. * FileList [I] Optional list of files to extract. See NOTES. * LReserved [I] Reserved. Must be NULL. * Reserved [I] Reserved. Must be 0. * * RETURNS * Success: S_OK. * Failure: E_FAIL. * * NOTES * FileList is a colon-separated list of filenames. If FileList is * non-NULL, only the files in the list will be extracted from the * cab file, otherwise all files will be extracted. Any number of * spaces, tabs, or colons can be before or after the list, but * the list itself must only be separated by colons. */ HRESULT WINAPI ExtractFilesA(LPCSTR CabName, LPCSTR ExpandDir, DWORD Flags, LPCSTR FileList, LPVOID LReserved, DWORD Reserved) { SESSION session; HMODULE hCabinet; HRESULT res = S_OK; DWORD dwFileCount = 0; DWORD dwFilesFound = 0; LPSTR szConvertedList = NULL; TRACE("(%s, %s, %d, %s, %p, %d)\n", debugstr_a(CabName), debugstr_a(ExpandDir), Flags, debugstr_a(FileList), LReserved, Reserved); if (!CabName || !ExpandDir) return E_INVALIDARG; if (GetFileAttributesA(ExpandDir) == INVALID_FILE_ATTRIBUTES) return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); hCabinet = LoadLibraryA("cabinet.dll"); if (!hCabinet) return E_FAIL; ZeroMemory(&session, sizeof(SESSION)); pExtract = (void *)GetProcAddress(hCabinet, "Extract"); if (!pExtract) { res = E_FAIL; goto done; } lstrcpyA(session.Destination, ExpandDir); if (FileList) { szConvertedList = convert_file_list(FileList, &dwFileCount); if (!szConvertedList) { res = E_FAIL; goto done; } dwFilesFound = fill_file_list(&session, CabName, szConvertedList); if (dwFilesFound != dwFileCount) { res = E_FAIL; goto done; } } else session.Operation |= EXTRACT_FILLFILELIST; session.Operation |= EXTRACT_EXTRACTFILES; res = pExtract(&session, CabName); done: free_file_list(&session); FreeLibrary(hCabinet); HeapFree(GetProcessHeap(), 0, szConvertedList); return res; }
/* * return list of file names that match the name in buf. */ struct list * make_file_list(char *buf) { char *dir, *file, *cp; size_t len, preflen; int ret; DIR *dirp; struct dirent *dent; struct list *last, *current; char fl_name[NFILEN + 2]; char prefixx[NFILEN + 1]; /* * We need three different strings: * dir - the name of the directory containing what the user typed. * Must be a real unix file name, e.g. no ~user, etc.. * Must not end in /. * prefix - the portion of what the user typed that is before the * names we are going to find in the directory. Must have a * trailing / if the user typed it. * names from the directory - We open dir, and return prefix * concatenated with names. */ /* first we get a directory name we can look up */ /* * Names ending in . are potentially odd, because adjustname will * treat foo/bar/.. as a foo/, whereas we are * interested in names starting with .. */ len = strlen(buf); if (len && buf[len - 1] == '.') { buf[len - 1] = 'x'; dir = adjustname(buf, TRUE); buf[len - 1] = '.'; } else dir = adjustname(buf, TRUE); if (dir == NULL) return (NULL); /* * If the user typed a trailing / or the empty string * he wants us to use his file spec as a directory name. */ if (len && buf[len - 1] != '/') { file = strrchr(dir, '/'); if (file) { *file = '\0'; if (*dir == '\0') dir = "/"; } else return (NULL); } /* Now we get the prefix of the name the user typed. */ if (strlcpy(prefixx, buf, sizeof(prefixx)) >= sizeof(prefixx)) return (NULL); cp = strrchr(prefixx, '/'); if (cp == NULL) prefixx[0] = '\0'; else cp[1] = '\0'; preflen = strlen(prefixx); /* cp is the tail of buf that really needs to be compared. */ cp = buf + preflen; len = strlen(cp); /* * Now make sure that file names will fit in the buffers allocated. * SV files are fairly short. For BSD, something more general would * be required. */ if (preflen > NFILEN - MAXNAMLEN) return (NULL); /* loop over the specified directory, making up the list of files */ /* * Note that it is worth our time to filter out names that don't * match, even though our caller is going to do so again, and to * avoid doing the stat if completion is being done, because stat'ing * every file in the directory is relatively expensive. */ dirp = opendir(dir); if (dirp == NULL) return (NULL); last = NULL; while ((dent = readdir(dirp)) != NULL) { int isdir; if (strncmp(cp, dent->d_name, len) != 0) continue; isdir = 0; if (dent->d_type == DT_DIR) { isdir = 1; } else if (dent->d_type == DT_LNK || dent->d_type == DT_UNKNOWN) { struct stat statbuf; char statname[NFILEN + 2]; statbuf.st_mode = 0; ret = snprintf(statname, sizeof(statname), "%s/%s", dir, dent->d_name); if (ret < 0 || ret > sizeof(statname) - 1) continue; if (stat(statname, &statbuf) < 0) continue; if (S_ISDIR(statbuf.st_mode)) isdir = 1; } if ((current = malloc(sizeof(struct list))) == NULL) { free_file_list(last); closedir(dirp); return (NULL); } ret = snprintf(fl_name, sizeof(fl_name), "%s%s%s", prefixx, dent->d_name, isdir ? "/" : ""); if (ret < 0 || ret >= sizeof(fl_name)) { free(current); continue; } current->l_next = last; current->l_name = strdup(fl_name); last = current; } closedir(dirp); return (last); }
/** * Reads the list of files from the host IDE runs on, * creates files, fills internal file table */ static int init_files() { trace("Files list initialization\n"); int bufsize = PATH_MAX + 32; char buffer[bufsize]; int success = false; file_elem* list = NULL; file_elem* tail = NULL; start_adding_file_data(); while (1) { if( !fgets(buffer, bufsize, stdin)) { report_error("protocol error while reading file info: unexpected EOF\n"); return false; } if (buffer[0] == '\n') { success = true; break; } trace("\tFile init: %s", buffer); // no trailing LF since it's in the buffer // remove trailing LF char* lf = strchr(buffer, '\n'); if (lf) { *lf = 0; } if (strchr(buffer, '\r')) { report_error("protocol error: unexpected CR: %s\n", buffer); return false; } enum file_state state; int file_size; char *path; struct timeval file_time; file_time.tv_sec = file_time.tv_usec = 0; if (!scan_line(buffer, bufsize, &state, &file_size, &file_time, (const char**) &path)) { report_error("protocol error: %s\n", buffer); break; } trace("\t\tpath=%s size=%d state=%c (0x%x) time=%d.%d\n", path, file_size, (char) state, (char) state, file_time.tv_sec, file_time.tv_usec); if (state == -1) { report_error("protocol error: %s\n", buffer); break; } else if (state == DIRECTORY) { // directory create_dir(path); } else if (state == LINK) { // symbolic link char lnk_src[bufsize]; // it is followed by a line that contains the link source if( !fgets(lnk_src, sizeof lnk_src, stdin)) { report_error("protocol error while reading link info: unexpected EOF\n"); return false; } char* lf = strchr(lnk_src, '\n'); if (lf) { *lf = 0; } if (strchr(buffer, '\r')) { report_error("protocol error: unexpected CR: %s\n", buffer); return false; } create_lnk(path, lnk_src); } else { // plain file int touch = false; if (state == INITIAL) { touch = true; } else if (state == COPIED || state == TOUCHED) { touch = !file_exists(path, file_size); } else if (state == UNCONTROLLED || state == INEXISTENT) { // nothing } else { report_error("protocol error: %s\n", buffer); } enum file_state new_state = state; if (touch) { if (touch_file(path, file_size, &file_time)) { new_state = TOUCHED; } else { new_state = ERROR; } } if (*path == '/') { char real_path [PATH_MAX + 1]; if (state == UNCONTROLLED || state == INEXISTENT) { char *dir = path; char *file = path; // find trailing zero while (*file) { file++; } // we'll find '/' for sure - at least the starting one while(*file != '/') { file--; } if (file == path) { // the file resides in root directory strcpy(real_path, path); } else { // NB: we modify the path! but we'll restore later char *pfile_start = file; // save file start char char file_start = *file; // save file start char *file = 0; // replace the '/' that separates file from dir by zero file++; if (!realpath(dir, real_path)) { report_unresolved_path(dir); break; } char *p = real_path; while (*p) { p++; } *(p++) = '/'; strncpy(p, file, sizeof real_path - (p - real_path)); *pfile_start = file_start; // restore file start char } } else { if (!realpath(path, real_path)) { report_unresolved_path(path); break; } } trace("\t\tadding %s with state '%c' (0x%x) -> %s\n", path, (char) new_state, (char) new_state, real_path); add_file_data(real_path, new_state); // send real path to local controller tail = add_file_to_list(tail, path, new_state, real_path); //trace("\t\tadded to list %s with state '%c' (0x%x) -> %s\n", tail->filename, tail->state, tail->state, tail->real_path); if (list == NULL) { list = tail; } } else { report_error("protocol error: %s is not absoulte\n", path); break; } } } stop_adding_file_data(); trace("Files list initialization done\n"); if (success) { // send info about touched files which were passed as copied files tail = list; while (tail != NULL) { fprintf(stdout, "*%c%s\n%s\n", tail->state, tail->filename, tail->real_path); fflush(stdout); tail = tail->next; } free_file_list(list); // empty line as indication of finished files list fprintf(stdout, "\n"); fflush(stdout); } return success; }