1 /* 2 * Show lines from a file. 3 * 4 * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/sys/err.h> 23 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 28 #include <fsclient/client.h> 29 #include <systypes/env.h> 30 #include <systypes/fcntl.h> 31 32 33 34 /* Read a line from the file. */ 35 36 static int readline(file_t *file, int *lineno, char **start, char **end) 37 { 38 static char buf[256]; 39 static offset_t current = 0, limit = 0; 40 char *newline = NULL; 41 42 do 43 { 44 /* Obtain file content. */ 45 46 if (!limit) 47 { 48 limit = client_read(file, buf, 256); 49 50 if (!limit) 51 { 52 *start = NULL; 53 *end = NULL; 54 return 0; 55 } 56 57 current = 0; 58 59 /* Start of line at start of buffer. */ 60 61 if (newline != NULL) 62 { 63 current += 1; 64 *start = buf; 65 *end = (char *) memchr(buf + current, (int) '\n', limit - current); 66 67 if (*end == NULL) 68 *end = buf + limit; 69 70 return 1; 71 } 72 } 73 74 /* Find newline. */ 75 76 newline = (char *) memchr(buf + current, (int) '\n', limit - current); 77 78 if (newline != NULL) 79 { 80 (*lineno)++; 81 current = newline - (char *) buf + 1; 82 83 /* Start of line before end of buffer. */ 84 85 if (current < limit) 86 { 87 *start = newline + 1; 88 *end = (char *) memchr(buf + current, (int) '\n', limit - current); 89 90 if (*end == NULL) 91 *end = buf + limit; 92 93 return 1; 94 } 95 96 /* Otherwise, reset the buffer to read the start of line. */ 97 98 else 99 limit = 0; 100 } 101 102 /* No newline: read more data. */ 103 104 else 105 limit = 0; 106 } 107 while (1); 108 } 109 110 111 112 int main(int argc, char *argv[]) 113 { 114 file_t *file; 115 int i, startline, numlines; 116 char *start, *end; 117 118 if (argc < 4) 119 return 1; 120 121 file = client_open(argv[1], O_RDONLY); 122 123 if (!client_opened(file)) 124 { 125 if (file != NULL) 126 printf("Error: %s\n", l4sys_errtostr(file->error)); 127 else 128 printf("Could not open file.\n"); 129 130 while (1); 131 } 132 133 startline = atoi(argv[2]); 134 numlines = atoi(argv[3]); 135 136 i = 1; 137 while (i < startline) 138 if (!readline(file, &i, &start, &end)) 139 break; 140 141 while (i < startline + numlines) 142 { 143 fwrite(start, sizeof(char), end - start, stdout); 144 if (!readline(file, &i, &start, &end)) 145 break; 146 } 147 148 fputs("\n\n", stdout); 149 150 client_close(file); 151 client_notifier_close(client_notifier_task()); 152 153 return 0; 154 } 155 156 /* vim: tabstop=2 expandtab shiftwidth=2 157 */