1// 2// A simple symlink test 3// 4 5#define _GNU_SOURCE 6 7#include <sys/stat.h> 8#include <unistd.h> 9#include <stdlib.h> 10#include <errno.h> 11#include <stdio.h> 12#include <string.h> 13 14// 15// Creates symlink [new-path] to [old-path], checks it, 16// returnes 0 - if everything looks fine and 17// 1 - otherwise. 18// mongo_slinks reads arguments from stdin. 19 20int main(int argc, char *argv[]) 21{ 22 char *old_path; 23 char *new_path; 24 25 struct stat statbuf; 26 27 int num; 28 char *buffer = NULL; 29 char *line_buffer = NULL; 30 size_t line_buffer_size = 0; 31 int size = 1; 32 33 if ((buffer = malloc(size + 1)) == NULL) { 34 perror("checklink: malloc failed"); 35 return 1; 36 } 37 38 while (getline(&line_buffer, &line_buffer_size, stdin) != -1) { 39 40 old_path = strtok(line_buffer, "\t "); 41 new_path = strtok(NULL, "\t\n "); 42 43 if (!old_path || !new_path) /* empty lines at the end of file */ 44 break; 45 46 // Create symlink 47 if (symlink(old_path, new_path) != 0) { 48 perror("checklink : symlink failed "); 49 return 1; 50 } 51 // stat data of symlink itself 52 if (lstat(new_path, &statbuf) == -1) { 53 perror("checklink: lstat failed"); 54 return 1; 55 } 56 57 if (!(S_ISLNK(statbuf.st_mode))) { 58 printf("checklink : file %s is not a symbol link\n", 59 new_path); 60 return 1; 61 } 62 // Test readlink 63 // 64 // Increase size of buffer to readlink untile whole symlink body will be read. 65 // Check readlink result on every iteration. 66 67 while (1) { 68 memset(buffer, 0, size + 1); 69 num = readlink(new_path, buffer, size); 70 if (num < 1 || num > size) { 71 perror("checklink: readlink failed"); 72 free(buffer); 73 return 1; 74 } 75 // Make sure that readlink did not break things 76 if (buffer[num] != 0) { 77 printf 78 ("checklink : readlink corrupts memory\n"); 79 free(buffer); 80 return 1; 81 } 82 // Whole expected symlink body is read 83 if (num < size) 84 break; 85 86 // Only part of symlink body was read. So we make a bigger buffer 87 // and call `readlink' again. 88 size *= 2; 89 if ((buffer = realloc(buffer, size + 1)) == NULL) { 90 perror("checklink: realloc failed"); 91 return 1; 92 } 93 } 94 } 95 free(buffer); 96 free(line_buffer); 97 return 0; 98} 99