/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <stdlib.h> #include <string.h> #include <dirent.h> #include <errno.h> #include <sys/types.h> #include "vold.h" #include "media.h" static media_list_t *list_root = NULL; media_t *media_create(char *devpath, char *name, char *serial, media_type_t type) { media_list_t *list_entry; media_t *new; if (!(new = malloc(sizeof(media_t)))) return NULL; memset(new, 0, sizeof(media_t)); if (!(list_entry = malloc(sizeof(media_list_t)))) { free(new); return NULL; } list_entry->media = new; list_entry->next = NULL; if (!list_root) list_root = list_entry; else { media_list_t *list_scan = list_root; while(list_scan->next) list_scan = list_scan->next; list_scan->next = list_entry; } new->devpath = strdup(devpath); new->name = strdup(name); if (!serial) new->serial = 0; else new->serial = strtoul(serial, NULL, 0); new->media_type = type; return new; } void media_destroy(media_t *media) { media_list_t *list_next; if (list_root->media == media) { list_next = list_root->next; free(list_root); list_root = list_next; } else { media_list_t *list_scan = list_root; while (list_scan->next->media != media) list_scan = list_scan -> next; list_next = list_scan->next->next; free(list_scan->next); list_scan->next = list_next; } free(media->devpath); free(media->name); while(media->devs) media_remove_blkdev(media, media->devs->dev); free(media); } media_t *media_lookup_by_path(char *devpath, boolean fuzzy_match) { media_list_t *list_scan = list_root; while (list_scan) { if (fuzzy_match) { if (!strncmp(list_scan->media->devpath, devpath, strlen(devpath))) return list_scan->media; } else { if (!strcmp(list_scan->media->devpath, devpath)) return list_scan->media; } list_scan = list_scan->next; } #if DEBUG_MEDIA LOG_VOL("media_lookup_by_path(): No media found @ %s", devpath); #endif return NULL; } int media_add_blkdev(media_t *card, blkdev_t *dev) { blkdev_list_t *list_entry; if (!(list_entry = malloc(sizeof(blkdev_list_t)))) return -ENOMEM; list_entry->next = NULL; list_entry->dev = dev; if (!card->devs) card->devs = list_entry; else { blkdev_list_t *scan = card->devs; while(scan->next) scan = scan->next; scan->next = list_entry; } return 0; } void media_remove_blkdev(media_t *card, blkdev_t *dev) { if (card->devs->dev == dev) card->devs = card->devs->next; else { blkdev_list_t *scan = card->devs; while (scan->next->dev != dev) scan = scan -> next; blkdev_list_t *next = scan->next->next; free(scan->next); scan->next = next; } } media_t *media_lookup_by_dev(blkdev_t *dev) { media_list_t *media_scan = list_root; while (media_scan) { blkdev_list_t *blk_scan = media_scan->media->devs; while (blk_scan) { if (blk_scan->dev == dev) return media_scan->media; blk_scan = blk_scan->next; } media_scan = media_scan->next; } return NULL; }