-
Notifications
You must be signed in to change notification settings - Fork 0
/
dd.cpp
145 lines (123 loc) · 3.89 KB
/
dd.cpp
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
/**
* Copyright (C) 2016-2018 Xilinx, Inc
* Author: Ryan Radjabi
* Simple command line utility to inetract with SDX PCIe devices
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located 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 "dd.h"
namespace dd {
const char *ddOptString = "i:o:b:c:p:e:";
static const struct option longOpts[] = {
{ "if", required_argument, NULL, 'i' },
{ "of", required_argument, NULL, 'o' },
{ "bs", required_argument, 0, 'b' },
{ "count", required_argument, 0, 'c' },
{ "skip", required_argument, 0, 'p' },
{ "seek", required_argument, 0, 'e' }
};
/*
enum e_direction {
deviceToFile,
fileToDevice,
unset
};
static struct ddArgs_t {
bool isValid = false;
std::string file = "";
int blockSize = defaultBS;
e_direction dir;
int count = -1;
int skip = -1;
int seek = -1;
} globalArgs;
*/
/*
* parse_dd_options
*/
ddArgs_t parse_dd_options( int argc, char *argv[] )
{
int opt = 0;
int longIndex = 0;
dd::ddArgs_t args;
args.isValid = true; // assume valid, then test at the end of function
args.file = "";
args.dir = unset;
args.blockSize = 0;
args.count = 0;
args.skip = 0;
args.seek = 0;
std::string tmpInFile, tmpOutFile = "";
opt = getopt_long( argc, argv, ddOptString, longOpts, &longIndex );
while( opt != -1 ) {
switch( opt ) {
case 'i':
tmpInFile = optarg;
std::cout << "if found: " << tmpInFile << std::endl;
break;
case 'o':
tmpOutFile = optarg;
std::cout << "of found: " << tmpOutFile << std::endl;
break;
case 'b':
args.blockSize = atoi( optarg );
std::cout << "bs found: " << args.blockSize << std::endl;
break;
case 'c':
args.count = atoi( optarg );
std::cout << "count found: " << args.count << std::endl;
break;
case 'p':
args.skip = atoi( optarg ) * args.blockSize; // must be sure blockSize has been parsed first
std::cout << "skip found: " << args.skip << std::endl;
break;
case 'e':
args.seek = atoi( optarg ) * args.blockSize; // must be sure blockSize has been parsed first
std::cout << "seek found: " << args.seek << std::endl;
break;
default:
break;
}
opt = getopt_long( argc, argv, ddOptString, longOpts, &longIndex );
}
/*
* Test for legal arguments, cannot specify both 'if' and 'of'
* Must have a specified device index as -d#
*/
if( tmpInFile.empty() && !tmpOutFile.empty() ) {
// read from device into file
args.file = tmpOutFile;
args.dir = deviceToFile;
} else if ( !tmpInFile.empty() && tmpOutFile.empty() ) {
// read write to device from file
args.file = tmpInFile;
args.dir = fileToDevice;
} else {
// no legal options
args.dir = unset;
args.isValid = false;
}
// Test for legal combinations of skip/seek.
if( args.dir == deviceToFile && args.seek > 0 ) {
args.isValid = false;
}
if( args.dir == fileToDevice && args.skip > 0 ) {
args.isValid = false;
}
// Test for legal count value; must be specified for dir==deviceToFile
if( args.dir == deviceToFile && args.count < 0 ) {
args.isValid = false;
}
return args;
}
};