Beispiel #1
0
int
main(int argc, char **argv)
{
    struct mbr_partition ppp;
    size_t bootsize;
    int c;
    int boot00[512/sizeof(int)];
    int devfd = -1;
    char *bp;

    while ((c = getopt(argc, argv, "vn")) != EOF) {
        switch (c) {
        case 'n':
            nowrite = 1;
            break;
        case 'v':
            verbose = 1;
            break;
        default:
            usage();
            break;
        }
    }

    if (argc - optind < 2)
        usage();

    boot = argv[optind];
    dev = argv[optind + 1];
    if (verbose) {
        printf("boot: %s\n", boot);
        printf("dev: %s\n", dev);
    }

    if ((bp = load_boot(boot, &bootsize)) == NULL)
        return 1;

    if ((devfd = open(dev, O_RDONLY, 0)) < 0) {
        warn("open: %s", dev);
        goto out;
    }

    if (load_prep_partition(devfd, &ppp)) {
        warn("load_prep_partition");
        goto out;
    }

    if (bootsize + dbtob(2) > dbtob(ppp.mbrp_size)) {
        warn("boot image is too big.");
        goto out;
    }

    close(devfd);

    if (nowrite) {
        free(bp);
        return 0;
    }

    if ((devfd = open(dev, O_RDWR, 0)) < 0) {
        warn("open: %s", dev);
        goto out;
    }

    /*
     * Write boot image.
     */
    memset(boot00, 0, sizeof(boot00));
    (void)lseek(devfd, (off_t)dbtob(ppp.mbrp_start), SEEK_SET);
    if (write(devfd, boot00, sizeof(boot00)) != sizeof(boot00)) {
        warn("write boot00(prep mbr)");
        goto out;
    }

    (void)lseek(devfd, (off_t)dbtob(ppp.mbrp_start+1), SEEK_SET);
    boot00[0] = htole32(dbtob(2));
    boot00[1] = htole32(bootsize);
    if (write(devfd, boot00, sizeof(boot00)) != sizeof(boot00)) {
        warn("write boot00(prep start/size)");
        goto out;
    }

    if (devread(devfd, boot00, 1, DEV_BSIZE, "start/size") != 0)
        goto out;
    boot00[0] = htole32(dbtob(ppp.mbrp_start));
    boot00[1] = htole32(bootsize + dbtob(2));
    (void)lseek(devfd, (off_t)dbtob(1), SEEK_SET);
    if (write(devfd, boot00, sizeof(boot00)) != sizeof(boot00)) {
        warn("write boot00(master start/size)");
        goto out;
    }

    (void)lseek(devfd, (off_t)dbtob(ppp.mbrp_start+2), SEEK_SET);
    if (write(devfd, bp, bootsize) != bootsize) {
        warn("write boot loader");
        goto out;
    }

    close(devfd);
    free(bp);
    return 0;

out:
    if (devfd >= 0)
        close(devfd);
    if (bp != NULL)
        free(bp);
    return 1;
}
Beispiel #2
0
/*
 * Main program
 */
