~ubuntu-branches/ubuntu/raring/mysql-5.5/raring-proposed

« back to all changes in this revision

Viewing changes to cmd-line-utils/libedit/filecomplete.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-14 23:59:22 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120214235922-cux5uek1e5l0hje9
Tags: 5.5.20-0ubuntu1
* New upstream release.
* d/mysql-server-5.5.mysql.upstart: Fix stop on to make sure mysql is
  fully stopped before shutdown commences. (LP: #688541) Also simplify
  start on as it is redundant.
* d/control: Depend on upstart version which has apparmor profile load
  script to prevent failure on upgrade from lucid to precise.
  (LP: #907465)
* d/apparmor-profile: need to allow /run since that is the true path
  of /var/run files. (LP: #917542)
* d/control: mysql-server-5.5 has files in it that used to be owned
  by libmysqlclient-dev, so it must break/replace it. (LP: #912487)
* d/rules, d/control: 5.5.20 Fixes segfault on tests with gcc 4.6,
  change compiler back to system default.
* d/rules: Turn off embedded libedit/readline.(Closes: #659566)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*      $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $    */
 
1
/*      $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */
2
2
 
3
3
/*-
4
4
 * Copyright (c) 1997 The NetBSD Foundation, Inc.
78
78
#include "histedit.h"
79
79
#include "filecomplete.h"
80
80
 
81
 
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
82
 
    '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
 
81
static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
 
82
    '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
83
83
 
84
84
 
85
85
/********************************/
95
95
char *
96
96
fn_tilde_expand(const char *txt)
97
97
{
 
98
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
 
99
        struct passwd pwres;
 
100
        char pwbuf[1024];
 
101
#endif
98
102
        struct passwd *pass;
99
103
        char *temp;
100
104
        size_t len = 0;
101
105
 
102
106
        if (txt[0] != '~')
103
 
                return (strdup(txt));
 
107
                return strdup(txt);
104
108
 
105
109
        temp = strchr(txt + 1, '/');
106
110
        if (temp == NULL) {
108
112
                if (temp == NULL)
109
113
                        return NULL;
110
114
        } else {
111
 
                len = temp - txt + 1;   /* text until string after slash */
112
 
                temp = malloc(len);
 
115
                /* text until string after slash */
 
116
                len = (size_t)(temp - txt + 1);
 
117
                temp = el_malloc(len * sizeof(*temp));
113
118
                if (temp == NULL)
114
119
                        return NULL;
115
120
                (void)strncpy(temp, txt + 1, len - 2);
116
121
                temp[len - 2] = '\0';
117
122
        }
118
 
        /* XXXMYSQL: use non-_r functions for now */
119
123
        if (temp[0] == 0) {
 
124
#ifdef HAVE_GETPW_R_POSIX
 
125
                if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf),
 
126
                    &pass) != 0)
 
127
                        pass = NULL;
 
128
#elif HAVE_GETPW_R_DRAFT
 
129
                pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
 
130
#else
120
131
                pass = getpwuid(getuid());
 
132
#endif
121
133
        } else {
 
134
#ifdef HAVE_GETPW_R_POSIX
 
135
                if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
 
136
                        pass = NULL;
 
137
#elif HAVE_GETPW_R_DRAFT
 
138
                pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
 
139
#else
122
140
                pass = getpwnam(temp);
 
141
#endif
123
142
        }
124
 
        free(temp);             /* value no more needed */
 
143
        el_free(temp);          /* value no more needed */
125
144
        if (pass == NULL)
126
 
                return (strdup(txt));
 
145
                return strdup(txt);
127
146
 
128
147
        /* update pointer txt to point at string immedially following */
129
148
        /* first slash */
130
149
        txt += len;
131
150
 
132
 
        temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
 
151
        len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
 
152
        temp = el_malloc(len * sizeof(*temp));
133
153
        if (temp == NULL)
134
154
                return NULL;
135
 
        (void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
 
155
        (void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
136
156
 
137
 
        return (temp);
 
157
        return temp;
138
158
}
139
159
 
140
160
 
160
180
                if (temp) {
161
181
                        char *nptr;
162
182
                        temp++;
163
 
                        nptr = realloc(filename, strlen(temp) + 1);
 
183
                        nptr = el_realloc(filename, (strlen(temp) + 1) *
 
184
                            sizeof(*nptr));
164
185
                        if (nptr == NULL) {
165
 
                                free(filename);
 
186
                                el_free(filename);
 
187
                                filename = NULL;
166
188
                                return NULL;
167
189
                        }
168
190
                        filename = nptr;
169
191
                        (void)strcpy(filename, temp);
170
 
                        len = temp - text;      /* including last slash */
171
 
                        nptr = realloc(dirname, len + 1);
 
192
                        len = (size_t)(temp - text);    /* including last slash */
 
193
 
 
194
                        nptr = el_realloc(dirname, (len + 1) *
 
195
                            sizeof(*nptr));
172
196
                        if (nptr == NULL) {
173
 
                                free(filename);
 
197
                                el_free(dirname);
 
198
                                dirname = NULL;
174
199
                                return NULL;
175
200
                        }
176
201
                        dirname = nptr;
177
202
                        (void)strncpy(dirname, text, len);
178
203
                        dirname[len] = '\0';
179
204
                } else {
 
205
                        el_free(filename);
180
206
                        if (*text == 0)
181
207
                                filename = NULL;
182
208
                        else {
184
210
                                if (filename == NULL)
185
211
                                        return NULL;
186
212
                        }
 
213
                        el_free(dirname);
187
214
                        dirname = NULL;
188
215
                }
189
216
 
193
220
                }
194
221
 
195
222
                /* support for ``~user'' syntax */
196
 
                free(dirpath);
197
 
 
198
 
                if (dirname == NULL && (dirname = strdup("./")) == NULL)
199
 
                        return NULL;
200
 
 
201
 
                if (*dirname == '~')
 
223
 
 
224
                el_free(dirpath);
 
225
                dirpath = NULL;
 
226
                if (dirname == NULL) {
 
227
                        if ((dirname = strdup("")) == NULL)
 
228
                                return NULL;
 
229
                        dirpath = strdup("./");
 
230
                } else if (*dirname == '~')
202
231
                        dirpath = fn_tilde_expand(dirname);
203
232
                else
204
233
                        dirpath = strdup(dirname);
208
237
 
209
238
                dir = opendir(dirpath);
210
239
                if (!dir)
211
 
                        return (NULL);  /* cannot open the directory */
 
240
                        return NULL;    /* cannot open the directory */
212
241
 
213
242
                /* will be used in cycle */
214
243
                filename_len = filename ? strlen(filename) : 0;
243
272
                len = strlen(entry->d_name);
244
273
#endif
245
274
 
246
 
                temp = malloc(strlen(dirname) + len + 1);
 
275
                len = strlen(dirname) + len + 1;
 
276
                temp = el_malloc(len * sizeof(*temp));
247
277
                if (temp == NULL)
248
278
                        return NULL;
249
 
                (void)sprintf(temp, "%s%s", dirname, entry->d_name);
 
279
                (void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
250
280
        } else {
251
281
                (void)closedir(dir);
252
282
                dir = NULL;
253
283
                temp = NULL;
254
284
        }
255
285
 
256
 
        return (temp);
 
286
        return temp;
257
287
}
258
288
 
259
289
 
270
300
                rs = "/";
271
301
out:
272
302
        if (expname)
273
 
                free(expname);
 
303
                el_free(expname);
274
304
        return rs;
275
305
}
276
306
/*
293
323
                        char **nmatch_list;
294
324
                        while (matches + 3 >= match_list_len)
295
325
                                match_list_len <<= 1;
296
 
                        nmatch_list = realloc(match_list,
297
 
                            match_list_len * sizeof(char *));
 
326
                        nmatch_list = el_realloc(match_list,
 
327
                            match_list_len * sizeof(*nmatch_list));
298
328
                        if (nmatch_list == NULL) {
299
 
                                free(match_list);
 
329
                                el_free(match_list);
300
330
                                return NULL;
301
331
                        }
302
332
                        match_list = nmatch_list;
319
349
                max_equal = i;
320
350
        }
321
351
 
322
 
        retstr = malloc(max_equal + 1);
 
352
        retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
323
353
        if (retstr == NULL) {
324
 
                free(match_list);
 
354
                el_free(match_list);
325
355
                return NULL;
326
356
        }
327
357
        (void)strncpy(retstr, match_list[1], max_equal);
329
359
        match_list[0] = retstr;
330
360
 
331
361
        /* add NULL as last pointer to the array */
332
 
        match_list[matches + 1] = (char *) NULL;
 
362
        match_list[matches + 1] = NULL;
333
363
 
334
 
        return (match_list);
 
364
        return match_list;
335
365
}
336
366
 
