~ubuntu-branches/ubuntu/trusty/apex/trusty

« back to all changes in this revision

Viewing changes to src/apex/command.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2009-11-10 11:55:15 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091110115515-6jjsf6rc8py35awe
Tags: 1.6.10ubuntu1
* Merge from debian testing, remaining changes:
  - Move apex VMA address to 4MiB to leave enough space for the ubuntu
  kernel and not overwrite apex in ram when loading.
  - nslu2 configuration: set CONFIG_RAMDISK_SIZE=0x0055FFF0 instead of
  0x005FFFF0 to make enough room for ubuntu initramfs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
   Copyright (C) 2004 Marc Singer
7
7
 
8
8
   This program is free software; you can redistribute it and/or
9
 
   modify it under the terms of the GNU General Public License as
10
 
   published by the Free Software Foundation; either version 2 of the
11
 
   License, or (at your option) any later version.
12
 
 
13
 
   This program is distributed in the hope that it will be useful, but
14
 
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
   General Public License for more details.
17
 
 
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21
 
   USA.
 
9
   modify it under the terms of the GNU General Public License
 
10
   version 2 as published by the Free Software Foundation.
 
11
   Please refer to the file debian/copyright for further details.
22
12
 
23
13
   -----------
24
14
   DESCRIPTION
25
15
   -----------
26
16
 
 
17
   expand_variables
 
18
   ----------------
 
19
 
 
20
   In order to expand variables recursively, the expand_variables()
 
21
   function is recursive.  It copies the characters from one string to
 
22
   another, expanding variables as they are found.  When a variable is
 
23
   detected, it is looked-up and then expanded using the buffer space
 
24
   following the current point in the expansion buffer.
 
25
 
 
26
   The only hazard is that the function will silently fail if an
 
27
   expansion would overflow the buffer.  In this case, the user will
 
28
   see an unexpanded variable in the output.
 
29
 
27
30
*/
28
31
 
 
32
//#define TALK 1
 
33
 
29
34
#include <linux/types.h>
30
35
#include <linux/string.h>
31
36
#include <apex.h>
35
40
#include <environment.h>
36
41
#include <spinner.h>
37
42
#include <lookup.h>
 
43
#include <talk.h>
38
44
 
39
45
const char* error_description;
40
46
 
49
55
#define TIMECMD_REPORT
50
56
#endif
51
57
 
52
 
#if defined (CONFIG_ALIAS) || defined (CONFIG_ENV)
53
 
 
54
 
static char* expand_variables (const char* rgbSrc)
 
58
#if defined (CONFIG_ALIASES) || defined (CONFIG_ENV)
 
59
# define USE_EXPAND_VARIABLES
 
60
#endif
 
61
 
 
62
 
 
63
 
 
64
#if defined (USE_EXPAND_VARIABLES)
 
65
 
 
66
static char* _expand_variables (const char* rgbSrc,
 
67
                                char* rgbExpand, size_t cbExpand)
