Imported from ../bash-2.05a.tar.gz.
[platform/upstream/bash.git] / examples / loadables / head.c
1 /* head - copy first part of files. */
2
3 /* See Makefile for compilation details. */
4
5 #include "config.h"
6
7 #include "bashtypes.h"
8 #include "posixstat.h"
9 #include "filecntl.h"
10
11 #if defined (HAVE_UNISTD_H)
12 #  include <unistd.h>
13 #endif
14
15 #include "bashansi.h"
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include "chartypes.h"
20
21 #include "builtins.h"
22 #include "shell.h"
23 #include "bashgetopt.h"
24
25 #if !defined (errno)
26 extern int errno;
27 #endif
28
29 static void
30 munge_list (list)
31      WORD_LIST *list;
32 {
33   WORD_LIST *l, *nl;
34   WORD_DESC *wd;
35   char *arg;
36
37   for (l = list; l; l = l->next)
38     {
39       arg = l->word->word;
40       if (arg[0] != '-' || arg[1] == '-' || (DIGIT(arg[1]) == 0))
41         return;
42       /* We have -[0-9]* */
43       wd = make_bare_word (arg+1);
44       nl = make_word_list (wd, l->next);
45       l->word->word[1] = 'n';
46       l->word->word[2] = '\0';
47       l->next = nl;
48       l = nl;   /* skip over new argument */
49     }
50 }
51
52 static int
53 file_head (fp, cnt)
54      FILE *fp;
55      int cnt;
56 {
57   int ch;
58
59   while (cnt--)
60     {
61       while ((ch = getc (fp)) != EOF)
62         {
63           if (putchar (ch) == EOF)
64             {
65               builtin_error ("write error: %s", strerror (errno));
66               return EXECUTION_FAILURE;
67             }
68           if (ch == '\n')
69             break;
70         }
71     }
72 }
73
74 head_builtin (list)
75      WORD_LIST *list;
76 {
77   int nline, opt, rval;
78   WORD_LIST *l;
79   FILE *fp;
80
81   char *t;
82
83   munge_list (list);    /* change -num into -n num */
84
85   reset_internal_getopt ();
86   nline = 10;
87   while ((opt = internal_getopt (list, "n:")) != -1)
88     {
89       switch (opt)
90         {
91         case 'n':
92           nline = atoi (list_optarg);
93           if (nline <= 0)
94             {
95               builtin_error ("bad line count: %s", list_optarg);
96               return (EX_USAGE);
97             }
98           break;
99         default:
100           builtin_usage ();
101           return (EX_USAGE);
102         }
103     }
104   list = loptend;
105
106   if (list == 0)
107     return (file_head (stdin, nline));
108
109   for (rval = EXECUTION_SUCCESS, opt = 1, l = list; l; l = l->next)
110     {
111       fp = fopen (l->word->word, "r");
112       if (fp == NULL)
113         {
114           builtin_error ("%s: %s", l->word->word, strerror (errno));
115           continue;
116         }
117       if (list->next)   /* more than one file */
118         {
119           printf ("%s==> %s <==\n", opt ? "" : "\n", l->word->word);
120           opt = 0;
121         }
122       rval = file_head (fp, nline);
123       fclose (fp);
124     }
125    
126   return (rval);
127 }
128
129 char *head_doc[] = {
130         "Copy the first N lines from the input files to the standard output.",
131         "N is supplied as an argument to the `-n' option.  If N is not given,",
132         "the first ten lines are copied.",
133         (char *)NULL
134 };
135
136 struct builtin head_struct = {
137         "head",                 /* builtin name */
138         head_builtin,           /* function implementing the builtin */
139         BUILTIN_ENABLED,        /* initial flags for builtin */
140         head_doc,               /* array of long documentation strings. */
141         "head [-n num] [file ...]", /* usage synopsis; becomes short_doc */
142         0                       /* reserved for internal use */
143 };