337
367
/*
348
378
 
349
379
/*
350
380
 * Display list of strings in columnar format on readline's output stream.
351
 
 * 'matches' is list of strings, 'len' is number of strings in 'matches',
352
 
 * 'max' is maximum length of string in 'matches'.
 
381
 * 'matches' is list of strings, 'num' is number of strings in 'matches',
 
382
 * 'width' is maximum length of string in 'matches'.
 
383
 *
 
384
 * matches[0] is not one of the match strings, but it is counted in
 
385
 * num, so the strings are matches[1] *through* matches[num-1].
353
386
 */
354
387
void
355
 
fn_display_match_list (EditLine *el, char **matches, int len, int max)
 
388
fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
356
389
{
357
 
        int i, idx, limit, count;
358
 
        int screenwidth = el->el_term.t_size.h;
359
 
 
360
 
        /*
361
 
         * Find out how many entries can be put on one line, count
362
 
         * with two spaces between strings.
363
 
         */
364
 
        limit = screenwidth / (max + 2);
365
 
        if (limit == 0)
366
 
                limit = 1;
367
 
 
368
 
        /* how many lines of output */
369
 
        count = len / limit;
370
 
        if (count * limit < len)
371
 
                count++;
372
 
 
373
 
        /* Sort the items if they are not already sorted. */
374
 
        qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
375
 
            _fn_qsort_string_compare);
