static int find_shortest_path (Bitmap *bitmap, GraphPath **path_r) /* current optimal path */ { GraphPath *path = *path_r; GraphPath *found_path = NULL; int cur_path_size = path->num_edges; int j,i; size_t num_p; int status = 1; int two_pass_mode = (cur_path_size < num_nodes); GraphNode **idc = alloca ( (path->num_edges + 1)*sizeof (GraphNode*) ); path_transform_to_reverse_nodes_aray (path, &idc, &num_p); _loop_enter: for (j = 0 ; j < num_p ;j++) { GraphNode *curnode = idc[j]; for (i = 0; i < curnode->num_edges; i++) { GraphEdge *curedge = curnode->edges[i]; GraphNode *node_to = curedge->node_ptr; if (path->total_weight + curedge->weight >= _found_min){ #ifdef DEBUG _stat_cut_by_weight++; #endif continue; //don't go this way } if (two_pass_mode && status && bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (two_pass_mode && !status && !bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (bmap_get (bitmap, curnode->arr_idx, node_to->arr_idx)){ #ifdef DEBUG _stat_cut_by_presence++; #endif continue; //already passed by this edge } _stop_cnt++; if (_stop_cnt > MAXIMUM_SEARCH_ITERATION){ //up until third level if (cur_path_size < _update_path){ _update_path -= 2; // printf ("max path update: %d\n", _update_path); _stop_cnt = 0; } goto _loop_exit; } #ifdef DEBUG _stat_evaluated++; #endif void *bitmap_n = bmap_clone (bitmap); // printf ("before(%d,%d): ",i,j); // path_print_short (path); path_add (path, curedge); bmap_set (bitmap_n, curnode->arr_idx, node_to->arr_idx); // printf ("after(%d,%d) : ",i,j); // path_print_short (path); int path_found = bmap_check_full (bitmap_n) && path_check_valid (path); GraphPath *hpath = NULL; if (path_found == 0){ //try to check solution in hash table hpath = bmap_hash_path_search_optimal (bitmap_n); if (hpath == NULL){ if (path->num_edges <= _depth ) path_found = find_shortest_path (bitmap_n, &path); }else { #ifdef DEBUG _stat_found_hash++; #endif if (hpath != BMAP_HASH_PATH_EMPTY ){ hpath = path_clone (hpath); //rearrange path ensure_order_paths (path, hpath, cur_path_size); path_free (path); path = hpath; path_found = 1; }else{ path_found = 0; } } } if (path_found == 1 && (found_path == NULL || path->total_weight < found_path->total_weight)) { path_free (found_path); found_path = path_clone (path); if (hpath == NULL && found_path->num_edges - cur_path_size > 1) bmap_hash_path_add_optimal (bitmap_n, found_path); }else{ if (hpath == NULL && cur_path_size < num_nodes + 2) bmap_hash_path_add_optimal (bitmap_n, NULL); } path_shrink_to_size (path, cur_path_size); bmap_free (bitmap_n); } } if(two_pass_mode && status && cur_path_size < num_nodes){ status = 0; goto _loop_enter; } _loop_exit: if (found_path != NULL){ _update_path = found_path->num_edges; // printf ("FOUND: "); // path_print_short (found_path); path_free (path); if (found_path->total_weight < _found_min){ _stop_cnt = 0; #ifdef DEBUG printf (" update max: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, found_path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); #endif _found_min = found_path->total_weight; } *path_r = found_path; return 1; } return 0; }
entry_t *traverse(void) /* Get one name from the directory tree. */ { static int depth; static pathname_t path; static entry_t entry; static namelist_t **entries; static size_t *trunc; static size_t deep; static namelist_t *newentries; struct stat st; recurse: keep= KEEP_TRAVERSE; if (deep == 0) { /* Initialize for the root of the tree. */ path_init(&path); path_add(&path, tree); entries= allocate(nil, 1 * sizeof(entries[0])); entries[0]= allocate(nil, sizeof(*entries[0])); entries[0]->next= nil; entries[0]->name= copystr("/"); trunc= allocate(nil, 1 * sizeof(trunc[0])); trunc[0]= path_length(&path); deep= 1; } else if (newentries != nil) { /* Last entry was a directory, need to go down. */ if (entry.ignore) { /* Ouch, it is to be ignored! */ while (newentries != nil) (void) pop_name(&newentries); goto recurse; } if (++depth == deep) { deep++; entries= allocate(entries, deep * sizeof(entries[0])); trunc= allocate(trunc, deep * sizeof(trunc[0])); } entries[depth]= newentries; newentries= nil; trunc[depth]= path_length(&path); } else { /* Pop up out of emptied directories. */ while (entries[depth] == nil) { if (depth == 0) return nil; /* Back at the root. */ /* Go up one level. */ depth--; } } entry.name= pop_name(&entries[depth]); path_trunc(&path, trunc[depth]); path_add(&path, entry.name); if (depth == 0) { entry.path= "/"; } else { entry.path= path_name(&path) + trunc[0]; if (entry.path[0] == '/') entry.path++; } entry.depth= depth; entry.ignore= 0; if (lstat(path_name(&path), &st) < 0) { if (depth == 0 || errno != ENOENT) { /* Something wrong with this entry, complain about * it and ignore it further. */ entry.ignore= errno; report(path_name(&path)); return &entry; } else { /* Entry strangely nonexistent; simply continue. */ goto recurse; } } /* Don't cross mountpoints if -x is set. */ if (xflag) { if (xdev == NO_DEVICE) xdev= st.st_dev; if (st.st_dev != xdev) { /* Ignore the mountpoint. */ entry.ignore= EXDEV; return &entry; } } entry.mode= st.st_mode & 07777; entry.uid= st.st_uid; entry.gid= st.st_gid; entry.size= st.st_size; entry.mtime= st.st_mtime; entry.rdev= st.st_rdev; linked(&entry, &st); if (S_ISDIR(st.st_mode)) { /* A directory. */ entry.type= F_DIR; /* Gather directory entries for the next traverse. */ if ((newentries= collect(path_name(&path))) == nil && errno != 0) { entry.ignore= errno; report(path_name(&path)); } } else if (S_ISREG(st.st_mode)) { /* A plain file. */ entry.type= F_FILE; } else if (S_ISBLK(st.st_mode)) { /* A block special file. */ entry.type= F_BLK; } else if (S_ISCHR(st.st_mode)) { /* A character special file. */ entry.type= F_CHR; } else if (S_ISFIFO(st.st_mode)) { /* A named pipe. */ entry.type= F_PIPE; } else if (S_ISLNK(st.st_mode)) { /* A symbolic link. */ entry.type= F_LINK; if ((entry.link= rdlink(path_name(&path), st.st_size)) == nil) { entry.ignore= errno; report(path_name(&path)); } } else { /* Unknown type of file. */ entry.ignore= EINVAL; } return &entry; }
entry_t *readstate(void) /* Read one entry from the state file. */ { static entry_t entry; static pathname_t path; static size_t *trunc; static size_t trunc_len; static base_indent; char *line; char **argv; size_t argc; static off_t lineno; int indent, depth; recurse: keep= KEEP_STATE; if (feof(statefp) || (line= read1line(statefp)) == nil) { checkstate(); return nil; } lineno++; /* How far is this entry indented? */ indent= 0; while (*line != 0) { if (*line == ' ') indent++; else if (*line == '\t') indent= (indent + 8) & ~7; else break; line++; } if (indent > 0 && base_indent == 0) base_indent= indent; depth= (base_indent == 0 ? 0 : indent / base_indent) + 1; if (entry.ignore && depth > entry.depth) { /* If the old directory is ignored, then so are its entries. */ goto recurse; } entry.depth= depth; splitline(line, &argv, &argc); if (argc < 2) state_syntax(lineno); if (trunc == nil) { /* The root of the tree, initialize path. */ if (argv[0][0] != '/') state_syntax(lineno); path_init(&path); path_add(&path, "/"); trunc= allocate(nil, (trunc_len= 16) * sizeof(trunc[0])); /* The root has depth 0. */ entry.depth= 0; trunc[0]= 0; } else { if (entry.depth > trunc_len) { trunc= allocate(trunc, (trunc_len*= 2) * sizeof(trunc[0])); } path_trunc(&path, trunc[entry.depth - 1]); path_add(&path, argv[0]); trunc[entry.depth]= path_length(&path); } entry.path= path_name(&path); entry.name= argv[0]; entry.link= nil; if ((entry.ignore= strcmp(argv[1], "ignore") == 0)) { return &entry; } if (!getattributes(&entry, argc - 1, argv + 1)) state_syntax(lineno); return &entry; }
int main() { int i, redirect_bool, pipe_bool, fd_rdr; char **cmd; char **cmmnd; char **pipe_command; char buf[512]; int command_bytes; int pipe_fd[2]; temp_environ = environ; while (1) { char arg[50], mod[50]; fprintf(stdout, "\nflop: "); fflush(stdout); // reset pipe and redirect values pipe_bool = 0; redirect_bool = 0; cmd = (char **)malloc(20*sizeof(char *)); for (i = 0; i < 20; i++) { cmd[i] = (char *) malloc(128); } if ((command_bytes = read(0, buf, 512)) < 0) { fprintf(stdout, "There was an issue reading the command, please try again.\n"); break; } buf[command_bytes] = '\0'; if (parse_cmd(buf, cmd)) { if (strcmp("exit", cmd[0]) == 0) { fprintf(stdout, "Exiting the floppy disk shell... \n"); return EXIT_SUCCESS; } pipe_bool = is_pipe(cmd); redirect_bool = is_redirection(cmd); if (strcmp("path", cmd[0]) == 0) { if (cmd[1]) strcpy(arg,cmd[1]); else strcpy(arg, ""); if (cmd[2]) strcpy(mod,cmd[2]); else strcpy(mod, ""); if ((strchr(arg,'+') == NULL) && (strchr(arg,'-') == NULL)) { path(); continue; } else if (!strcmp("+", arg)) { if(strchr(mod,'#') == NULL){ path_add(mod); strcpy(arg,""); continue; } else { fprintf(stdout, "Error invalid argument, please try again! \n"); continue; } } else if (!strcmp("-", arg)) { if(strchr(mod,'#') == NULL){ path_sub(mod); strcpy(arg,""); continue; } else{ fprintf(stdout, "Error invalid argument, please try again! \n"); } } else { fprintf(stdout, "Error invalid argument, please try again! \n"); } } else if (!strcmp("cd", cmd[0])) { change_dir((const char*)cmd[1]); continue; } if (pipe_bool > 0) { // copy command string to not alter original cmmnd = cmd; // iterate over command to find pipe portion while (*cmmnd != NULL) { if (!strcmp(*cmmnd, "|")) { pipe_command = cmmnd + 1; *cmmnd = NULL; break; } cmmnd++; } // iterate over command string to find redirection portion if (redirect_bool > 0) { cmmnd = pipe_command; while (*cmmnd != NULL) { if (!strcmp(*cmmnd, ">")) { if ((fd_rdr = open(*(cmmnd+1), (O_WRONLY | O_CREAT | O_TRUNC), 0644)) < 0) fprintf(stdout, "There was an error creating file for redirection\n"); *cmmnd = NULL; break; } cmmnd++; } } if (*pipe_command == NULL || pipe_command[0][0] == '\0') { fprintf(stdout, "There was an error in the pipe command\n"); fflush(stdout); continue; } if ((pipe(pipe_fd)) != 0) fprintf(stdout, "There was an error creating the pipe\n"); if ((fork()) == 0) { close(1); dup(pipe_fd[1]); close(pipe_fd[1]); close(pipe_fd[0]); // execute command execve(cmd[0], cmd, NULL); // above command was not found so try path_name environment char* temp = path_name; char *token = strtok(temp,":"); while( token != NULL ) { char envir_arg_pathname[50]; strcpy(envir_arg_pathname, "PATH="); strcpy(envir_arg_pathname, token); char *env_args[] = { envir_arg_pathname, NULL, NULL }; environ = env_args; if((execvp(cmd[0], &cmd[0])) == -1) { token = strtok(NULL, ":"); } else break; } fprintf(stdout, "There was an invalid command in string\n"); } if ((fork()) == 0) { close(0); dup(pipe_fd[0]); close(pipe_fd[0]); close(pipe_fd[1]); if (redirect_bool) { close(1); dup(fd_rdr); close(fd_rdr); } // reset environment environ = temp_environ; // execute pipe execvp(pipe_command[0], pipe_command); // above command was not found so try path_name environment char* temp = path_name; char *token = strtok(temp,":"); while( token != NULL ) { char envir_arg_pathname[50]; strcpy(envir_arg_pathname, "PATH="); strcpy(envir_arg_pathname, token); char *env_args[] = { envir_arg_pathname, NULL, NULL }; environ = env_args; if((execvp(cmd[0], &cmd[0])) == -1) { token = strtok(NULL, ":"); } else break; } fprintf(stdout, "There was an error in pipe command\n"); } close(pipe_fd[0]); close(pipe_fd[1]); wait(NULL); wait(NULL); } else { // pipe was not found if (redirect_bool > 0) { // copy command to not alter original string cmmnd = cmd; // find redirect file name and create file for writing. while (*cmmnd != NULL) { if (!strcmp(*cmmnd, ">")) { if ((fd_rdr = open(*(cmmnd+1), (O_WRONLY | O_CREAT | O_TRUNC), 0644)) < 0) fprintf(stdout, "There was an issue creating redirect file\n"); *cmmnd = NULL; break; } cmmnd++; } } if ((fork()) == 0) { if (redirect_bool) { close(1); dup(fd_rdr); close(fd_rdr); } execve(cmd[0], cmd, NULL); // above command was not found so try path_name environment char* temp; char* token; temp = path_name; token = strtok(path_name,":"); while(token != NULL){ char *slash = "/"; path_name = temp; //add command to end of each path to search strcat(token,slash); strcat(token,cmd[0]); printf("token : %s",token); execl(token,cmd[0],cmd[1],cmd[2],NULL); token = strtok(NULL,":"); } fprintf(stdout, "There was an invalid command in command string.\n"); } if (redirect_bool) close(fd_rdr); wait(NULL); } } free(cmd); } return 0; }