一些指令替换记录

一,替换system直接写入

#include <stdlib.h>
#include <stdio.h>

int main() 
{
    char user_input[100];
    printf("请输入一个字符串: ");
    fgets(user_input, sizeof(user_input), stdin);
    // 去除换行符
    user_input[strcspn(user_input, "\n")] = 0;

    char command[200];
    sprintf(command, "echo \"%s\"", user_input);
    system(command);
    return 0;
}

二,替换tftp

1,tftp.h

#ifndef   _TFTP_H_
#define  _TFTP_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define TFTP_PORT 69
#define BUFFER_SIZE 516
#define DATA_SIZE 512
#define TIMEOUT 5

// TFTP 操作码
#define RRQ 1
#define WRQ 2
#define DATA 3
#define ACK 4
#define ERROR 5

// TFTP 错误码
#define NOT_DEFINED 0
#define FILE_NOT_FOUND 1
#define ACCESS_VIOLATION 2
#define DISK_FULL 3
#define ILLEGAL_OPERATION 4
#define UNKNOWN_TID 5
#define FILE_EXISTS 6
#define NO_SUCH_USER 7

struct tftp_packet 
{
    uint16_t opcode;
    union {
        struct {
            char filename[2];
        } rrq_wrq;
        struct {
            uint16_t block_num;
            char data[DATA_SIZE];
        } data;
        struct {
            uint16_t block_num;
        } ack;
        struct {
            uint16_t error_code;
            char error_msg[2];
        } error;
    };
};




// 打印使用说明
void print_usage(const char *program_name);
// 创建 TFTP 请求包
int create_request_packet(char *buffer, uint16_t opcode, const char *filename, const char *mode);
// 创建数据包
int create_data_packet(char *buffer, uint16_t block_num, const char *data, int data_len);
// 创建 ACK 包
int create_ack_packet(char *buffer, uint16_t block_num);
// 创建错误包
int create_error_packet(char *buffer, uint16_t error_code, const char *error_msg);
// 解析收到的包
int parse_packet(const char *buffer, int len, uint16_t *opcode, uint16_t *block_num, char *data, int *data_len, uint16_t *error_code, char *error_msg) ;


// 下载文件 (GET)
int tftp_get(const char *server, const char *remote_file, const char *local_file); 



// 上传文件 (PUT)
int tftp_put(const char *server, const char *local_file, const char *remote_file);

#endif

2,tftp.c

#include"tftp.h"
// 打印使用说明
void print_usage(const char *program_name)
 {
    printf("Usage: %s [get|put] <remote_filename> [local_filename]\n", program_name);
    printf("Examples:\n");
    printf("  %s get remote.txt local.txt\n", program_name);
    printf("  %s put local.txt remote.txt\n", program_name);
    printf("  %s get remote.txt  (uses same local filename)\n", program_name);
}

// 创建 TFTP 请求包
int create_request_packet(char *buffer, uint16_t opcode, const char *filename, const char *mode) {
    uint16_t *op = (uint16_t *)buffer;
    *op = htons(opcode);
    
    char *ptr = buffer + 2;
    strcpy(ptr, filename);
    ptr += strlen(filename) + 1;
    
    strcpy(ptr, mode);
    ptr += strlen(mode) + 1;
    
    return ptr - buffer;
}

// 创建数据包
int create_data_packet(char *buffer, uint16_t block_num, const char *data, int data_len) {
    uint16_t *op = (uint16_t *)buffer;
    *op = htons(DATA);
    
    uint16_t *block = (uint16_t *)(buffer + 2);
    *block = htons(block_num);
    
    memcpy(buffer + 4, data, data_len);
    
    return data_len + 4;
}

// 创建 ACK 包
int create_ack_packet(char *buffer, uint16_t block_num) {
    uint16_t *op = (uint16_t *)buffer;
    *op = htons(ACK);
    
    uint16_t *block = (uint16_t *)(buffer + 2);
    *block = htons(block_num);
    
    return 4;
}

// 创建错误包
int create_error_packet(char *buffer, uint16_t error_code, const char *error_msg) {
    uint16_t *op = (uint16_t *)buffer;
    *op = htons(ERROR);
    
    uint16_t *error = (uint16_t *)(buffer + 2);
    *error = htons(error_code);
    
    strcpy(buffer + 4, error_msg);
    
    return strlen(error_msg) + 5;
}

