| |
| /* |
| * 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; |
| } |