376
 
 
377
 
        idx = 1;
378
 
        for(; count > 0; count--) {
379
 
                for(i = 0; i < limit && matches[idx]; i++, idx++)
380
 
                        (void)fprintf(el->el_outfile, "%-*s  ", max,
381
 
                            matches[idx]);
 
390
        size_t line, lines, col, cols, thisguy;
 
391
        int screenwidth = el->el_terminal.t_size.h;
 
392
 
 
393
        /* Ignore matches[0]. Avoid 1-based array logic below. */
 
394
        matches++;
 
395
        num--;
 
396
 
 
397
        /*
 
398
         * Find out how many entries can be put on one line; count
 
399
         * with one space between strings the same way it's printed.
 
400
         */
 
401
        cols = (size_t)screenwidth / (width + 1);
 
402
        if (cols == 0)
 
403
                cols = 1;
 
404
 
 
405
        /* how many lines of output, rounded up */
 
406
        lines = (num + cols - 1) / cols;
 
407
 
 
408
        /* Sort the items. */
 
409
        qsort(matches, num, sizeof(char *), _fn_qsort_string_compare);
 
410
 
 
411
        /*
 
412
         * On the ith line print elements i, i+lines, i+lines*2, etc.
 
413
         */
 
414
        for (line = 0; line < lines; line++) {
 
415
                for (col = 0; col < cols; col++) {
 
416
                        thisguy = line + col * lines;
 
417
                        if (thisguy >= num)
 
418
                                break;
 
419
                        (void)fprintf(el->el_outfile, "%s%-*s",
 
420
                            col == 0 ? "" : " ", (int)width, matches[thisguy]);
 
421
                }
382
422
                (void)fprintf(el->el_outfile, "\n");
383
423
        }
384
424
}
399
439
fn_complete(EditLine *el,
400
440
        char *(*complet_func)(const char *, int),
401
441
        char **(*attempted_completion_function)(const char *, int, int),
402
 
        const char *word_break, const char *special_prefixes,
403
 
        const char *(*app_func)(const char *), int query_items,
 
442
        const Char *word_break, const Char *special_prefixes,
 
443
        const char *(*app_func)(const char *), size_t query_items,
404
444
        int *completion_type, int *over, int *point, int *end)