// 解析收到的包
int parse_packet(const char *buffer, int len, uint16_t *opcode, uint16_t *block_num, 
                 char *data, int *data_len, uint16_t *error_code, char *error_msg) {
    if (len < 2) return -1;
    
    *opcode = ntohs(*(uint16_t *)buffer);
    
    switch (*opcode) {
        case DATA:
            if (len < 4) return -1;
            *block_num = ntohs(*(uint16_t *)(buffer + 2));
            *data_len = len - 4;
            if (data && *data_len > 0) {
                memcpy(data, buffer + 4, *data_len);
            }
            break;
            
        case ACK:
            if (len < 4) return -1;
            *block_num = ntohs(*(uint16_t *)(buffer + 2));
            break;
            
        case ERROR:
            if (len < 4) return -1;
            *error_code = ntohs(*(uint16_t *)(buffer + 2));
            if (error_msg && len > 4) {
                strncpy(error_msg, buffer + 4, len - 4);
                error_msg[len - 4] = '\0';
            }
            break;
            
        default:
            return -1;
    }
    
    return 0;
}






// 下载文件 (GET)
int tftp_get(const char *server, const char *remote_file, const char *local_file) {
    int sockfd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(server_addr);
    char buffer[BUFFER_SIZE];
    char data_buffer[DATA_SIZE];
    int fd, ret;
    
    // 创建 socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }
    
    // 设置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(TFTP_PORT);
    
    if (inet_pton(AF_INET, server, &server_addr.sin_addr) <= 0) {
        // 尝试解析主机名
        struct hostent *he = gethostbyname(server);
        if (he == NULL) 
        {
            fprintf(stderr, "Error: Cannot resolve hostname '%s'\n", server);
            close(sockfd);
            return -1;
        }
        memcpy(&server_addr.sin_addr, he->h_addr_list[0], he->h_length);
    }
    
    // 创建本地文件
    fd = open(local_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd < 0) {
        perror("open");
        close(sockfd);
        return -1;
    }
    
    // 发送读请求
    int packet_len = create_request_packet(buffer, RRQ, remote_file, "octet");
    ret = sendto(sockfd, buffer, packet_len, 0, 
                (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0) {
        perror("sendto");
        close(fd);
        close(sockfd);
        return -1;
    }
    
    printf("Downloading %s from %s to %s\n", remote_file, server, local_file);
    
    uint16_t expected_block = 1;
    int total_bytes = 0;
    
    // 设置超时
    struct timeval tv;
    tv.tv_sec = TIMEOUT;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    
    while (1) 
  {
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, 
                        (struct sockaddr *)&server_addr, &addr_len);
        if (n < 0) 
       {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                fprintf(stderr, "Timeout waiting for data\n");
                break;
            }
            perror("recvfrom");
            break;
        }
        
        uint16_t opcode, block_num, error_code;
        int data_len;
        char error_msg[256];
        
        if (parse_packet(buffer, n, &opcode, &block_num, data_buffer, &data_len, 
                        &error_code, error_msg) < 0) 
        {
            fprintf(stderr, "Error: Invalid packet received\n");
            break;
        }
        
        if (opcode == ERROR) 
        {
            fprintf(stderr, "TFTP Error %d: %s\n", error_code, error_msg);
            break;
        }
        
        if (opcode == DATA) {
            if (block_num == expected_block) {
                // 写入数据
                write(fd, data_buffer, data_len);
                total_bytes += data_len;
                
                // 发送 ACK
                packet_len = create_ack_packet(buffer, block_num);
                sendto(sockfd, buffer, packet_len, 0, 
                      (struct sockaddr *)&server_addr, sizeof(server_addr));
                
                printf("\rReceived %d bytes...", total_bytes);
                fflush(stdout);
                
                // 检查是否结束
                if (data_len < DATA_SIZE) {
                    printf("\nDownload completed: %d bytes\n", total_bytes);
                    break;
                }
                
                expected_block++;
            } else if (block_num == expected_block - 1) {
                // 重复包,重新发送 ACK
                packet_len = create_ack_packet(buffer, block_num);
                sendto(sockfd, buffer, packet_len, 0, 
                      (struct sockaddr *)&server_addr, sizeof(server_addr));
            }
        }
    }
    
    close(fd);
    close(sockfd);
    return total_bytes > 0 ? 0 : -1;
}























