home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / install / libfdisk / testfdisk.c < prev   
Encoding:
C/C++ Source or Header  |  1997-09-17  |  15.3 KB  |  619 lines

  1. /* test of the libfdisk library */
  2.  
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "libfdisk.h"
  9.  
  10.  
  11.  
  12. /* clean up that string */
  13. void TrimWhitespace( char *s ) {
  14.     char *f, *l, *p, *q;
  15.  
  16.     if (!(*s))
  17.         return;
  18.  
  19.     for (f=s; *f && isspace(*f); f++) ;
  20.  
  21.     if (!*f) {
  22.         *s = '\0';
  23.         return;
  24.     }
  25.  
  26.     for (l=f+strlen(f)-1; isspace(*l) ; l--)
  27.     *l = '\0';
  28.  
  29.     q = s, p = f;
  30.     while (*p)
  31.         *q++ = *p++;
  32.  
  33.     *q = '\0';
  34.  
  35. int ReadUnsigned( unsigned int *i ) {
  36.     char num[12];
  37.     char *eptr;
  38.     
  39.     fgets(num,12,stdin);
  40.     num[strlen(num)-1] = 0; /* blow the newline */
  41.     *i=strtol(num,&eptr,10);
  42.  
  43.     if (eptr != num && *eptr == 0)
  44.     return 0;
  45.     else
  46.     return FDISK_ERR_USERABORT;
  47. }
  48.  
  49. void ReadString( char **p ) {
  50.     char num[100];
  51.     
  52.     fgets(num,100,stdin);
  53.     num[strlen(num)-1] = 0; /* blow the newline */
  54.  
  55.     /* cleanup front, end whitespace */
  56.     TrimWhitespace( num );
  57.     
  58.     *p = (char *) malloc(strlen(num)+1);
  59.     strcpy(*p, num);
  60. }
  61.  
  62. int ReadBoolean( void ) {
  63.     char *str;
  64.     int  ret;
  65.     
  66.     ReadString(&str);
  67.     ret = (*str == 'Y' || *str == 'y');
  68.     free(str);
  69.     return ret;
  70. }
  71.     
  72. int ReadConstraint( char *name, Constraint *c, int required ) {
  73.     unsigned int v;
  74.  
  75.     printf("Requesting constraint for the parameter \"%s\":\n", name);
  76.     if (required)
  77.     printf("%s -> min value [required     ] :", name);
  78.     else
  79.     printf("%s -> min value [Enter to skip] :", name);
  80.     
  81.     if (ReadUnsigned(&v)) {
  82.     c->active  = 0;
  83.     c->min     = 0;
  84.     c->max     = 0;
  85.     c->current = 0;
  86.     return 1;
  87.     }
  88.  
  89.     c->min     = v;
  90.     c->active  = 1;
  91.  
  92. #if 0
  93.     printf("%s -> max value [Enter sets to min] :", name);
  94.     if (ReadUnsigned(&v))
  95.     c->max     = c->min;
  96.     else
  97.     c->max     = v;
  98. #endif
  99.  
  100.     return 0;
  101. }
  102.  
  103. void print_raw_partition_table_head( void ) {
  104.     printf("Nr AF  Hd Sec  Cyl  Hd Sec  Cyl   Start      Size    ID\n");
  105. }
  106.  
  107. void print_raw_partition_table(int num, RawPartitionTable *pt) {
  108.     int s_cyl, s_head, s_sector;
  109.     int e_cyl, e_head, e_sector;
  110.     unsigned int i;
  111.  
  112.     RawPartition *p;
  113.     
  114.     print_raw_partition_table_head();
  115.  
  116.     for (i=0; i<4; i++) {
  117.     p = &pt->entry[i];
  118.     
  119.     s_head    = p->start_head;
  120.     s_sector  = p->start_sec & 0x3f;
  121.     s_cyl     = ((unsigned int)(p->start_sec & 0xc0) << 2) + p->start_cyl;
  122.     
  123.     e_head    = p->end_head;
  124.     e_sector  = p->end_sec & 0x3f;
  125.     e_cyl     = ((unsigned int)(p->end_sec & 0xc0) << 2) + p->end_cyl;
  126.     
  127.     printf("%2d %2x %3d %3d %4d %3d %3d %4d %7d   %7d    %2x\n",
  128.            i+1, p->active, s_head, s_sector, s_cyl,
  129.            e_head, e_sector, e_cyl, p->start, p->size,
  130.            p->type);
  131.     }
  132. }
  133.  
  134. void print_user_partition_table(HardDrive *hd) {
  135.     int i;
  136.     Partition *up;
  137.     unsigned int first, last, end;
  138.     unsigned int s_cyl, s_hd, s_sec, e_cyl, e_hd, e_sec;
  139.  
  140.     
  141.     printf("Nr AF     Start C/H/S     End C/H/S      Start      Size    ID\n");
  142.  
  143.     /* print primary partitions first */
  144.     fdiskFirstPartition( hd, &first );
  145.     fdiskLastPartition( hd, &last );
  146.     for (i=first; i<=last; i++) {
  147.     up = &hd->table[i];
  148.     if (!(up->size.current) || !(up->type.current))
  149.         continue;
  150.  
  151.     fdiskSectorToCHS( hd, up->start.current, &s_cyl, &s_hd, &s_sec );
  152.     end = up->start.current + up->size.current - 1;
  153.     fdiskSectorToCHS( hd, end, &e_cyl, &e_hd, &e_sec );
  154.     printf("%2d %2x   [%4d/%3d/%3d]  [%4d/%3d/%3d] %7d   %7d    %2x\n",
  155.            up->num.current,
  156.            up->active.current,
  157.            s_cyl, s_hd, s_sec,
  158.            e_cyl, e_hd, e_sec,
  159.            up->start.current,
  160.            up->size.current,
  161.            up->type.current);
  162.     }
  163.  
  164. }
  165. void print_user_extended_partition_table(HardDrive *hd) {
  166.     int i;
  167.     Partition *up;
  168.     unsigned int last, end;
  169.     unsigned int s_cyl, s_hd, s_sec, e_cyl, e_hd, e_sec;
  170.  
  171.     printf("Nr AF     Start C/H/S     End C/H/S      Start      Size    ID\n");
  172.     if (!hd->pep) {
  173.     printf(" No  Extended Partitions Present\n");
  174.     return;
  175.     }
  176.     
  177.     /* print extended partitions only */
  178.     fdiskLastPartition( hd, &last );
  179.     for (i=hd->pep; i<=last; i++) {
  180.     if (i!=hd->pep)
  181.         up = &hd->eptable[i];
  182.     else
  183.         up = &hd->table[i];
  184.     
  185.     if (!(up->size.current) || !(up->type.current))
  186.         continue;
  187.  
  188.     fdiskSectorToCHS( hd, up->start.current, &s_cyl, &s_hd, &s_sec );
  189.     end = up->start.current + up->size.current - 1;
  190.     fdiskSectorToCHS( hd, end, &e_cyl, &e_hd, &e_sec );
  191.     printf("%2d %2x   [%4d/%3d/%3d]  [%4d/%3d/%3d] %7d   %7d    %2x\n",
  192.            up->num.current,
  193.            up->active.current,
  194.            s_cyl, s_hd, s_sec,
  195.            e_cyl, e_hd, e_sec,
  196.            up->start.current,
  197.            up->size.current,
  198.            up->type.current);
  199.  
  200.     /* make sure we move to first extended/logical pair */
  201.     if (i==hd->pep)
  202.         i = 4;
  203.     }
  204. }
  205.  
  206.  
  207. int print_used_spacemap( HardDrive *hd ) {
  208.     unsigned int i;
  209.     SpaceMap *map;
  210.     
  211.     fdiskUsedMapGen( hd, &map );
  212.  
  213.     printf("Number           Start        End         Size\n");
  214.     for (i=0; i < map->num; i++)
  215.     printf("   %d        %7d       %7d       %7d\n",
  216.            i,
  217.            map->entry[i].start,
  218.            map->entry[i].start+map->entry[i].size,
  219.            map->entry[i].size);
  220.  
  221.     fdiskSpaceMapFree( map );
  222.  
  223.     return 0;
  224. }
  225.  
  226. int print_free_spacemap( HardDrive *hd ) {
  227.     unsigned int i;
  228.     SpaceMap *map;
  229.     
  230.     fdiskFreeMapGen( hd, &map );
  231.  
  232.     printf("Number           Start        End         Size\n");
  233.     for (i=0; i < map->num; i++)
  234.     printf("   %d        %7d       %7d       %7d\n",
  235.            i,
  236.            map->entry[i].start,
  237.            map->entry[i].start+map->entry[i].size,
  238.            map->entry[i].size);
  239.  
  240.     fdiskSpaceMapFree( map );
  241.  
  242.     return 0;
  243. }
  244.  
  245. void print_partitionspec( PartitionSpec *spec ) {
  246.     unsigned int j;
  247.     unsigned int drive;
  248.     Partition   *p;
  249.     
  250.     printf("Requested partitions: \n\n");
  251.     printf("Mount Point  Num    Drive            Size          Endcyl     Weight   Status\n");
  252.     printf("-----------  ---  ----------    --------------   ----------   ------  ---------\n");
  253.  
  254.     for (j=0; j<spec->num; j++) {
  255.     p = &spec->entry[j].partition;
  256.     printf("%11s  ", spec->entry[j].name);
  257.  
  258.     printf("%2d   ",p->num.current);
  259.     
  260.     if (fdiskDriveSetIsActive(&p->drive)) {
  261.         fdiskInitWalkDriveSet(&p->drive,&drive);
  262.         printf("%2d", drive);
  263.         do {
  264.         printf(",%2d", drive);
  265.         } while (fdiskWalkDriveSet(&p->drive,&drive)==FDISK_SUCCESS);
  266.     } else
  267.         printf("Any Drive  ");
  268.  
  269.     if (p->size.active) {
  270.         printf("%8d", p->size.min);
  271.         if (p->size.max != p->size.min)
  272.         printf("+");
  273.         else
  274.         printf(" ");
  275.         printf("/%8d", p->size.current);
  276.     }else
  277.         printf("       Not Active      ");
  278.  
  279.     if (p->endcyl.active)
  280.         printf("  <= %5d  ", p->endcyl.max);
  281.     else
  282.         printf("  Not Active");
  283.  
  284.     printf("   %5d    ", fdiskGetConstraintPriority( p ));
  285.  
  286.     if (spec->entry[j].status == REQUEST_PENDING)
  287.         printf("PENDING");
  288.     else if (spec->entry[j].status == REQUEST_DENIED)
  289.         printf("DENIED");
  290.     else if (spec->entry[j].status == REQUEST_GRANTED)
  291.         printf("GRANTED");
  292.     else if (spec->entry[j].status == REQUEST_ORIGINAL)
  293.         printf("ORIGINAL");
  294.     else
  295.         printf("UNKNOWN");
  296.  
  297.     printf("\n");
  298.     }
  299. }
  300.  
  301. /* get user params and add a partition to the HardDrive hd     */
  302. /* new partition table stored on HardDrive nhd, and partition  */
  303. /* is added to the PartitionSpec spec                          */
  304. int TestAddPartition( HardDrive **hdarr, unsigned int numhd,
  305.               HardDrive **nhdarr, PartitionSpec *spec ) {
  306.     int status;
  307.     int num;
  308.     unsigned int temp;
  309.     char *name;
  310.     Constraint tempc;
  311.     Partition p;
  312.  
  313.     /* we read in a set of constaints for the desired partition */
  314.     /* from the user, then use the auto-allocation routines to  */
  315.     /* insert it into the current partition table.              */
  316.     /*                                                          */
  317.     num = spec->num;
  318.     if (num >= MAX_PARTITION_SPEC)
  319.     return FDISK_ERR_NOFREE;
  320.  
  321.     /* start from scratch */
  322.     memset(&p, 0, sizeof(Partition));
  323.  
  324.     /* get the desired name */
  325.     printf("Enter the mount point of the partition -> ");
  326.     ReadString( &name );
  327.     if (!*name)
  328.     return FDISK_ERR_NOFREE;
  329.  
  330.     /* We REQUIRE a size */
  331.     if (ReadConstraint("Size [in kilobytes]", &tempc, 1 )) {
  332.     printf("User aborted add.\n");
  333.     free(name);
  334.     return FDISK_ERR_USERABORT; /* they aborted */
  335.     }
  336.     temp = tempc.min*2;
  337.  
  338.     printf("Should partition be allowed to grow? ");
  339.     if (!ReadBoolean())
  340.     fdiskSetConstraint(&p.size, 0, temp, temp, 1);
  341.     else
  342.     fdiskSetConstraint(&p.size, 0, temp, FDISK_SIZE_MAX, 1);
  343.     
  344.     /* We REQUIRE a type */
  345.     if (ReadConstraint("Type", &tempc, 1 )) {
  346.     printf("User aborted add.\n");
  347.     free(name);
  348.     return FDISK_ERR_USERABORT; /* they aborted */
  349.     }
  350.     temp = tempc.min;
  351.     fdiskSetConstraint(&p.type, temp, temp, temp, 1);
  352.  
  353.     status = fdiskInsertPartitionSpec( spec, name, &p, REQUEST_PENDING );
  354.  
  355.     if (status == FDISK_SUCCESS) {
  356.     status = fdiskAutoInsertPartitions( hdarr, numhd, nhdarr, spec );
  357.     printf("Status of add was %d\n",status);
  358.     }
  359.  
  360.     free(name);
  361.     return status;
  362. }
  363.  
  364. /* edit partition specs, refresh table          */
  365. int TestEditPartition( HardDrive **hdarr, unsigned int numhd,
  366.                HardDrive **nhdarr, PartitionSpec *spec ) {
  367.     int status;
  368.     int num;
  369.     unsigned int temp;
  370.     char *name;
  371.     Constraint tempc;
  372.     Partition *p;
  373.  
  374.     if ((num=spec->num) == 0)
  375.     return FDISK_ERR_BADNUM;
  376.  
  377.     /* which should we change? */
  378.     printf("Enter mount point to edit [q to exit] ->");
  379.     ReadString( &name );
  380.     
  381.     if (!*name)
  382.     return FDISK_ERR_USERABORT;
  383.  
  384.     status = fdiskReturnPartitionSpec( spec, name, &p );
  385.     if (status != FDISK_SUCCESS)
  386.     return FDISK_ERR_BADNUM;
  387.  
  388.     if (p->immutable){
  389.     free(p);
  390.     return FDISK_ERR_BADNUM;
  391.     }
  392.     
  393.     /* let them them change size or type or growability */
  394.     /* We REQUIRE a size */
  395.     if (!ReadConstraint("Size [in kilobytes]", &tempc, 1 )) {
  396.     temp = tempc.min*2;
  397.     }
  398.  
  399.     printf("Should partition be allowed to grow? ");
  400.     if (!ReadBoolean())
  401.     fdiskSetConstraint(&p->size, 0, temp, temp, 1);
  402.     else
  403.     fdiskSetConstraint(&p->size, 0, temp, FDISK_SIZE_MAX, 1);
  404.     
  405.     /* We REQUIRE a type */
  406.     if (!ReadConstraint("Type", &tempc, 1 )) {
  407.     temp = tempc.min;
  408.     fdiskSetConstraint(&p->type, temp, temp, temp, 1);
  409.     }
  410.  
  411.     status = fdiskModifyPartitionSpec( spec, name, p, REQUEST_PENDING );
  412.     
  413.     if (status == FDISK_SUCCESS) {
  414.     status = fdiskAutoInsertPartitions( hdarr, numhd, nhdarr, spec );
  415.     printf("Status of add was %d\n",status);
  416.     }
  417.  
  418.     free(name);
  419.     free(p);
  420.     return status;
  421. }
  422.  
  423.  
  424. /* delete partition specs, refresh table          */
  425. int TestDeletePartition( HardDrive **hdarr, unsigned int numhd,
  426.              HardDrive **nhdarr, PartitionSpec *spec ) {
  427.     int status;
  428.     int num;
  429.     unsigned int c, l, m;
  430.     char *name;
  431.     Partition *p;
  432.  
  433.     if ((num=spec->num) == 0)
  434.     return FDISK_ERR_BADNUM;
  435.  
  436.     /* which should we change? */
  437.     printf("Enter mount point to delete [q to exit] -> ");
  438.     ReadString( &name );
  439.     
  440.     if (!*name)
  441.     return FDISK_ERR_USERABORT;
  442.  
  443.     status = fdiskReturnPartitionSpec( spec, name, &p );
  444.     if (status != FDISK_SUCCESS)
  445.     return FDISK_ERR_BADNUM;
  446.  
  447.     if (p->immutable) {
  448.     printf("Deleting a immutable partition (ok it sounds funny haha).\n");
  449.     fdiskGetCurrentConstraint(&p->num, &c);
  450.     fdiskGetCurrentDriveSet(&p->drive, &l);
  451.     for (m=0; m<numhd; m++)
  452.         if (hdarr[m]->num == l)
  453.         break;
  454.     
  455.     fdiskRemovePartition(hdarr[m], c);
  456.  
  457.     /* make it so we can delete this partition now */
  458.     p->immutable = 0;
  459.     fdiskModifyPartitionSpec( spec, name, p, REQUEST_PENDING );
  460.     }
  461.     
  462.     status = fdiskDeletePartitionSpec( spec, name );
  463.     
  464.     if (status == FDISK_SUCCESS) {
  465.     status = fdiskAutoInsertPartitions( hdarr, numhd, nhdarr, spec );
  466.     printf("Status of add was %d\n",status);
  467.     }
  468.  
  469.     free(name);
  470.     free(p);
  471.  
  472.     fdiskCleanOriginalSpecs( hdarr, numhd, spec );
  473.     return status;
  474. }
  475.  
  476.  
  477. int main(int argc, char **argv) {
  478.     int status;
  479.     int refresh;
  480.     int done;
  481.     
  482.     HardDrive       *ohd;          /* stores the original configuration    */
  483.     HardDrive       *hd;           /* stores current immutable partitions  */
  484.     HardDrive       *nhd;          /* stores current snapshot of everything*/
  485.     HardDrive       *thd;          /* tempoary snapshot used in updates    */
  486.     PartitionSpec   spec;          /* stores all the requested partitions  */
  487.  
  488.     if (argc < 2) {
  489.     fprintf(stderr, "Need to give a device name as argument.\n");
  490.     exit(1);
  491.     }
  492.     
  493.     status=fdiskOpenDevice(argv[1], 1, &ohd);
  494.     if (status < 0) {
  495.     perror("fdiskOpenDevice");
  496.     exit(1);
  497.     } else if (status > 0) {
  498.     fprintf(stderr,"fdiskOpendevice returns error %d\n",status);
  499.     exit(1);
  500.     } else
  501.     fprintf(stderr,"fdiskOpenDevice returns successfully\n");
  502.     
  503.  
  504.     status=fdiskReadPartitions(ohd);
  505.     if (status < 0) {
  506.     perror("fdiskReadPartitions");
  507.     exit(1);
  508.     } else if (status > 0) {
  509.     fprintf(stderr,"fdiskReadPartitions returns error %d\n",status);
  510.     exit(1);
  511.     } else
  512.     fprintf(stderr,"fdiskReadPartitions returns successfully.\n");
  513.  
  514.     /* copy harddrive data into working version */
  515.     hd = (HardDrive *) alloca(sizeof(HardDrive));
  516.     nhd = (HardDrive *) alloca(sizeof(HardDrive));
  517.     thd = (HardDrive *) alloca(sizeof(HardDrive));
  518.     memcpy(hd, ohd, sizeof(HardDrive));
  519.     memcpy(nhd, ohd, sizeof(HardDrive));
  520.     
  521.     /* setup original partitions */
  522.     fdiskSetupPartitionSpec( &hd, 1, &spec );
  523.     
  524.     /* ultra-simple fdisk program */
  525.     done = 0;
  526.     refresh = 1;
  527.  
  528.     while (!done) {
  529.     char cmd[5];
  530.  
  531.     if (refresh) {
  532.         printf("\nDrive %s: Geom  %d heads, %d sectors, %d cylinders\n",
  533.            hd->name,
  534.            hd->geom.heads, hd->geom.sectors, hd->geom.cylinders);
  535.         printf("Total number of sectors is %d\n",hd->totalsectors);
  536.  
  537.         printf("\nPartition Table is currently\n---------------\n");
  538.         print_user_partition_table(nhd);
  539.         printf("-----------------\nEnd of Table\n\n");
  540.         printf("\nExtended Partition Tables are currently\n");
  541.         printf("---------------------------------------\n\n");
  542.         print_user_extended_partition_table(nhd);
  543.         printf("-----------------\nEnd of Table\n\n");
  544.         print_partitionspec( &spec );
  545.         printf("\nUsed Space Map\n---------------\n\n");
  546.         print_used_spacemap(nhd);
  547.         printf("-----------------\nEnd of Table\n\n");
  548.         printf("\nFree Space Map\n---------------\n\n");
  549.         print_free_spacemap(nhd);
  550.         printf("-----------------\nEnd of Table\n\n");
  551.         refresh = 0;
  552.     }
  553.     
  554.         printf("[a]dd [d]elete [e]dit [p]rint [v]erify [w]rite [q]uit: ");
  555.     fgets(cmd, 5, stdin);
  556.  
  557.     switch (*cmd) {
  558.       case 'd':
  559.         memcpy(thd, hd, sizeof(HardDrive));
  560.         if (TestDeletePartition( &hd, 1, &thd, &spec ) == FDISK_SUCCESS) {
  561.         memcpy(nhd, thd, sizeof(HardDrive));
  562.         refresh = 1;
  563.         } else
  564.         printf("error deleting partition\n");
  565.         break;
  566.  
  567.       case 'p':
  568.         refresh = 1;
  569.         break;
  570.  
  571.       case 'a':
  572.         memcpy(thd, hd, sizeof(HardDrive));
  573.         if (TestAddPartition(&hd, 1, &thd, &spec) == FDISK_SUCCESS) {
  574.         memcpy(nhd, thd, sizeof(HardDrive));
  575.         refresh = 1;
  576.         } else
  577.         printf("error adding partition\n");
  578.         break;
  579.  
  580.       case 'e':
  581.         memcpy(thd, hd, sizeof(HardDrive));
  582.         if (TestEditPartition( &hd, 1, &thd, &spec ) == FDISK_SUCCESS) {
  583.         memcpy(nhd, thd, sizeof(HardDrive));
  584.         refresh = 1;
  585.         } else
  586.         printf("error editting partition\n");
  587.         break;
  588.  
  589.       case 'w':
  590.         fdiskWritePartitions( nhd );
  591.         break;
  592.  
  593.       case 'q':
  594.         done = 1;
  595.         break;
  596.  
  597.       default:
  598.         printf("Unknown command!\n");
  599.         break;
  600.     }
  601.  
  602.     }
  603.         
  604.  
  605.     status=fdiskCloseDevice(ohd);
  606.     if (status < 0) {
  607.     perror("fdiskCloseDevice");
  608.     exit(1);
  609.     } else if (status > 0) {
  610.     fprintf(stderr,"fdiskCloseDevice returns error %d\n",status);
  611.     exit(1);
  612.     } else
  613.     fprintf(stderr,"fdiskCloseDevice returns successfully\n");
  614.  
  615.     exit(0);
  616. }
  617.  
  618.