str_list* get_file_list(char *dir_name) { str_list dir_list = {" ", NULL}, file_list = {" ", NULL}; char *path; DIR *dir; struct dirent *dp; int dir_length = strlen(dir_name); if (dir_length <= 0) { return NULL; } dir = opendir(dir_name); if (dir == NULL) return NULL; for (dp = readdir(dir); dp != NULL; dp = readdir(dir)) { if (dp->d_name[0] == '.') { continue; } path = malloc(dir_length + 1 + strlen(dp->d_name) + 1); sprintf(path, "%s/%s", dir_name, dp->d_name); int file_type = is_reg_file(path); if (file_type == 1) { strlist_add_sort(&file_list, dp->d_name); } else if (file_type == 0) { strlist_add_sort(&dir_list, dp->d_name); } free(path); } closedir(dir); if (strlist_length(dir_list.next) > 0) { strlist_last(dir_list.next)->next = file_list.next; } else { dir_list.next = file_list.next; } return dir_list.next; }
int print_dir_entries(char *dir_name) { int dir_name_length = strlen(dir_name), item_length = 0; char *path = NULL; char *escaped_path = NULL; str_list *list = get_file_list(dir_name); struct DESKTOP_ENTRY data = { APPLICATION, NULL, NULL, NULL, NULL, NULL, true }; if (dir_name == NULL || list == NULL) return 1; str_list *item = list; while (item != NULL) { item_length = strlen(item->str); path = realloc(path, dir_name_length + 1 + item_length + 1); sprintf(path, "%s/%s", dir_name, item->str); switch (is_reg_file(path)) { case 1: if (get_data(&data, path)) { if (data.type == LINK) { printf( "<item\n" " label=\"%s\"\n" " icon=\"" PAGE_ICON "\">\n" " <action name=\"Execute\">\n" " <execute>%s "%s"</execute>\n" " </action>\n" "</item>\n", data.name, g_browser_name, data.url ); } else if (data.type == APPLICATION) { printf( "<item\n" ); if (data.comment != NULL) { printf( " label=\"%s (%s)\"\n", data.name, data.comment ); } else { printf( " label=\"%s\"\n", data.name ); } printf( " icon=\"%s/%s.png\">\n" " <action name=\"Execute\">\n", g_icon_dir, data.icon ); if (data.has_gui) { printf( " <execute>%s</execute>\n", data.command ); } else { printf( " <execute>urxvt -icon "%s/%s.png" -title "%s" -e "%s"</execute>\n", g_icon_dir, data.command, data.command, data.command ); } printf( " </action>\n" "</item>\n" ); } } reset_data(&data); break; case 0: /* if the path represents a directory */ escaped_path = escape_space(path); printf( "<menu\n" " icon=\"" CATEGORY_ICON "\"\n" " id=\"%s\"\n" " label=\"%s\"\n" " execute=\"%s -d%s -b%s -f%s -i%s\" />\n", item->str, item->str, g_cmd_name, escaped_path, g_browser_name, g_filer_name, g_icon_dir ); free(escaped_path); break; } item = item->next; } strlist_free(list); free(path); return 0; }
int print_dir_entries(MINODE *mip) { int i; char *cp; char sbuf[BLKSIZE], temp[256], buf2[BLKSIZE], *t1 = "xwrxwrxwr-------", *t2 = "----------------"; ip = &(mip->INODE); int inode_start_block = ip->i_blocks; for (i=0; i<12; i++) // ASSUME DIRs only has 12 direct blocks { if (ip->i_block[i] == 0) return 0; get_block(mip->dev,ip->i_block[i], sbuf); dp = (DIR *)sbuf; cp = sbuf; printf(CYAN); while (cp < sbuf + BLKSIZE) { // Get name strncpy(temp, dp->name, dp->name_len); temp[dp->name_len] = 0; // Dir entry mip = iget(mip->dev, dp->inode); // Entry type printf("\t\t|%4d ", mip->ino); if(is_dir_file(mip)) printf("d"); else if(is_reg_file(mip)) printf("-"); else printf("l"); // Permissions for (i = 8; i >= 0; i--) { if (mip->INODE.i_mode & (1 << i)) printf("%c", t1[i]); else printf("%c", t2[i]); } // Ref count printf("%3d", mip->INODE.i_links_count); // User ID printf("%3d", mip->INODE.i_uid); // Grpup ID printf("%3d", mip->INODE.i_gid); // Size printf("%9d", mip->INODE.i_size); // Time printf("%9d", mip->INODE.i_atime); // Name printf("%20s", temp); // If symbolic, print it's link location if(!is_dir_file(mip) && !is_reg_file(mip)) { get_block(running->cwd->dev, mip->INODE.i_block[0], buf); printf(" -> '%s'", buf); } printf("\n"); // Write minode back mip->dirty = 1; iput(mip); // Grab next inode int inode_block_number = (dp->inode - 1) / 8 + inode_start_block; int inode_remainder = (dp->inode - 1) % 8; get_block(mip->dev, inode_block_number, buf2); ip = (INODE *) buf2 + inode_remainder; // Move to next entry cp += dp->rec_len; dp = (DIR *)cp; } printf(RESET); } return 0; }
int open_file() { char *pathname; int file_use_mode, dev, ino; MINODE *mip; // Get pathname and use mode printf(">> ENTER pathname: "); //.. pathname printf(">> ENTER use mode (0 = Read; 1 = Write; 2 = Read-write; 3 = Append): "); //.. file_use_mode // Get pathname's ino if(pathname[0] == '/') dev = root->dev; else dev = running->cwd->dev; ino = getino(dev, pathname); // Get its mip mip = iget(dev, ino); // Check if regular file is_reg_file(mip); // Check if we have the right permissions do_have_permissions(mip, mip->INODE.i_uid); print("\t...Good: File is regular and you have permissions.\n"); // Check if file already opened for W, RW, APPEND : reject. Otherwise (R), accept /// TODO // Allocate free Open File Table (OFT) /* 1. ask for a pathname and mode to open: You may use mode = 0|1|2|3 for R|W|RW|APPEND 2. get pathname's inumber: if (pathname[0]=='/') dev = root->dev; // root INODE's dev else dev = running->cwd->dev; ino = getino(&dev, pathname); // NOTE: dev may change with mounting 3. get its Minode pointer mip = iget(dev,ino); 4. check mip->INODE.i_mode to verify it's a REGULAR file and permission OK. Check whether the file is ALREADY opened with INCOMPATIBLE mode: If it's already opened for W, RW, APPEND : reject. (that is, only multiple R are OK) 5. allocate a FREE OpenFileTable (OFT) and fill in values: oftp->mode = mode; // mode = 0|1|2|3 for R|W|RW|APPEND oftp->refCount = 1; oftp->minodePtr = mip; // point at the file's minode[] 6. Depending on the open mode 0|1|2|3, set the OFT's offset accordingly: switch(mode){ case 0 : oftp->offset = 0; // R: offset = 0 break; case 1 : truncate(mip); // W: truncate file to 0 size oftp->offset = 0; break; case 2 : oftp->offset = 0; // RW: do NOT truncate file break; case 3 : oftp->offset = mip->INODE.i_size; // APPEND mode break; default: printf("invalid mode\n"); return(-1); } 7. find the SMALLEST i in running PROC's fd[ ] such that fd[i] is NULL Let running->fd[i] point at the OFT entry 8. update INODE's time field for R: touch atime. for W|RW|APPEND mode : touch atime and mtime mark Minode[ ] dirty 9. return i as the file descriptor */ return EXIT_SUCCESS; }