"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/utils_blkid.c" (13 Jan 2022, 6561 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "utils_blkid.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * blkid probe utilities
    3  *
    4  * Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
    5  *
    6  * This program is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU General Public License
    8  * as published by the Free Software Foundation; either version 2
    9  * of the License, or (at your option) any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   19  */
   20 
   21 #include <errno.h>
   22 #include <stdio.h>
   23 #include <stdlib.h>
   24 #include <string.h>
   25 #include <unistd.h>
   26 
   27 #include "utils_blkid.h"
   28 #include "utils_io.h"
   29 
   30 #ifdef HAVE_BLKID
   31 #include <blkid/blkid.h>
   32 /* make bad checksums flag optional */
   33 #ifndef BLKID_SUBLKS_BADCSUM
   34 #define BLKID_SUBLKS_BADCSUM 0
   35 #endif
   36 struct blkid_handle {
   37     int fd;
   38     blkid_probe pr;
   39 };
   40 #ifndef HAVE_BLKID_WIPE
   41 static size_t crypt_getpagesize(void)
   42 {
   43     long r = sysconf(_SC_PAGESIZE);
   44     return r <= 0 ? 4096 : (size_t)r;
   45 }
   46 #endif
   47 #endif
   48 
   49 void blk_set_chains_for_wipes(struct blkid_handle *h)
   50 {
   51 #ifdef HAVE_BLKID
   52     blkid_probe_enable_partitions(h->pr, 1);
   53     blkid_probe_set_partitions_flags(h->pr, 0
   54 #ifdef HAVE_BLKID_WIPE
   55     | BLKID_PARTS_MAGIC
   56 #endif
   57     );
   58 
   59     blkid_probe_enable_superblocks(h->pr, 1);
   60     blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_LABEL   |
   61                          BLKID_SUBLKS_UUID    |
   62                          BLKID_SUBLKS_TYPE    |
   63                          BLKID_SUBLKS_USAGE   |
   64                          BLKID_SUBLKS_VERSION |
   65                          BLKID_SUBLKS_MAGIC   |
   66                          BLKID_SUBLKS_BADCSUM);
   67 #endif
   68 }
   69 
   70 void blk_set_chains_for_full_print(struct blkid_handle *h)
   71 {
   72     blk_set_chains_for_wipes(h);
   73 }
   74 
   75 void blk_set_chains_for_fast_detection(struct blkid_handle *h)
   76 {
   77 #ifdef HAVE_BLKID
   78     blkid_probe_enable_partitions(h->pr, 1);
   79     blkid_probe_set_partitions_flags(h->pr, 0);
   80 
   81     blkid_probe_enable_superblocks(h->pr, 1);
   82     blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_TYPE);
   83 #endif
   84 }
   85 
   86 int blk_init_by_path(struct blkid_handle **h, const char *path)
   87 {
   88     int r = -ENOTSUP;
   89 #ifdef HAVE_BLKID
   90     struct blkid_handle *tmp = malloc(sizeof(*tmp));
   91     if (!tmp)
   92         return -ENOMEM;
   93 
   94     tmp->fd = -1;
   95 
   96     tmp->pr = blkid_new_probe_from_filename(path);
   97     if (!tmp->pr) {
   98         free(tmp);
   99         return -EINVAL;
  100     }
  101 
  102     *h = tmp;
  103 
  104     r = 0;
  105 #endif
  106     return r;
  107 }
  108 
  109 int blk_init_by_fd(struct blkid_handle **h, int fd)
  110 {
  111     int r = -ENOTSUP;
  112 #ifdef HAVE_BLKID
  113     struct blkid_handle *tmp = malloc(sizeof(*tmp));
  114     if (!tmp)
  115         return -ENOMEM;
  116 
  117     tmp->pr = blkid_new_probe();
  118     if (!tmp->pr) {
  119         free(tmp);
  120         return -EINVAL;
  121     }
  122 
  123     if (blkid_probe_set_device(tmp->pr, fd, 0, 0)) {
  124         blkid_free_probe(tmp->pr);
  125         free(tmp);
  126         return -EINVAL;
  127     }
  128 
  129     tmp->fd = fd;
  130 
  131     *h = tmp;
  132 
  133     r = 0;
  134 #endif
  135     return r;
  136 }
  137 
  138 int blk_superblocks_filter_luks(struct blkid_handle *h)
  139 {
  140     int r = -ENOTSUP;
  141 #ifdef HAVE_BLKID
  142     char luks[] = "crypto_LUKS";
  143     char *luks_filter[] = {
  144         luks,
  145         NULL
  146     };
  147     r = blkid_probe_filter_superblocks_type(h->pr, BLKID_FLTR_NOTIN, luks_filter);
  148 #endif
  149     return r;
  150 }
  151 
  152 blk_probe_status blk_probe(struct blkid_handle *h)
  153 {
  154     blk_probe_status pr = PRB_FAIL;
  155 #ifdef HAVE_BLKID
  156     int r = blkid_do_probe(h->pr);
  157 
  158     if (r == 0)
  159         pr = PRB_OK;
  160     else if (r == 1)
  161         pr = PRB_EMPTY;
  162 #endif
  163     return pr;
  164 }
  165 
  166 blk_probe_status blk_safeprobe(struct blkid_handle *h)
  167 {
  168     int r = -1;
  169 #ifdef HAVE_BLKID
  170     r = blkid_do_safeprobe(h->pr);
  171 #endif
  172     switch (r) {
  173     case -2:
  174         return PRB_AMBIGUOUS;
  175     case 1:
  176         return PRB_EMPTY;
  177     case 0:
  178         return PRB_OK;
  179     default:
  180         return PRB_FAIL;
  181     }
  182 }
  183 
  184 int blk_is_partition(struct blkid_handle *h)
  185 {
  186     int r = 0;
  187 #ifdef HAVE_BLKID
  188     r = blkid_probe_has_value(h->pr, "PTTYPE");
  189 #endif
  190     return r;
  191 }
  192 
  193 int blk_is_superblock(struct blkid_handle *h)
  194 {
  195     int r = 0;
  196 #ifdef HAVE_BLKID
  197     r = blkid_probe_has_value(h->pr, "TYPE");
  198 #endif
  199     return r;
  200 }
  201 
  202 const char *blk_get_partition_type(struct blkid_handle *h)
  203 {
  204     const char *value = NULL;
  205 #ifdef HAVE_BLKID
  206     (void) blkid_probe_lookup_value(h->pr, "PTTYPE", &value, NULL);
  207 #endif
  208     return value;
  209 }
  210 
  211 const char *blk_get_superblock_type(struct blkid_handle *h)
  212 {
  213     const char *value = NULL;
  214 #ifdef HAVE_BLKID
  215     (void) blkid_probe_lookup_value(h->pr, "TYPE", &value, NULL);
  216 #endif
  217     return value;
  218 }
  219 
  220 void blk_free(struct blkid_handle *h)
  221 {
  222 #ifdef HAVE_BLKID
  223     if (!h)
  224         return;
  225 
  226     if (h->pr)
  227         blkid_free_probe(h->pr);
  228 
  229     free(h);
  230 #endif
  231 }
  232 
  233 #ifdef HAVE_BLKID
  234 #ifndef HAVE_BLKID_WIPE
  235 static int blk_step_back(struct blkid_handle *h)
  236 {
  237 #ifdef HAVE_BLKID_STEP_BACK
  238     return blkid_probe_step_back(h->pr);
  239 #else
  240     blkid_reset_probe(h->pr);
  241     blkid_probe_set_device(h->pr, h->fd, 0, 0);
  242     return 0;
  243 #endif
  244 }
  245 #endif /* not HAVE_BLKID_WIPE */
  246 #endif /* HAVE_BLKID */
  247 
  248 int blk_do_wipe(struct blkid_handle *h)
  249 {
  250 #ifdef HAVE_BLKID
  251 #ifdef HAVE_BLKID_WIPE
  252     return blkid_do_wipe(h->pr, 0);
  253 #else
  254     const char *offset;
  255     off_t offset_val;
  256     void *buf;
  257     ssize_t ret;
  258     size_t alignment, len, bsize = blkid_probe_get_sectorsize(h->pr);
  259 
  260     if (h->fd < 0 || !bsize)
  261         return -EINVAL;
  262 
  263     if (blk_is_partition(h)) {
  264         if (blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
  265             return -EINVAL;
  266         if (blkid_probe_lookup_value(h->pr, "PTMAGIC", NULL, &len))
  267             return -EINVAL;
  268     } else if (blk_is_superblock(h)) {
  269         if (blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
  270             return -EINVAL;
  271         if (blkid_probe_lookup_value(h->pr, "SBMAGIC", NULL, &len))
  272             return -EINVAL;
  273     } else
  274         return 0;
  275 
  276     alignment = crypt_getpagesize();
  277 
  278     if (posix_memalign(&buf, alignment, len))
  279         return -EINVAL;
  280     memset(buf, 0, len);
  281 
  282     offset_val = strtoll(offset, NULL, 10);
  283 
  284     /* TODO: missing crypt_wipe_fd() */
  285     ret = write_lseek_blockwise(h->fd, bsize, alignment, buf, len, offset_val);
  286     free(buf);
  287     if (ret < 0)
  288         return -EIO;
  289 
  290     if ((size_t)ret == len) {
  291         blk_step_back(h);
  292         return 0;
  293     }
  294 
  295     return -EIO;
  296 #endif
  297 #else /* HAVE_BLKID */
  298     return -ENOTSUP;
  299 #endif
  300 }
  301 
  302 int blk_supported(void)
  303 {
  304     int r = 0;
  305 #ifdef HAVE_BLKID
  306     r = 1;
  307 #endif
  308     return r;
  309 }
  310 
  311 off_t blk_get_offset(struct blkid_handle *h)
  312 {
  313     off_t offset_value = -1;
  314 #ifdef HAVE_BLKID
  315     const char *offset;
  316     if (blk_is_superblock(h)) {
  317         if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
  318             offset_value = strtoll(offset, NULL, 10);
  319     } else if (blk_is_partition(h) && !blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
  320         offset_value = strtoll(offset, NULL, 10);
  321 #endif
  322     return offset_value;
  323 }