// 上传文件 (PUT)
int tftp_put(const char *server, const char *local_file, const char *remote_file) {
    int sockfd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(server_addr);
    char buffer[BUFFER_SIZE];
    char data_buffer[DATA_SIZE];
    int fd, ret;
    
    // 创建 socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }
    
    // 设置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(TFTP_PORT);
    
    if (inet_pton(AF_INET, server, &server_addr.sin_addr) <= 0) {
        struct hostent *he = gethostbyname(server);
        if (he == NULL) {
            fprintf(stderr, "Error: Cannot resolve hostname '%s'\n", server);
            close(sockfd);
            return -1;
        }
        memcpy(&server_addr.sin_addr, he->h_addr_list[0], he->h_length);
    }
    
    // 打开本地文件
    fd = open(local_file, O_RDONLY);
    if (fd < 0) {
        perror("open");
        close(sockfd);
        return -1;
    }
    
    // 发送写请求
    int packet_len = create_request_packet(buffer, WRQ, remote_file, "octet");
    ret = sendto(sockfd, buffer, packet_len, 0, 
                (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0) {
        perror("sendto");
        close(fd);
        close(sockfd);
        return -1;
    }
    
    printf("Uploading %s to %s as %s\n", local_file, server, remote_file);
    
    uint16_t current_block = 0;
    int total_bytes = 0;
    int bytes_read;
    
    // 设置超时
    struct timeval tv;
    tv.tv_sec = TIMEOUT;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    
    while (1) {
        // 等待 ACK
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, 
                        (struct sockaddr *)&server_addr, &addr_len);
        if (n < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                fprintf(stderr, "Timeout waiting for ACK\n");
                break;
            }
            perror("recvfrom");
            break;
        }
        
        uint16_t opcode, block_num, error_code;
        char error_msg[256];
        
        if (parse_packet(buffer, n, &opcode, &block_num, NULL, NULL, 
                        &error_code, error_msg) < 0) {
            fprintf(stderr, "Error: Invalid packet received\n");
            break;
        }
        
        if (opcode == ERROR) {
            fprintf(stderr, "TFTP Error %d: %s\n", error_code, error_msg);
            break;
        }
        
        if (opcode == ACK) {
            if (block_num == current_block) {
                current_block++;
                
                // 读取文件数据
                bytes_read = read(fd, data_buffer, DATA_SIZE);
                if (bytes_read < 0) {
                    perror("read");
                    break;
                }
                
                total_bytes += bytes_read;
                
                // 发送数据包
                packet_len = create_data_packet(buffer, current_block, data_buffer, bytes_read);
                ret = sendto(sockfd, buffer, packet_len, 0, 
                            (struct sockaddr *)&server_addr, sizeof(server_addr));
                if (ret < 0) {
                    perror("sendto");
                    break;
                }
                
                printf("\rSent %d bytes...", total_bytes);
                fflush(stdout);
                
                // 检查是否结束
                if (bytes_read < DATA_SIZE) {
                    // 等待最后一个 ACK
                    n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, 
                                (struct sockaddr *)&server_addr, &addr_len);
                    if (n > 0) {
                        parse_packet(buffer, n, &opcode, &block_num, NULL, NULL, 
                                    &error_code, error_msg);
                        if (opcode == ACK && block_num == current_block) {
                            printf("\nUpload completed: %d bytes\n", total_bytes);
                        }
                    }
                    break;
                }
            }
        }
    }
    
    close(fd);
    close(sockfd);
    return total_bytes > 0 ? 0 : -1;
}

3,main.c

#include"tftp.h"
int main(int argc, char *argv[]) 
{
    if (argc < 4) 
    {
        print_usage(argv[0]);
        return 1;
    }
    
    const char *operation = argv[1];
    const char *remote_file = argv[2];
    const char *local_file = (argc > 3) ? argv[3] : remote_file;
    
    // 从环境变量获取服务器地址,默认为 localhost
    const char *server = getenv("TFTP_SERVER");
    if (server == NULL) 
   {
        server = "127.0.0.1";
    }
    
    if (strcmp(operation, "get") == 0) 
    {
       // return tftp_get(server, remote_file, local_file);
	   printf("+++%d\n",tftp_get(server, remote_file, local_file));
    } 
    else if (strcmp(operation, "put") == 0) 
    {
      //  return tftp_put(server, local_file, remote_file);
	    printf("---%d\n",tftp_put(server, local_file, remote_file) );
    } 
    else 
    {
        fprintf(stderr, "Error: Unknown operation '%s'\n", operation);
        print_usage(argv[0]);
        return 1;
    }
    
    return 0;
}

 ./mytftp
Usage: ./mytftp [get|put] <remote_filename> [local_filename]
Examples:
  ./mytftp get remote.txt local.txt
  ./mytftp put local.txt remote.txt
  ./mytftp get remote.txt  (uses same local filename)
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒听雪落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值