405
445
{
406
 
        const LineInfo *li;
407
 
        char *temp, **matches;
408
 
        const char *ctemp;
 
446
        const TYPE(LineInfo) *li;
 
447
        Char *temp;
 
448
        char **matches;
 
449
        const Char *ctemp;
409
450
        size_t len;
410
451
        int what_to_do = '\t';
411
452
        int retval = CC_NORM;
423
464
                app_func = append_char_function;
424
465
 
425
466
        /* We now look backwards for the start of a filename/variable word */
426
 
        li = el_line(el);
427
 
        ctemp = (const char *) li->cursor;
 
467
        li = FUN(el,line)(el);
 
468
        ctemp = li->cursor;
428
469
        while (ctemp > li->buffer
429
 
            && !strchr(word_break, ctemp[-1])
430
 
            && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
 
470
            && !Strchr(word_break, ctemp[-1])
 
471
            && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
431
472
                ctemp--;
432
473
 
433
 
        len = li->cursor - ctemp;
 
474
        len = (size_t)(li->cursor - ctemp);
434
475
#if defined(__SSP__) || defined(__SSP_ALL__)
435
 
        temp = malloc(len + 1);
 
476
        temp = el_malloc((len + 1) * sizeof(*temp));
436
477
#else
437
 
        temp = alloca(len + 1);
 
478
        temp = alloca((len + 1) * sizeof(*temp));
438
479
#endif
439
 
        (void)strncpy(temp, ctemp, len);
 
480
        (void)Strncpy(temp, ctemp, len);
440
481
        temp[len] = '\0';
441
482
 
442
483
        /* these can be used by function called in completion_matches() */
443
484
        /* or (*attempted_completion_function)() */
444
485
        if (point != 0)
445
 
                *point = li->cursor - li->buffer;
 
486
                *point = (int)(li->cursor - li->buffer);
446
487
        if (end != NULL)
447
 
                *end = li->lastchar - li->buffer;
 
488
                *end = (int)(li->lastchar - li->buffer);
448
489
 
449
490
        if (attempted_completion_function) {
450
 
                int cur_off = li->cursor - li->buffer;
451
 
                matches = (*attempted_completion_function) (temp,
452
 
                    (int)(cur_off - len), cur_off);
 
491
                int cur_off = (int)(li->cursor - li->buffer);
 
492
                matches = (*attempted_completion_function)(
 
493
                    ct_encode_string(temp, &el->el_scratch),
 
494
                    cur_off - (int)len, cur_off);
453
495
        } else
454
496
                matches = 0;
455
497
        if (!attempted_completion_function || 
456
498
            (over != NULL && !*over && !matches))
457
 
                matches = completion_matches(temp, complet_func);
 
499
                matches = completion_matches(
 
500
                    ct_encode_string(temp, &el->el_scratch), complet_func);
458
501
 
459
502
        if (over != NULL)
460
503
                *over = 0;
461
504
 
462
505
        if (matches) {
463
506
                int i;
464
 
                int matches_num, maxlen, match_len, match_display=1;
 
507
                size_t matches_num, maxlen, match_len, match_display=1;
465
508
 
466
509
                retval = CC_REFRESH;
467
510
                /*
470
513
                 */
471
514
                if (matches[0][0] != '\0') {
472
515
                        el_deletestr(el, (int) len);
473
 
                        el_insertstr(el, matches[0]);
 
516
                        FUN(el,insertstr)(el,
 
517
                            ct_decode_string(matches[0], &el->el_scratch));
474
518
                }
475
519
 
476
520
                if (what_to_do == '?')
482
526
                         * it, unless we do filename completion and the
483
527
                         * object is a directory.
484
528
                         */
485
 
                        el_insertstr(el, (*app_func)(matches[0])); 
 
529
                        FUN(el,insertstr)(el,
 
530
                            ct_decode_string((*app_func)(matches[0]),
 
531
                            &el->el_scratch));
486
532
                } else if (what_to_do == '!') {
487
533
    display_matches:
488
534
                        /*
490
536
                         * matches.
491
537
                         */
492
538
 
493
 
                        for(i=1, maxlen=0; matches[i]; i++) {
 
539
                        for(i = 1, maxlen = 0; matches[i]; i++) {
494
540
                                match_len = strlen(matches[i]);
495
541
                                if (match_len > maxlen)
496
542
                                        maxlen = match_len;
497
543
                        }
498
 
                        matches_num = i - 1;
 
544
                        /* matches[1] through matches[i-1] are available */
 
545
                        matches_num = (size_t)(i - 1);
499
546
                                
500
547
                        /* newline to get on next line from command line */
501
548
                        (void)fprintf(el->el_outfile, "\n");
506
553
                         */
507
554
                        if (matches_num > query_items) {
508
555
                                (void)fprintf(el->el_outfile,
509
 
                                    "Display all %d possibilities? (y or n) ",
 
556
                                    "Display all %zu possibilities? (y or n) ",
510
557
                                    matches_num);
511
558
                                (void)fflush(el->el_outfile);
512
559
                                if (getc(stdin) != 'y')
514
561
                                (void)fprintf(el->el_outfile, "\n");
515
562
                        }
516
563
 
517
 
                        if (match_display)
518
 
                                fn_display_match_list(el, matches, matches_num,
519
 
                                        maxlen);
 
564
                        if (match_display) {
 
565
                                /*
 
566
                                 * Interface of this function requires the
 
567
                                 * strings be matches[1..num-1] for compat.
 
568
                                 * We have matches_num strings not counting
 
569
                                 * the prefix in matches[0], so we need to
 
570
                                 * add 1 to matches_num for the call.
 
571
                                 */
 
572
                                fn_display_match_list(el, matches,
 
573
                                    matches_num+1, maxlen);
 
574
                        }
520
575
                        retval = CC_REDISPLAY;
521
576
                } else if (matches[0][0]) {
522
577
                        /*
534
589
 
535
590
                /* free elements of array and the array itself */
536
591
                for (i = 0; matches[i]; i++)
537
 
                        free(matches[i]);
538
 
                free(matches);
 
592
                        el_free(matches[i]);
 
593
                el_free(matches);
539
594
                matches = NULL;
540
595
        }
541
596
#if defined(__SSP__) || defined(__SSP_ALL__)
542
 
        free(temp);
 
597
        el_free(temp);
543
598
#endif
544
599
        return retval;
545
600
}
552
607
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
553
608
{
554
609
        return (unsigned char)fn_complete(el, NULL, NULL,
555
 
            break_chars, NULL, NULL, 100,
 
610
            break_chars, NULL, NULL, (size_t)100,
556
611
            NULL, NULL, NULL, NULL);
557
612
}