int main(int argc, char **argv) {
    int sock_fd, serv_len, n;
    struct sockaddr_in serv_addr;
    struct hostent *serv;

    struct {
        char message[BUFFER];
        int uuid;
    } msg_in, msg_out;

    /* Generate a random UUID */
    srand(time(NULL));
    uuid = rand();

    clearScreen();

    char *input;
    command *cmd;
    size_t buffer = BUFFER;
    while (TRUE) {
        /* Display prompt */
        printPrompt();

        /* malloc input to memory */
        input = (char *)malloc(sizeof(char) * BUFFER);

        /* Clear msg_in and msg_out */
        bzero((char *)msg_in.message, sizeof(msg_in.message));
        bzero((char *)msg_out.message, sizeof(msg_out.message));
        msg_in.uuid = -1;
        msg_out.uuid = uuid;

        /* Get input */
        getline(&input, &buffer, stdin);
        input[strcspn(input, "\n")] = '\0'; //Remove trailing '\n'

        /* Create command */
        cmd = new_command(input);

        /* Output redirection */
        int file_out, con_out;
        if (cmd->output_file) {
            file_out = open(cmd->output_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
            if (file_out < 0) {
                perror("open");
                break;
            }
            con_out = dup(STDOUT_FILENO);
            dup2(file_out, STDOUT_FILENO);
            close(file_out);
        }

        /* Execute user command if possible */
        switch (check_command(cmd->name)) {
            case HELP: //help
                printHelp();
                break;
            case FMOUNT: //fmount
                if (serv_uuid != -1) {
                    printf("[ERROR] You are already connected to a server\n");
                    break;
                }
                if (cmd->argc != 2) {
                    printf("[ERROR] Usage: fmount <server>\n");
                    break;
                }

                printf("Connecting to `%s`... ", cmd->argv[1]);
                fflush(stdout); //Safety precaution

                /* Parse server */
                serv = gethostbyname(cmd->argv[1]);

                /* Open UDP socket */
                sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                if (sock_fd < 0) {
                    perror("socket");
                    break;
                }

                /* Write zero's to serv_addr */
                bzero((char *)&serv_addr, sizeof(serv_addr));

                /* Set up server */
                serv_addr.sin_family = AF_INET;
                bcopy(serv->h_addr, (char *)&serv_addr.sin_addr, serv->h_length);
                serv_addr.sin_port = htons(PORT);
                serv_len = sizeof(serv_addr);

                /* Send CONNECT command to server */
                sprintf(msg_out.message, "CONNECT");
                n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                if (n < 0) {
                    perror("sendto");
                    break;
                }

                /* Get response from server */
                n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                if (n < 0) {
                    perror("recvfrom");
                    break;
                }

                if (strcmp(msg_in.message, "CONNECT") != 0) {
                    printf("[ERROR] Invalid response from server\n");
                    break;
                }

                /* Save server UUID */
                serv_uuid = msg_in.uuid;

                /* Clear msg_in and msg_out */
                bzero((char *)&msg_out.message, sizeof(msg_out.message));
                bzero((char *)&msg_in.message, sizeof(msg_in.message));
                msg_out.uuid = uuid;
                msg_in.uuid = -1;

                /* Get SECTOR 0 from server */
                sprintf(msg_out.message, "GETSECTOR 0");
                n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                if (n < 0) {
                    perror("sendto");
                    break;
                }

                /* Get response from server */
                n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                if (n < 0) {
                    perror("recvfrom");
                    break;
                }

                /* Load bytes into Fat12Boot */
                load_boot((unsigned char *)msg_in.message);

                /* malloc Fat12Entry */
                entry = (Fat12Entry *)malloc(sizeof(Fat12Entry) * boot.MAX_ROOT_DIRS);

                /* Request all ROOT_DIRECTORY sector entries */
                for (int i = 0; i < 14; i++) {
                    /* Clear msg_in and msg_out */
                    bzero((char *)&msg_out.message, sizeof(msg_out.message));
                    bzero((char *)&msg_in.message, sizeof(msg_in.message));
                    msg_out.uuid = uuid;
                    msg_in.uuid = -1;

                    /* Get ROOT DIRECTORY sector from server */
                    sprintf(msg_out.message, "GETSECTOR %d", ((boot.NUM_OF_FATS * boot.SECTORS_PER_FAT) + 1) + i);
                    n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                    if (n < 0) {
                        perror("sendto");
                        break;
                    }

                    /* Get response from server */
                    n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                    if (n < 0) {
                        perror("recvfrom");
                        break;
                    }

                    /* Load bytes into Fat12Entry */
                    load_entry(16 * i, (unsigned char *)msg_in.message);
                }

                printf("Connected!\n");
                break;

            case FUMOUNT: //fumount
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to any server\n");
                    break;
                }
                if (cmd->argc != 1) {
                    printf("[ERROR] Usage: fumount\n");
                    break;
                }

                sprintf(msg_out.message, "DISCONNECT");
                n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                if (n < 0) {
                    perror("sendto");
                    break;
                }

                /* Close and write zero's to server */
                close(sock_fd);
                bzero((char *)&serv_addr, sizeof(serv_addr));
                serv_uuid = -1;
                break;

            case STRUCTURE: //structure
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to any server\n");
                    break;
                }
                if (cmd->argc > 2) {
                    printf("[ERROR] Usage: structure [-l]\n");
                    break;
                } else if (cmd->argc == 2) {
                    if (strcmp(cmd->argv[1], "-l") != 0) {
                        printf("[ERROR] Usage: structure [-l]\n");
                        break;
                    }
                }

                printf("        number of FAT:                      %d\n", boot.NUM_OF_FATS);
                printf("        number of sectors used by FAT:      %d\n", boot.SECTORS_PER_FAT);
                printf("        number of sectors per cluster:      %d\n", boot.SECTORS_PER_CLUSTER);
                printf("        number of ROOT Entries:             %d\n", boot.MAX_ROOT_DIRS);
                printf("        number of bytes per sector          %d\n", boot.BYTES_PER_SECTOR);
                if (cmd->argc == 2) {
                    printf("        ---Sector #---      ---Sector Types---\n");
                    printf("             0                    BOOT\n");
                    for (int i = 0; i < boot.NUM_OF_FATS; i++)
                        printf("          %02d -- %02d                FAT%d\n", (boot.SECTORS_PER_FAT * i) + 1, boot.SECTORS_PER_FAT * (i + 1), i);

                    printf("          %02d -- %02d                ROOT DIRECTORY\n", boot.SECTORS_PER_FAT * boot.NUM_OF_FATS, (boot.MAX_ROOT_DIRS / 16) + (boot.SECTORS_PER_FAT * boot.NUM_OF_FATS));
                }
                break;

            case TRAVERSE: //traverse
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to any server\n");
                    break;
                }
                if (cmd->argc > 2) {
                    printf("[ERROR] Usage: traverse [-l]\n");
                    break;
                } else if (cmd->argc == 2) {
                    if (strcmp(cmd->argv[1], "-l") != 0) {
                        printf("[ERROR] Usage: traverse [-l]\n");
                        break;
                    }
                }

                if (cmd->argc == 2) {
                    printf("    *****************************\n");
                    printf("    ** FILE ATTRIBUTE NOTATION **\n");
                    printf("    **                         **\n");
                    printf("    ** R ------ READ ONLY FILE **\n");
                    printf("    ** S ------ SYSTEM FILE    **\n");
                    printf("    ** H ------ HIDDEN FILE    **\n");
                    printf("    ** A ------ ARCHIVE FILE   **\n");
                    printf("    *****************************\n");
                    printf("\n");

                    for (int i = 0; i < boot.MAX_ROOT_DIRS; i++) {
                        if (entry[i].FILENAME[0] != 0x00 && entry[i].START_CLUSTER != 0) {
                            char attr[6] = {'-', '-', '-', '-', '-'};
                            unsigned char a = entry[i].ATTRIBUTES[0];
                            if (a == 0x01)
                                attr[0] = 'R';
                            if (a == 0x02)
                                attr[1] = 'H';
                            if (a == 0x04)
                                attr[2] = 'S';
                            if (a == 0x20)
                                attr[5] = 'A';
                            if (a == 0x10) {
                                for (int j = 0; j < 6; j++)
                                    attr[j] = '-';
                            }

                            if (entry[i].ATTRIBUTES[0] == 0x10) {
                                printf("%.6s    %d %d       < DIR >      /%.8s                 %d\n", attr, entry[i].CREATION_DATE, entry[i].CREATION_TIME, entry[i].FILENAME, entry[i].START_CLUSTER);
                                printf("%.6s    %d %d       < DIR >      /%.8s/.                 %d\n", attr, entry[i].CREATION_DATE, entry[i].CREATION_TIME, entry[i].FILENAME, entry[i].START_CLUSTER);
                                printf("%.6s    %d %d       < DIR >      /%.8s/..                 %d\n", attr, entry[i].CREATION_DATE, entry[i].CREATION_TIME, entry[i].FILENAME, 0);
                            } else {
                                printf("%.6s    %d %d       %lu      /%.8s.%.3s                 %d\n", attr, entry[i].CREATION_DATE, entry[i].CREATION_TIME, entry[i].FILE_SIZE, entry[i].FILENAME, entry[i].EXT, entry[i].START_CLUSTER);
                            }
                        }
                    }
                } else {
                    for (int i = 0; i < boot.MAX_ROOT_DIRS; i++) {
                        if (entry[i].FILENAME[0] != 0x00 && entry[i].START_CLUSTER != 0) {
                            if (entry[i].ATTRIBUTES[0] == 0x10) {
                                printf("/%.8s                       < DIR >\n", entry[i].FILENAME);
                                printf("/%.8s/.                     < DIR >\n", entry[i].FILENAME);
                                printf("/%.8s/..                    < DIR >\n", entry[i].FILENAME);
                            } else {
                                printf("/%.8s.%.3s\n", entry[i].FILENAME, entry[i].EXT);
                            }
                        }
                    }
                }
                break;

            case SHOWFAT: //showfat
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to any server\n");
                    break;
                }
                if (cmd->argc != 1) {
                    printf("[ERROR] Usage: showfat\n");
                    break;
                }

                int sectors = (boot.NUM_OF_FATS * boot.SECTORS_PER_FAT);
                int count = 0;
                printf("        0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f\n");

                /* Send GETSECTOR command to server */
                for (int i = 1; i <= sectors; i++) {
                    sprintf(msg_out.message, "GETSECTOR %d", i);
                    n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                    if (n < 0) {
                        perror("sendto");
                        break;
                    }

                    /* Get response from server */
                    n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                    if (n < 0) {
                        perror("sendto");
                        break;
                    }

                    /* Check server UUID */
                    if (serv_uuid != msg_in.uuid) {
                        printf("[ERROR] Invalid server UUID - Connection rejected\n");
                        break;
                    }

                    for (int j = 0; j < boot.BYTES_PER_SECTOR; j++) {
                        if (count % 16 == 0 || count == 0) {
                            printf("\n");
                            printf("%4x", count);
                        }
                        printf("%5x", (unsigned char)msg_in.message[j]);
                        count++;
                    }
                }
                printf("\n");
                break;

            case SHOWSECTOR: //showsector
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to any server\n");
                    break;
                }
                if (cmd->argc != 2) {
                    printf("[ERROR] Usage: showsector <sector>\n");
                    break;
                }

                /* Parse sector */
                int sector = atoi(cmd->argv[1]);

                /* Send GETSECTOR command to server */
                sprintf(msg_out.message, "GETSECTOR %d", sector);
                n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                if (n < 0) {
                    perror("sendto");
                    break;
                }

                /* Get response from server */
                n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                if (n < 0) {
                    perror("recvfrom");
                    break;
                }

                /* Check for valid server UUID */
                if (serv_uuid != msg_in.uuid) {
                    printf("[ERROR] Invalid server UUID - Connection rejected\n");
                    break;
                }

                /* Read response */
                printf("        0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f\n");
                for (int i = 0; i < boot.BYTES_PER_SECTOR; i++) {
                    if (i % 16 == 0 || i == 0) {
                        printf("\n");
                        printf("%4x", i);
                    }
                    printf("%5x", (unsigned char)msg_in.message[i]);
                }
                printf("\n");
                break;

            case SHOWFILE: //showfile
                if (serv_uuid == -1) {
                    printf("[ERROR] You are not connected to a server\n");
                    break;
                }
                if (cmd->argc != 2) {
                    printf("[ERROR] Usage: showfile <filename>\n");
                    break;
                }

                char filename[12] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' , '\0'};

                int index = 0, k;
                for (k = 0; k < strlen(cmd->argv[1]) && k < 9; k++) {
                    if (cmd->argv[1][k] == '.') {
                        k++;
                        break;
                    }
                    filename[index] = cmd->argv[1][k];
                    index++;
                }

                index = 8;
                for (int j = k; j < strlen(cmd->argv[1]) && j < 12; j++) {
                    if (cmd->argv[1][j] == '\n' || cmd->argv[1][j] == '\0') {
                        break;
                    }
                    filename[index] = cmd->argv[1][j];
                    index++;
                }

                for (int i = 0; i < boot.MAX_ROOT_DIRS; i++) {
                    if (entry[i].FILENAME != 0x00 && entry[i].START_CLUSTER != 0) {
                        if (compare_char(filename, (char *)entry[i].FILENAME)) {
                            int sector = ((boot.MAX_ROOT_DIRS / 16) + (boot.SECTORS_PER_FAT * boot.NUM_OF_FATS) - 1) + entry[i].START_CLUSTER;
                            int size = (entry[i].FILE_SIZE / 512) + 1;
                            int count = 0;

                            printf("        0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f\n");
                            for (int p = sector; p <= sector + size + 1; p++) {
                                sprintf(msg_out.message, "GETSECTOR %d", p);
                                n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                                if (n < 0) {
                                    perror("sendto");
                                    break;
                                }

                                n = recvfrom(sock_fd, &msg_in, sizeof(msg_in), 0, (struct sockaddr *)&serv_addr, (socklen_t *)&serv_len);
                                if (n < 0) {
                                    perror("recvfrom");
                                    break;
                                }

                                if (serv_uuid != msg_in.uuid) {
                                    printf("[ERROR] Invalid server UUID - Connection reject\n");
                                    break;
                                }

                                for (int j = 0; j < boot.BYTES_PER_SECTOR; j++) {
                                    if (j % 16 == 0 || j == 0) {
                                        printf("\n");
                                        printf("%4x", count++);
                                    }
                                    printf("%5x", (unsigned char)msg_in.message[j]);
                                }
                            }
                            printf("\n");
                        }
                    }
                }
                break;

            case EXIT: //exit
                free(input);
                delete_command(cmd);

                if (serv_uuid != -1) {
                    /* Send DISCONNECT command to server */
                    sprintf(msg_out.message, "DISCONNECT");
                    n = sendto(sock_fd, &msg_out, sizeof(msg_out), 0, (struct sockaddr *)&serv_addr, (socklen_t)serv_len);
                    if (n < 0) {
                        perror("sendto");
                        exit(EXIT_FAILURE);
                    }

                    close(sock_fd);
                    bzero((char *)&serv_addr, sizeof(serv_addr));
                    serv_uuid = -1;
                }
                exit(EXIT_SUCCESS);

            case INVALID_CMD: //Invalid command (default)
                printf("[ERROR] %s: Command not found\n", cmd->name);
                break;
        }

        fflush(stdout); //Safety precaution

        /* Restore output */
        if (cmd->output_file) {
            dup2(con_out, STDOUT_FILENO);
            close(con_out);
        }

        /* Free memory */
        free(input);
        delete_command(cmd);
    }
}