55
68
{
56
69
  const char* pchSrc;
57
 
  static char __xbss(command) rgb[CB_COMMAND_MAX];
58
 
  char* pch = rgb;
 
70
  char* pch = rgbExpand;        /* Destination pointer, this step */
59
71
  char* pchKey = NULL;
60
72
  int state = 0;
61
 
  const char* value;
62
73
  int fChanged = 0;
63
74
 
64
 
  for (pchSrc = rgbSrc; pch < rgb + sizeof (rgb) - 1; ++pchSrc) {
 
75
  for (pchSrc = rgbSrc; pch < rgbExpand + cbExpand - 1; ++pchSrc) {
65
76
    switch (state) {
66
77
    case 0:                     /* Beginning of word */
67
78
      if (*pchSrc == '"')
81
92
      break;
82
93
 
83
94
    case 2:                     /* Scanning variable key */
84
 
      if (isalpha (*pchSrc) || *pchSrc == '_' || *pchSrc == '-')
 
95
      if (isalpha (*pchSrc)
 
96
          || *pchSrc == '_' || *pchSrc == '-')        /* key ::= [A-Za-z_-]+ */
85
97
        break;
86
 
      *pch = 0;
87
 
      value = lookup_alias_or_env (pchKey + 1, 0);
88
 
      if (value) {
89
 
        if (pch + strlen (value) + 1 >= rgb + sizeof (rgb) - 1)
90
 
          return 0;             /* Simple failure on overflow */
91
 
        strcpy (pchKey, value);
92
 
        pch = pchKey + strlen (value);
93
 
        fChanged = 1;
94
 
        state = 0;
 
98
      *pch = 0;                 /* Terminate string so lookup can succeed */
 
99
      {
 
100
        const char* value = lookup_alias_or_env (pchKey + 1, 0);
 
101
        const char* value_expanded;
 
102
        if (value) {
 
103
          if (pchKey + strlen (value) >= rgbExpand + cbExpand - 1)
 
104
            return 0;           /* Simple overflow */
 
105
          value_expanded = _expand_variables (value, pch + 1,
 
106
                                              rgbExpand + cbExpand - 1
 
107
                                              - (pch + 1));
 
108
          if (value_expanded)
 
109
            value = value_expanded;
 
110
          if (value) {
 
111
                                /* Successful expansion, so replace
 
112
                                   variable with substitution */
 
113
            memmove (pchKey, value, strlen (value) + 1);
 
114
            pch = pchKey + strlen (pchKey);
 
115
            fChanged = 1;
 
116
          }
 
117
        }
95
118
      }
 
119
      state = 0;                /* In any case, return to normal parsing */
96
120
      break;
97
121
 
98
122
    case 11:                    /* Quoting */
110
134
    if (!*pchSrc)
111
135
      break;
112
136
  }
113
 
  return fChanged && state == 0 ? rgb : NULL;
114
 
}
 
137
  return fChanged && state == 0 ? rgbExpand : NULL;
 
138
}
 
139
 
 
140
static char* expand_variables (const char* rgbSrc)
 
141
{
 
142
  static char __xbss(command) rgbExpand[2*1024]; /* Ridiculously large */
 
143
  return _expand_variables (rgbSrc, rgbExpand, sizeof (rgbExpand));
 
144
}
 
145
 
115
146
#endif
116
147
 
117
148
 
133
164
  int cb;
134
165
  int result = 0;
135
166
 
136
 
#if defined (CONFIG_ALIASES) || defined (CONFIG_ENV)
 
167
#if defined (USE_EXPAND_VARIABLES)
137
168
  pb = expand_variables (rgb);
138
169
  if (pb) {
139
170
    rgb = pb;
187
218
  int cb;
188
219
  struct command_d* command_match = NULL;
189
220
  struct command_d* command;
 
221
  int result;
190
222
 
191
223
  if (!argc)
192
224
    return 0;
206
238
        break;
207
239
    }
208
240
  }
209
 
  if (command_match) {
210
 
    int result;
211
 
    error_description = NULL;
212
 
    result = command_match->func (argc, argv);
213
 
    if (result < ERROR_IMPORTANT) {
214
 
      printf ("Error %d", result);
 
241
  error_description = NULL;
 
242
  result = command_match
 
243
    ? command_match->func (argc, argv)
 
244
    : ERROR_NOCOMMAND;
 
245
  if (result < ERROR_IMPORTANT) {
 
246
    printf ("Error %d", result);
215
247
#if !defined (CONFIG_SMALL)
216
 
      if (error_description == NULL) {
217
 
        switch (result) {
218
 
        case ERROR_PARAM:
219
 
          error_description = "parameter error"; break;
220
 
        case ERROR_OPEN:
221
 
          error_description = "error on open"; break;
222
 
        case ERROR_AMBIGUOUS:
223
 
          error_description = "ambiguous"; break;
224
 
        case ERROR_NODRIVER:
225
 
          error_description = "no driver"; break;
226
 
        case ERROR_UNSUPPORTED:
227
 
          error_description = "unsupported"; break;
228
 
        case ERROR_BADPARTITION:
229
 
          error_description = "bad partition"; break;
230
 
        case ERROR_FILENOTFOUND:
231
 
          error_description = "file not found"; break;
232
 
        case ERROR_IOFAILURE:
233
 
          error_description = "i/o failure"; break;
234
 
        case ERROR_BREAK:
235
 
          error_description = "break"; break;
236
 
        }
 
248
    if (error_description == NULL) {
 
249
      switch (result) {
 
250
      case ERROR_FAILURE:
 
251
        error_description = "command failure"; break;
 
252
      case ERROR_PARAM:
 
253
        error_description = "parameter error"; break;
 
254
      case ERROR_OPEN:
 
255
        error_description = "error on open"; break;
 
256
      case ERROR_AMBIGUOUS:
 
257
        error_description = "ambiguous"; break;
 
258
      case ERROR_NODRIVER:
 
259
        error_description = "no driver"; break;
 
260
      case ERROR_UNSUPPORTED:
 
261
        error_description = "unsupported"; break;
 
262
      case ERROR_BADPARTITION:
 
263
        error_description = "bad partition"; break;
 
264
      case ERROR_FILENOTFOUND:
 
265
        error_description = "file not found"; break;
 
266
      case ERROR_IOFAILURE:
 
267
        error_description = "i/o failure"; break;
 
268
      case ERROR_BREAK:
 
269
        error_description = "break"; break;
 
270
      case ERROR_NOCOMMAND:
 
271
        error_description = "no such command"; break;
 
272
      case ERROR_TIMEOUT:
 
273
        error_description = "timeout"; break;
 
274
      case ERROR_UNRECOGNIZED:
 
275
        error_description = "unrecognized operand"; break;
237
276
      }
238
 
#endif
 
277
    }
 
278
    if (error_description)
239
279
      printf (" (%s)", error_description);
240
 
      printf ("\n");
241
 
    }
242
 
    return result;
 
280
#endif
 
281
    printf ("\n");
243
282
  }
244
 
  return ERROR_NOCOMMAND;
 
283
 
 
284
  return result;
245
285
}
246
286
 
247
287
void exec_monitor (void)
258
298
    const char** argv;
259
299
    strcpy (sz, szStartup);
260
300
 
 
301
    DBG (1, "%s: startup '%s'\n", __FUNCTION__, sz);
 
302
 
261
303
    while (pch && *pch) {
262
304
      int result;
263
305
      char* pchEnd = strchr (pch, ';');
 
306
      DBG (1, " pchEnd 0x%p *pchEnd %x\n", pchEnd, pchEnd ? *pchEnd : 0);
264
307
      if (pchEnd)
265
308
        *pchEnd = 0;
266
309
      while (*pch == ' ')
267
310
        ++pch;
268
 
      printf ("\r# %s\n", pch);
269
 
      result = parse_command (pch, &argc, &argv);
270
 
      if (result >= 0 && (call_command (argc, argv) && result != 1))
271
 
        break;
 
311
      if (*pch) {
 
312
        printf ("\r# %s\n", pch);
 
313
        result = parse_command (pch, &argc, &argv);
 
314
        if (result >= 0 && (call_command (argc, argv) && result != 1))
 
315
          break;
 
316
      }
272
317
      pch = (pchEnd ? pchEnd + 1 : 0);
 
318
      DBG (1, " pch 0x%p *pch %x\n", pch, pch ? *pch : 0);
273
319
    }
274
320
  }
275
321