summaryrefslogtreecommitdiff
path: root/fpcsrc/packages/cdrom/src/cdromlin.inc
blob: f5b22faf120030730fb00f5da060d19fbe5aad59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
uses
  baseunix,
  unix,
  lincd;

Function ReadCDTOC(Device : String; Var CDTOC : Array of TTocEntry) : Integer;

Var
  I,Drive    : Integer;
  tochdr   : Tcdrom_tochdr;
  tocentry : tcdrom_tocentry;

begin
  drive:=fpOpen(Device, Open_RDONLY or Open_NONBLOCK);
  if drive<0 then
    begin
    Result:=-1;
    Exit;
    end;
  if fpioctl(drive, CDROMREADTOCHDR, @tochdr)<>0 then
    begin
    Result:=-1;
    Exit;
    end;
  If (tochdr.cdth_trk1-tochdr.cdth_trk0)>High(CDToc) then
    Result:=-2
  else
    begin
    Result:=0;
    for i := tochdr.cdth_trk0 to tochdr.cdth_trk1 do
      begin
      tocentry.cdte_track := i;
      tocentry.cdte_format := CDROM_MSF;
      fpIOCtl(drive, CDROMREADTOCENTRY, @tocentry);
      // We should do some error checking here actually.
      With cdtoc[result] do
        begin
        min := tocentry.cdte_addr.msf.minute;
        sec := tocentry.cdte_addr.msf.second;
        frame := tocentry.cdte_addr.msf.frame;
        inc(frame,min*60*75);
        inc(frame,sec*75);
        end;
      Inc(result);
      end;
    tocentry.cdte_track := $AA;
    tocentry.cdte_format := CDROM_MSF;
    fpIOCtl(drive, CDROMREADTOCENTRY, @tocentry);
    With cdtoc[Result] do
      begin
      Min := tocentry.cdte_addr.msf.minute;
      sec := tocentry.cdte_addr.msf.second;
      frame := tocentry.cdte_addr.msf.frame;
      inc(frame, min*60*75);
      inc(frame, sec*75);
      end;
    end;
  fpClose(drive);
end;

{ ---------------------------------------------------------------------
    /etc/fstab scanning.
  ---------------------------------------------------------------------}

Function ExtractDevice(S : String) : String;

Var
  P,L : Integer;

begin
  Result:='';
  P:=Pos('#',S);
  If P<>0 then
    S:=Copy(S,1,P-1);
  If Length(S)>0 then
    begin
    P:=1;
    While (P<=Length(S)) and (S[P] in [#9,' ']) do
      Inc(p);
    L:=P;
    While (L<=Length(S)) and (Not (S[L] in [#9,' '])) do
      Inc(L);
    If L>P then
      Result:=Copy(S,P,L-P);
    end;
end;

Function TestFSTab(var Devices : Array of String) : Integer;

Var
  fstab : text;
  Line : String;

begin
  Result:=0;
  Assign(FSTab,'/etc/fstab');
  {$i-}
  Reset(fstab);
  {$i+}
  If IOResult=0 then
    begin
    While Not EOF(fstab) do
      begin
      ReadLn(fsTab,Line);
      Line:=ExtractDevice(Line);
      If IsCdDevice(Line) and (Result<=High(Devices)) then
        begin
        Devices[Result]:=Line;
        inc(Result);
        end;
      end;
    Close(fstab);
    end
  else
    Result:=-1;
end;

Function GetCDRomDevices(Var Devices : Array of string) : Integer;


  Function AlreadyAdded(AName: String; AMax: Integer): Boolean;
  var
    I: Integer;
  begin
    Result := False;
    for I := 0 to AMax do
      if Devices[I] = AName then
        Exit(True);
  end;

  // Resolves name if it's a symlink and adds it ensuring no dups
  Function AddCdrom(ACDRom: String; I: Integer): Integer;
  var
    SInfo : stat;
    RealName: String;
  begin
    Result := I;
    if fpStat(PChar(ACDRom), SInfo) <> -1 then
    begin
      RealName := ACDRom;
      if SInfo.st_mode and S_IFMT = S_IFLNK then
        RealName := fpReadLink(ACDRom);

      if not AlreadyAdded(RealName, I-1) then
      begin
        Devices[I] := RealName;
        Result := I+1;
      end;
    end;
  end;

var
  I,J: Integer;
  CDRec: TCDSearchRec;
  FSTab: array[0..10] of String;

begin
  I := 0;
  // First Add Entries From FSTab
  for J := 0 to TestFSTab(FSTab)-1 do
    I := AddCdrom(FSTab[J], I);

  //Now Do A Search
  if FindFirstCD(CDRec) then
  repeat
    I := AddCdrom(CDRec.Name, I);
  until FindNextCD(CDRec) = False;
  Result := I;
end;