[BACK]Return to list.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Annotation of src/usr.bin/sudo/list.c, Revision 1.1

1.1     ! millert     1: /*
        !             2:  * Copyright (c) 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
        !             3:  *
        !             4:  * Permission to use, copy, modify, and distribute this software for any
        !             5:  * purpose with or without fee is hereby granted, provided that the above
        !             6:  * copyright notice and this permission notice appear in all copies.
        !             7:  *
        !             8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !             9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            15:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
        !            16:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            17:  */
        !            18:
        !            19: #include <config.h>
        !            20:
        !            21: #include <sys/types.h>
        !            22: #include <stdio.h>
        !            23: #ifdef STDC_HEADERS
        !            24: # include <stdlib.h>
        !            25: # include <stddef.h>
        !            26: #else
        !            27: # ifdef HAVE_STDLIB_H
        !            28: #  include <stdlib.h>
        !            29: # endif
        !            30: #endif /* STDC_HEADERS */
        !            31:
        !            32: #include "sudo.h"
        !            33:
        !            34: #ifndef lint
        !            35: __unused static const char rcsid[] = "$Sudo: list.c,v 1.6 2008/11/09 14:13:12 millert Exp $";
        !            36: #endif /* lint */
        !            37:
        !            38: struct list_proto {
        !            39:     struct list_proto *prev;
        !            40:     struct list_proto *next;
        !            41: };
        !            42:
        !            43: struct list_head_proto {
        !            44:     struct list_proto *first;
        !            45:     struct list_proto *last;
        !            46: };
        !            47:
        !            48: /*
        !            49:  * Pop the last element off the end of vh.
        !            50:  * Returns the popped element.
        !            51:  */
        !            52: void *
        !            53: tq_pop(vh)
        !            54:     void *vh;
        !            55: {
        !            56:     struct list_head_proto *h = (struct list_head_proto *)vh;
        !            57:     void *last = NULL;
        !            58:
        !            59:     if (!tq_empty(h)) {
        !            60:        last = (void *)h->last;
        !            61:        if (h->first == h->last) {
        !            62:            h->first = NULL;
        !            63:            h->last = NULL;
        !            64:        } else {
        !            65:            h->last = h->last->prev;
        !            66:            h->last->next = NULL;
        !            67:        }
        !            68:     }
        !            69:     return (last);
        !            70: }
        !            71:
        !            72: /*
        !            73:  * Convert from a semi-circle queue to normal doubly-linked list
        !            74:  * with a head node.
        !            75:  */
        !            76: void
        !            77: list2tq(vh, vl)
        !            78:     void *vh;
        !            79:     void *vl;
        !            80: {
        !            81:     struct list_head_proto *h = (struct list_head_proto *)vh;
        !            82:     struct list_proto *l = (struct list_proto *)vl;
        !            83:
        !            84:     if (l != NULL) {
        !            85: #ifdef DEBUG
        !            86:        if (l->prev == NULL) {
        !            87:            warningx("list2tq called with non-semicircular list");
        !            88:            abort();
        !            89:        }
        !            90: #endif
        !            91:        h->first = l;
        !            92:        h->last = l->prev;      /* l->prev points to the last member of l */
        !            93:        l->prev = NULL;         /* zero last ptr now that we have a head */
        !            94:     } else {
        !            95:        h->first = NULL;
        !            96:        h->last = NULL;
        !            97:     }
        !            98: }
        !            99:
        !           100: /*
        !           101:  * Append one queue (or single entry) to another using the
        !           102:  * circular properties of the prev pointer to simplify the logic.
        !           103:  */
        !           104: void
        !           105: list_append(vl1, vl2)
        !           106:     void *vl1;
        !           107:     void *vl2;
        !           108: {
        !           109:     struct list_proto *l1 = (struct list_proto *)vl1;
        !           110:     struct list_proto *l2 = (struct list_proto *)vl2;
        !           111:     void *tail = l2->prev;
        !           112:
        !           113:     l1->prev->next = l2;
        !           114:     l2->prev = l1->prev;
        !           115:     l1->prev = tail;
        !           116: }
        !           117:
        !           118: /*
        !           119:  * Append the list of entries to the head node and convert
        !           120:  * e from a semi-circle queue to normal doubly-linked list.
        !           121:  */
        !           122: void
        !           123: tq_append(vh, vl)
        !           124:     void *vh;
        !           125:     void *vl;
        !           126: {
        !           127:     struct list_head_proto *h = (struct list_head_proto *)vh;
        !           128:     struct list_proto *l = (struct list_proto *)vl;
        !           129:     void *tail = l->prev;
        !           130:
        !           131:     if (h->first == NULL)
        !           132:        h->first = l;
        !           133:     else
        !           134:        h->last->next = l;
        !           135:     l->prev = h->last;
        !           136:     h->last = tail;
        !           137: }