00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00321
00322
00323 #include "midas.h"
00324 #include "msystem.h"
00325
00326 #ifdef OS_UNIX
00327 #include <sys/mount.h>
00328 #endif
00329
00330 static INT ss_in_async_routine_flag = 0;
00331 #ifdef LOCAL_ROUTINES
00332 #include <signal.h>
00333
00334
00335
00336
00337
00338 BOOL disable_shm_write = FALSE;
00339
00340
00341 INT ss_set_async_flag(INT flag)
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 {
00362 INT old_flag;
00363
00364 old_flag = ss_in_async_routine_flag;
00365 ss_in_async_routine_flag = flag;
00366 return old_flag;
00367 }
00368
00369
00370 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 {
00395 INT status;
00396 char mem_name[256], file_name[256], path[256];
00397
00398
00399 sprintf(mem_name, "SM_%s", name);
00400
00401
00402 cm_get_path(path);
00403 if (path[0] == 0) {
00404 getcwd(path, 256);
00405 #if defined(OS_VMS)
00406 #elif defined(OS_UNIX)
00407 strcat(path, "/");
00408 #elif defined(OS_WINNT)
00409 strcat(path, "\\");
00410 #endif
00411 }
00412
00413 strcpy(file_name, path);
00414 #if defined (OS_UNIX)
00415 strcat(file_name, ".");
00416 #endif
00417 strcat(file_name, name);
00418 strcat(file_name, ".SHM");
00419
00420 #ifdef OS_WINNT
00421
00422 status = SS_SUCCESS;
00423
00424 {
00425 HANDLE hFile, hMap;
00426 char str[256], *p;
00427 DWORD file_size;
00428
00429
00430
00431
00432
00433 strcpy(str, path);
00434
00435
00436 while (strpbrk(str, "\\: "))
00437 *strpbrk(str, "\\: ") = '*';
00438 strcat(str, mem_name);
00439
00440
00441 p = str;
00442 while (*p)
00443 *p++ = (char) toupper(*p);
00444
00445 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00446 if (hMap == 0) {
00447 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00448 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00449 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00450 if (!hFile) {
00451 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00452 return SS_FILE_ERROR;
00453 }
00454
00455 file_size = GetFileSize(hFile, NULL);
00456 if (file_size != 0xFFFFFFFF && file_size > 0)
00457 size = file_size;
00458
00459 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00460
00461 if (!hMap) {
00462 status = GetLastError();
00463 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
00464 return SS_FILE_ERROR;
00465 }
00466
00467 CloseHandle(hFile);
00468 status = SS_CREATED;
00469 }
00470
00471 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00472 *handle = (HNDLE) hMap;
00473
00474 if (adr == NULL) {
00475 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00476 return SS_NO_MEMORY;
00477 }
00478
00479 return status;
00480 }
00481
00482 #endif
00483 #ifdef OS_VMS
00484
00485 status = SS_SUCCESS;
00486
00487 {
00488 int addr[2];
00489 $DESCRIPTOR(memname_dsc, "dummy");
00490 $DESCRIPTOR(filename_dsc, "dummy");
00491 memname_dsc.dsc$w_length = strlen(mem_name);
00492 memname_dsc.dsc$a_pointer = mem_name;
00493 filename_dsc.dsc$w_length = strlen(file_name);
00494 filename_dsc.dsc$a_pointer = file_name;
00495
00496 addr[0] = size;
00497 addr[1] = 0;
00498
00499 status = ppl$create_shared_memory(&memname_dsc, addr, &PPL$M_NOUNI, &filename_dsc);
00500
00501 if (status == PPL$_CREATED)
00502 status = SS_CREATED;
00503 else if (status != PPL$_NORMAL)
00504 status = SS_FILE_ERROR;
00505
00506 *adr = (void *) addr[1];
00507 *handle = 0;
00508
00509 if (adr == NULL)
00510 return SS_NO_MEMORY;
00511
00512 return status;
00513 }
00514
00515 #endif
00516 #ifdef OS_UNIX
00517
00518 status = SS_SUCCESS;
00519
00520 {
00521 int key, shmid, fh, file_size;
00522 struct shmid_ds buf;
00523
00524
00525 key = ftok(file_name, 'M');
00526
00527
00528 if (key == -1) {
00529 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00530 close(fh);
00531 key = ftok(file_name, 'M');
00532
00533 if (key == -1) {
00534 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00535 return SS_FILE_ERROR;
00536 }
00537
00538 status = SS_CREATED;
00539
00540
00541
00542 shmid = shmget(key, 0, 0);
00543 shmctl(shmid, IPC_RMID, &buf);
00544 } else {
00545
00546 file_size = (INT) ss_file_size(file_name);
00547 if (file_size > 0)
00548 size = file_size;
00549 }
00550
00551
00552 shmid = shmget(key, size, 0);
00553 if (shmid == -1) {
00554
00555 shmid = shmget(key, size, IPC_CREAT|IPC_EXCL);
00556 if (shmid == -1 && errno == EEXIST)
00557 {
00558 cm_msg(MERROR, "ss_shm_open", "Shared memory segment with key 0x%x already exists, please remove it manually: ipcrm -M 0x%x",key,key);
00559 return SS_NO_MEMORY;
00560 }
00561 status = SS_CREATED;
00562 }
00563
00564 if (shmid == -1) {
00565 cm_msg(MERROR, "ss_shm_open", "shmget(key=0x%x,size=%d) failed, errno %d (%s)", key, size, errno, strerror(errno));
00566 return SS_NO_MEMORY;
00567 }
00568
00569 buf.shm_perm.uid = getuid();
00570 buf.shm_perm.gid = getgid();
00571 buf.shm_perm.mode = 0666;
00572 shmctl(shmid, IPC_SET, &buf);
00573
00574 *adr = shmat(shmid, 0, 0);
00575 *handle = (HNDLE) shmid;
00576
00577 if ((*adr) == (void *) (-1)) {
00578 cm_msg(MERROR, "ss_shm_open","shmat(shmid=%d) failed, errno %d (%s)", shmid, errno, strerror(errno));
00579 return SS_NO_MEMORY;
00580 }
00581
00582
00583 if (status == SS_CREATED) {
00584 fh = open(file_name, O_RDONLY, 0644);
00585 if (fh == -1)
00586 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00587 else
00588 read(fh, *adr, size);
00589 close(fh);
00590 }
00591
00592 return status;
00593 }
00594
00595 #endif
00596 }
00597
00598
00599 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 {
00624 char mem_name[256], file_name[256], path[256];
00625
00626
00627
00628
00629
00630 sprintf(mem_name, "SM_%s", name);
00631
00632
00633 cm_get_path(path);
00634 if (path[0] == 0) {
00635 getcwd(path, 256);
00636 #if defined(OS_VMS)
00637 #elif defined(OS_UNIX)
00638 strcat(path, "/");
00639 #elif defined(OS_WINNT)
00640 strcat(path, "\\");
00641 #endif
00642 }
00643
00644 strcpy(file_name, path);
00645 #if defined (OS_UNIX)
00646 strcat(file_name, ".");
00647 #endif
00648 strcat(file_name, name);
00649 strcat(file_name, ".SHM");
00650
00651 #ifdef OS_WINNT
00652
00653 if (!UnmapViewOfFile(adr))
00654 return SS_INVALID_ADDRESS;
00655
00656 CloseHandle((HANDLE) handle);
00657
00658 return SS_SUCCESS;
00659
00660 #endif
00661 #ifdef OS_VMS
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 return SS_INVALID_ADDRESS;
00686
00687 #endif
00688 #ifdef OS_UNIX
00689
00690 {
00691 struct shmid_ds buf;
00692 FILE *fh;
00693
00694
00695 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00696 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_STAT) failed, errno %d (%s)",handle,errno,strerror(errno));
00697 return SS_INVALID_HANDLE;
00698 }
00699
00700
00701 if (buf.shm_nattch == 1) {
00702 if (!disable_shm_write) {
00703 fh = fopen(file_name, "w");
00704
00705 if (fh == NULL) {
00706 cm_msg(MERROR, "ss_shm_close",
00707 "Cannot write to file %s, please check protection", file_name);
00708 } else {
00709
00710 fwrite(adr, 1, buf.shm_segsz, fh);
00711 fclose(fh);
00712 }
00713 }
00714
00715 if (shmdt(adr) < 0) {
00716 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00717 return SS_INVALID_ADDRESS;
00718 }
00719
00720 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00721 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_RMID) failed, errno %d (%s)",handle,errno,strerror(errno));
00722 return SS_INVALID_ADDRESS;
00723 }
00724 } else
00725
00726 if (shmdt(adr) < 0) {
00727 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00728 return SS_INVALID_ADDRESS;
00729 }
00730
00731 return SS_SUCCESS;
00732 }
00733
00734 #endif
00735 }
00736
00737
00738 INT ss_shm_protect(HNDLE handle, void *adr)
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 {
00759 #ifdef OS_WINNT
00760
00761 if (!UnmapViewOfFile(adr))
00762 return SS_INVALID_ADDRESS;
00763
00764 #endif
00765 #ifdef OS_UNIX
00766
00767 if (shmdt(adr) < 0) {
00768 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00769 return SS_INVALID_ADDRESS;
00770 }
00771 #endif
00772 return SS_SUCCESS;
00773 }
00774
00775
00776 INT ss_shm_unprotect(HNDLE handle, void **adr)
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 {
00797 #ifdef OS_WINNT
00798
00799 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00800
00801 if (*adr == NULL) {
00802 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00803 return SS_NO_MEMORY;
00804 }
00805 #endif
00806 #ifdef OS_UNIX
00807
00808 *adr = shmat(handle, 0, 0);
00809
00810 if ((*adr) == (void *) (-1)) {
00811 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
00812 return SS_NO_MEMORY;
00813 }
00814 #endif
00815
00816 return SS_SUCCESS;
00817 }
00818
00819
00820 INT ss_shm_flush(char *name, void *adr, INT size)
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 {
00841 char mem_name[256], file_name[256], path[256];
00842
00843
00844
00845
00846
00847 sprintf(mem_name, "SM_%s", name);
00848
00849
00850 cm_get_path(path);
00851 if (path[0] == 0) {
00852 getcwd(path, 256);
00853 #if defined(OS_VMS)
00854 #elif defined(OS_UNIX)
00855 strcat(path, "/");
00856 #elif defined(OS_WINNT)
00857 strcat(path, "\\");
00858 #endif
00859 }
00860
00861 strcpy(file_name, path);
00862 #if defined (OS_UNIX)
00863 strcat(file_name, ".");
00864 #endif
00865 strcat(file_name, name);
00866 strcat(file_name, ".SHM");
00867
00868 #ifdef OS_WINNT
00869
00870 if (!FlushViewOfFile(adr, size))
00871 return SS_INVALID_ADDRESS;
00872
00873 return SS_SUCCESS;
00874
00875 #endif
00876 #ifdef OS_VMS
00877
00878 return SS_SUCCESS;
00879
00880 #endif
00881 #ifdef OS_UNIX
00882
00883 if (!disable_shm_write) {
00884 FILE *fh;
00885
00886 fh = fopen(file_name, "w");
00887
00888 if (fh == NULL) {
00889 cm_msg(MERROR, "ss_shm_flush",
00890 "Cannot write to file %s, please check protection", file_name);
00891 } else {
00892
00893 fwrite(adr, 1, size, fh);
00894 fclose(fh);
00895 }
00896 }
00897 return SS_SUCCESS;
00898
00899 #endif
00900 }
00901
00902
00903 INT ss_getthandle(void)
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920 {
00921 #ifdef OS_WINNT
00922 HANDLE hThread;
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00934 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS, TRUE, 0);
00935
00936 return (INT)hThread;
00937
00938 #endif
00939 #ifdef OS_VMS
00940
00941 return 0;
00942
00943 #endif
00944 #ifdef OS_UNIX
00945
00946 return ss_getpid();
00947
00948 #endif
00949 }
00950
00951 #endif
00952
00953
00954 struct {
00955 char c;
00956 double d;
00957 } test_align;
00958
00959 INT ss_get_struct_align()
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 {
00982 return (PTYPE) (&test_align.d) - (PTYPE) & test_align.c;
00983 }
00984
00985
00986 INT ss_getpid(void)
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 {
01004 #ifdef OS_WINNT
01005
01006 return (int) GetCurrentProcessId();
01007
01008 #endif
01009 #ifdef OS_VMS
01010
01011 return getpid();
01012
01013 #endif
01014 #ifdef OS_UNIX
01015
01016 return getpid();
01017
01018 #endif
01019 #ifdef OS_VXWORKS
01020
01021 return 0;
01022
01023 #endif
01024 #ifdef OS_MSDOS
01025
01026 return 0;
01027
01028 #endif
01029 }
01030
01031
01032
01033 static BOOL _single_thread = FALSE;
01034
01035 void ss_force_single_thread()
01036 {
01037 _single_thread = TRUE;
01038 }
01039
01040 INT ss_gettid(void)
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 {
01058
01059 if (_single_thread)
01060 return 1;
01061
01062 #ifdef OS_MSDOS
01063
01064 return 0;
01065
01066 #endif
01067 #ifdef OS_WINNT
01068
01069 return (int) GetCurrentThreadId();
01070
01071 #endif
01072 #ifdef OS_VMS
01073
01074 return ss_getpid();
01075
01076 #endif
01077 #ifdef OS_UNIX
01078
01079 return ss_getpid();
01080
01081 #endif
01082 #ifdef OS_VXWORKS
01083
01084 return ss_getpid();
01085
01086 #endif
01087 }
01088
01089
01090
01091 #ifdef OS_UNIX
01092 void catch_sigchld(int signo)
01093 {
01094 int status;
01095
01096 wait(&status);
01097 return;
01098 }
01099 #endif
01100
01101 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 {
01125 #ifdef OS_WINNT
01126
01127 if (spawnvp(mode, cmdname, argv) < 0)
01128 return SS_INVALID_NAME;
01129
01130 return SS_SUCCESS;
01131
01132 #endif
01133
01134 #ifdef OS_MSDOS
01135
01136 spawnvp((int) mode, cmdname, argv);
01137
01138 return SS_SUCCESS;
01139
01140 #endif
01141
01142 #ifdef OS_VMS
01143
01144 {
01145 char cmdstring[500], *pc;
01146 INT i, flags, status;
01147 va_list argptr;
01148
01149 $DESCRIPTOR(cmdstring_dsc, "dummy");
01150
01151 if (mode & P_DETACH) {
01152 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01153 cmdstring_dsc.dsc$a_pointer = cmdstring;
01154
01155 status = sys$creprc(0, &cmdstring_dsc,
01156 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
01157 } else {
01158 flags = (mode & P_NOWAIT) ? 1 : 0;
01159
01160 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
01161 if (*pc == ']')
01162 pc++;
01163
01164 strcpy(cmdstring, pc);
01165
01166 if (strchr(cmdstring, ';'))
01167 *strchr(cmdstring, ';') = 0;
01168
01169 strcat(cmdstring, " ");
01170
01171 for (i = 1; argv[i] != NULL; i++) {
01172 strcat(cmdstring, argv[i]);
01173 strcat(cmdstring, " ");
01174 }
01175
01176 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01177 cmdstring_dsc.dsc$a_pointer = cmdstring;
01178
01179 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
01180 }
01181
01182 return BM_SUCCESS;
01183 }
01184
01185 #endif
01186 #ifdef OS_UNIX
01187 pid_t child_pid;
01188
01189 #ifdef OS_ULTRIX
01190 union wait *status;
01191 #else
01192 int status;
01193 #endif
01194
01195 if ((child_pid = fork()) < 0)
01196 return (-1);
01197
01198 if (child_pid == 0) {
01199
01200 child_pid = execvp(cmdname, argv);
01201 return SS_SUCCESS;
01202 } else {
01203
01204 if (mode == P_WAIT)
01205 #ifdef OS_ULTRIX
01206 waitpid(child_pid, status, WNOHANG);
01207 #else
01208 waitpid(child_pid, &status, WNOHANG);
01209 #endif
01210
01211 else
01212
01213 signal(SIGCHLD, catch_sigchld);
01214 }
01215
01216 return SS_SUCCESS;
01217
01218 #endif
01219 }
01220
01221
01222 INT ss_shell(int sock)
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239 {
01240 #ifdef OS_WINNT
01241
01242 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
01243 hChildStdoutRd, hChildStdoutWr,
01244 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
01245
01246 SECURITY_ATTRIBUTES saAttr;
01247 PROCESS_INFORMATION piProcInfo;
01248 STARTUPINFO siStartInfo;
01249 char buffer[256], cmd[256];
01250 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
01251 fd_set readfds;
01252 struct timeval timeout;
01253
01254
01255 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
01256 saAttr.bInheritHandle = TRUE;
01257 saAttr.lpSecurityDescriptor = NULL;
01258
01259
01260 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
01261
01262
01263 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
01264 return 0;
01265
01266
01267 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
01268 return 0;
01269
01270
01271
01272 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
01273
01274
01275 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01276 return 0;
01277
01278
01279 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01280 return 0;
01281
01282
01283
01284 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01285
01286
01287 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01288 return 0;
01289
01290
01291 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01292 return 0;
01293
01294
01295 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01296 DUPLICATE_SAME_ACCESS))
01297 return 0;
01298
01299 CloseHandle(hChildStdinWr);
01300
01301
01302 memset(&siStartInfo, 0, sizeof(siStartInfo));
01303 siStartInfo.cb = sizeof(STARTUPINFO);
01304 siStartInfo.lpReserved = NULL;
01305 siStartInfo.lpReserved2 = NULL;
01306 siStartInfo.cbReserved2 = 0;
01307 siStartInfo.lpDesktop = NULL;
01308 siStartInfo.dwFlags = 0;
01309
01310 if (!CreateProcess(NULL, "cmd /Q",
01311 NULL,
01312 NULL,
01313 TRUE,
01314 0,
01315 NULL,
01316 NULL,
01317 &siStartInfo,
01318 &piProcInfo))
01319 return 0;
01320
01321
01322 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01323 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01324 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01325
01326 i_cmd = 0;
01327
01328 do {
01329
01330 do {
01331 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01332 break;
01333
01334 if (dwRead > 0) {
01335 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01336 send(sock, buffer, dwRead, 0);
01337 }
01338 } while (dwAvail > 0);
01339
01340
01341 do {
01342 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01343 break;
01344 if (dwRead > 0) {
01345 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01346 send(sock, buffer, dwRead, 0);
01347 }
01348 } while (dwAvail > 0);
01349
01350
01351
01352 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01353 break;
01354 if (i != STILL_ACTIVE)
01355 break;
01356
01357
01358 FD_ZERO(&readfds);
01359 FD_SET(sock, &readfds);
01360 timeout.tv_sec = 0;
01361 timeout.tv_usec = 100;
01362 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01363
01364 if (FD_ISSET(sock, &readfds)) {
01365 i = recv(sock, cmd + i_cmd, 1, 0);
01366 if (i <= 0)
01367 break;
01368
01369
01370 if (cmd[i_cmd] == 8) {
01371 if (i_cmd > 0) {
01372 send(sock, "\b \b", 3, 0);
01373 i_cmd -= 1;
01374 }
01375 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01376 send(sock, cmd + i_cmd, 1, 0);
01377 i_cmd += i;
01378 }
01379 }
01380
01381
01382 if (cmd[i_cmd - 1] == 10) {
01383 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01384 i_cmd = 0;
01385 }
01386
01387 } while (TRUE);
01388
01389 CloseHandle(hChildStdinWrDup);
01390 CloseHandle(hChildStdinRd);
01391 CloseHandle(hChildStderrRd);
01392 CloseHandle(hChildStdoutRd);
01393
01394 return SS_SUCCESS;
01395
01396 #endif
01397
01398 #ifdef OS_UNIX
01399 #ifndef NO_PTY
01400 pid_t pid;
01401 int i, pipe;
01402 char line[32], buffer[1024], shell[32];
01403 fd_set readfds;
01404
01405 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01406 return 0;
01407 else if (pid > 0) {
01408
01409
01410 do {
01411 FD_ZERO(&readfds);
01412 FD_SET(sock, &readfds);
01413 FD_SET(pipe, &readfds);
01414
01415 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01416
01417 if (FD_ISSET(sock, &readfds)) {
01418 memset(buffer, 0, sizeof(buffer));
01419 i = recv(sock, buffer, sizeof(buffer), 0);
01420 if (i <= 0)
01421 break;
01422 if (write(pipe, buffer, i) != i)
01423 break;
01424 }
01425
01426 if (FD_ISSET(pipe, &readfds)) {
01427 memset(buffer, 0, sizeof(buffer));
01428 i = read(pipe, buffer, sizeof(buffer));
01429 if (i <= 0)
01430 break;
01431 send(sock, buffer, i, 0);
01432 }
01433
01434 } while (1);
01435 } else {
01436
01437
01438 if (getenv("SHELL"))
01439 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01440 else
01441 strcpy(shell, "/bin/sh");
01442 execl(shell, shell, 0);
01443 }
01444 #else
01445 send(sock, "not implemented\n", 17, 0);
01446 #endif
01447
01448 return SS_SUCCESS;
01449
01450 #endif
01451 }
01452
01453
01454 static BOOL _daemon_flag;
01455
01456 INT ss_daemon_init(BOOL keep_stdout)
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474 {
01475 #ifdef OS_UNIX
01476
01477
01478 int i, fd, pid;
01479
01480 if ((pid = fork()) < 0)
01481 return SS_ABORT;
01482 else if (pid != 0)
01483 exit(0);
01484
01485
01486
01487 _daemon_flag = TRUE;
01488
01489
01490
01491 for (i = 0; i < 3; i++) {
01492 if (keep_stdout && ((i == 1) || (i == 2)))
01493 continue;
01494
01495 close(i);
01496 fd = open("/dev/null", O_RDWR, 0);
01497 if (fd < 0)
01498 fd = open("/dev/null", O_WRONLY, 0);
01499 if (fd < 0) {
01500 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01501 return SS_ABORT;
01502 }
01503 if (fd != i) {
01504 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01505 return SS_ABORT;
01506 }
01507 }
01508
01509 setsid();
01510 chdir("/");
01511 umask(0);
01512
01513 #endif
01514
01515 return SS_SUCCESS;
01516 }
01517
01518
01519 BOOL ss_existpid(INT pid)
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537 {
01538 #ifdef OS_UNIX
01539
01540 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01541 #else
01542 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01543 return FALSE;
01544 #endif
01545 }
01546
01547
01548
01549 #endif
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 INT ss_system(char *command)
01570 {
01571 #ifdef OS_UNIX
01572 INT childpid;
01573
01574 return ss_exec(command, &childpid);
01575
01576 #else
01577
01578 system(command);
01579 return SS_SUCCESS;
01580
01581 #endif
01582 }
01583
01584
01585 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01586
01587
01588 INT ss_exec(char *command, INT * pid)
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607 {
01608 #ifdef OS_UNIX
01609
01610
01611 int i, fd;
01612
01613 if ((*pid = fork()) < 0)
01614 return SS_ABORT;
01615 else if (*pid != 0) {
01616
01617 signal(SIGCHLD, catch_sigchld);
01618 return SS_SUCCESS;
01619 }
01620
01621
01622
01623
01624 for (i = 0; i < 256; i++)
01625 close(i);
01626
01627
01628
01629 for (i = 0; i < 3; i++) {
01630 fd = open("/dev/null", O_RDWR, 0);
01631 if (fd < 0)
01632 fd = open("/dev/null", O_WRONLY, 0);
01633 if (fd < 0) {
01634 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01635 return SS_ABORT;
01636 }
01637 if (fd != i) {
01638 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01639 return SS_ABORT;
01640 }
01641 }
01642
01643 setsid();
01644
01645 umask(0);
01646
01647
01648 execl("/bin/sh", "sh", "-c", command, NULL);
01649
01650 #else
01651
01652 system(command);
01653
01654 #endif
01655
01656 return SS_SUCCESS;
01657 }
01658
01659
01660 #endif
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695 midas_thread_t ss_thread_create(INT(*thread_func) (void *), void *param)
01696 {
01697 #if defined(OS_WINNT)
01698
01699 HANDLE status;
01700 DWORD thread_id;
01701
01702 if (thread_func == NULL) {
01703 return 0;
01704 }
01705
01706 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01707 (LPVOID) param, 0, &thread_id);
01708
01709 return status == NULL ? 0 : (midas_thread_t)thread_id;
01710
01711 #elif defined(OS_MSDOS)
01712
01713 return 0;
01714
01715 #elif defined(OS_VMS)
01716
01717 return 0;
01718
01719 #elif defined(OS_VXWORKS)
01720
01721
01722
01723
01724
01725
01726
01727
01728 INT status;
01729 VX_TASK_SPAWN *ts;
01730
01731 ts = (VX_TASK_SPAWN *) param;
01732 status =
01733 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01734 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01735 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
01736
01737 return status == ERROR ? 0 : status;
01738
01739 #elif defined(OS_UNIX)
01740
01741 INT status;
01742 pthread_t thread_id;
01743
01744 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01745
01746 return status != 0 ? 0 : thread_id;
01747
01748 #endif
01749 }
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 INT ss_thread_kill(midas_thread_t thread_id)
01770 {
01771 #if defined(OS_WINNT)
01772
01773 DWORD status;
01774
01775 status = TerminateThread(thread_id, 0);
01776
01777 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01778
01779 #elif defined(OS_MSDOS)
01780
01781 return 0;
01782
01783 #elif defined(OS_VMS)
01784
01785 return 0;
01786
01787 #elif defined(OS_VXWORKS)
01788
01789 INT status;
01790 status = taskDelete(thread_id);
01791 return status == OK ? 0 : ERROR;
01792
01793 #elif defined(OS_UNIX)
01794
01795 INT status;
01796 status = pthread_kill(thread_id, SIGKILL);
01797 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01798
01799 #endif
01800 }
01801
01802
01803 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01804
01805
01806 static INT skip_mutex_handle = -1;
01807
01808 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835 {
01836 char mutex_name[256], path[256], file_name[256];
01837
01838
01839 sprintf(mutex_name, "MX_%s", name);
01840
01841 #ifdef OS_VXWORKS
01842
01843
01844
01845 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01846 return SS_NO_MUTEX;
01847 return SS_CREATED;
01848
01849 #endif
01850
01851
01852 cm_get_path(path);
01853 if (path[0] == 0) {
01854 getcwd(path, 256);
01855 #if defined(OS_VMS)
01856 #elif defined(OS_UNIX)
01857 strcat(path, "/");
01858 #elif defined(OS_WINNT)
01859 strcat(path, "\\");
01860 #endif
01861 }
01862
01863 strcpy(file_name, path);
01864 #if defined (OS_UNIX)
01865 strcat(file_name, ".");
01866 #endif
01867 strcat(file_name, name);
01868 strcat(file_name, ".SHM");
01869
01870 #ifdef OS_WINNT
01871
01872 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01873
01874 if (*mutex_handle == 0)
01875 return SS_NO_MUTEX;
01876
01877 return SS_CREATED;
01878
01879 #endif
01880 #ifdef OS_VMS
01881
01882
01883
01884 {
01885 INT status;
01886 $DESCRIPTOR(mutexname_dsc, "dummy");
01887 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01888 mutexname_dsc.dsc$a_pointer = mutex_name;
01889
01890 *mutex_handle = (HNDLE) malloc(8);
01891
01892 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01893 0, 0, 0, 0, 0, 0);
01894
01895 if (status != SS$_NORMAL) {
01896 free((void *) *mutex_handle);
01897 *mutex_handle = 0;
01898 }
01899
01900 if (*mutex_handle == 0)
01901 return SS_NO_MUTEX;
01902
01903 return SS_CREATED;
01904 }
01905
01906 #endif
01907 #ifdef OS_UNIX
01908
01909 {
01910 INT key, status, fh;
01911 struct semid_ds buf;
01912
01913 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01914 union semun arg;
01915 #else
01916 union semun {
01917 INT val;
01918 struct semid_ds *buf;
01919 ushort *array;
01920 } arg;
01921 #endif
01922
01923 status = SS_SUCCESS;
01924
01925
01926 key = ftok(file_name, 'M');
01927 if (key < 0) {
01928 fh = open(file_name, O_CREAT, 0644);
01929 close(fh);
01930 key = ftok(file_name, 'M');
01931 status = SS_CREATED;
01932 }
01933
01934
01935 *mutex_handle = (HNDLE) semget(key, 1, 0);
01936 if (*mutex_handle < 0) {
01937 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01938 status = SS_CREATED;
01939 }
01940
01941 if (*mutex_handle < 0) {
01942 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d", errno);
01943 return SS_NO_MUTEX;
01944 }
01945
01946 buf.sem_perm.uid = getuid();
01947 buf.sem_perm.gid = getgid();
01948 buf.sem_perm.mode = 0666;
01949 arg.buf = &buf;
01950
01951 semctl(*mutex_handle, 0, IPC_SET, arg);
01952
01953
01954 if (status == SS_CREATED) {
01955 arg.val = 1;
01956 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01957 return SS_NO_MUTEX;
01958 }
01959
01960 return SS_SUCCESS;
01961 }
01962 #endif
01963
01964 #ifdef OS_MSDOS
01965 return SS_NO_MUTEX;
01966 #endif
01967 }
01968
01969
01970 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990 {
01991 INT status;
01992
01993 #ifdef OS_WINNT
01994
01995 status = WaitForSingleObject((HANDLE) mutex_handle, timeout == 0 ? INFINITE : timeout);
01996 if (status == WAIT_FAILED)
01997 return SS_NO_MUTEX;
01998 if (status == WAIT_TIMEOUT)
01999 return SS_TIMEOUT;
02000
02001 return SS_SUCCESS;
02002 #endif
02003 #ifdef OS_VMS
02004 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02005 if (status != SS$_NORMAL)
02006 return SS_NO_MUTEX;
02007 return SS_SUCCESS;
02008
02009 #endif
02010 #ifdef OS_VXWORKS
02011
02012 status = semTake((SEM_ID) mutex_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
02013 if (status == ERROR)
02014 return SS_NO_MUTEX;
02015 return SS_SUCCESS;
02016
02017 #endif
02018 #ifdef OS_UNIX
02019 {
02020 DWORD start_time;
02021 struct sembuf sb;
02022
02023 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02024 union semun arg;
02025 #else
02026 union semun {
02027 INT val;
02028 struct semid_ds *buf;
02029 ushort *array;
02030 } arg;
02031 #endif
02032
02033 sb.sem_num = 0;
02034 sb.sem_op = -1;
02035 sb.sem_flg = SEM_UNDO;
02036
02037 memset(&arg, 0, sizeof(arg));
02038
02039
02040
02041 if (ss_in_async_routine_flag)
02042 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
02043 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
02044 skip_mutex_handle = mutex_handle;
02045 return SS_SUCCESS;
02046 }
02047
02048 skip_mutex_handle = -1;
02049
02050 start_time = ss_millitime();
02051
02052 do {
02053 status = semop(mutex_handle, &sb, 1);
02054
02055
02056 if (status == 0)
02057 break;
02058
02059
02060 if (errno == EINTR) {
02061
02062 if (timeout > 0 && ss_millitime() - start_time > timeout)
02063 return SS_TIMEOUT;
02064
02065 continue;
02066 }
02067
02068 return SS_NO_MUTEX;
02069 } while (1);
02070
02071 return SS_SUCCESS;
02072 }
02073 #endif
02074
02075 #ifdef OS_MSDOS
02076 return SS_NO_MUTEX;
02077 #endif
02078 }
02079
02080
02081 INT ss_mutex_release(HNDLE mutex_handle)
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099 {
02100 INT status;
02101
02102 #ifdef OS_WINNT
02103
02104 status = ReleaseMutex((HANDLE) mutex_handle);
02105
02106 if (status == FALSE)
02107 return SS_NO_MUTEX;
02108
02109 return SS_SUCCESS;
02110
02111 #endif
02112 #ifdef OS_VMS
02113
02114 status = sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02115
02116 if (status != SS$_NORMAL)
02117 return SS_NO_MUTEX;
02118
02119 return SS_SUCCESS;
02120
02121 #endif
02122
02123 #ifdef OS_VXWORKS
02124
02125 if (semGive((SEM_ID) mutex_handle) == ERROR)
02126 return SS_NO_MUTEX;
02127 return SS_SUCCESS;
02128 #endif
02129
02130 #ifdef OS_UNIX
02131 {
02132 struct sembuf sb;
02133
02134 sb.sem_num = 0;
02135 sb.sem_op = 1;
02136 sb.sem_flg = SEM_UNDO;
02137
02138 if (mutex_handle == skip_mutex_handle) {
02139 skip_mutex_handle = -1;
02140 return SS_SUCCESS;
02141 }
02142
02143 do {
02144 status = semop(mutex_handle, &sb, 1);
02145
02146
02147 if (status == 0)
02148 break;
02149
02150
02151 if (errno == EINTR)
02152 continue;
02153
02154 return SS_NO_MUTEX;
02155 } while (1);
02156
02157 return SS_SUCCESS;
02158 }
02159 #endif
02160
02161 #ifdef OS_MSDOS
02162 return SS_NO_MUTEX;
02163 #endif
02164 }
02165
02166
02167 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 {
02186 #ifdef OS_WINNT
02187
02188 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
02189 return SS_NO_MUTEX;
02190
02191 return SS_SUCCESS;
02192
02193 #endif
02194 #ifdef OS_VMS
02195
02196 free((void *) mutex_handle);
02197 return SS_SUCCESS;
02198
02199 #endif
02200
02201 #ifdef OS_VXWORKS
02202
02203 if (semDelete((SEM_ID) mutex_handle) == ERROR)
02204 return SS_NO_MUTEX;
02205 return SS_SUCCESS;
02206 #endif
02207
02208 #ifdef OS_UNIX
02209 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02210 union semun arg;
02211 #else
02212 union semun {
02213 INT val;
02214 struct semid_ds *buf;
02215 ushort *array;
02216 } arg;
02217 #endif
02218
02219 memset(&arg, 0, sizeof(arg));
02220
02221 if (destroy_flag)
02222 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
02223 return SS_NO_MUTEX;
02224
02225 return SS_SUCCESS;
02226
02227 #endif
02228
02229 #ifdef OS_MSDOS
02230 return SS_NO_MUTEX;
02231 #endif
02232 }
02233
02234
02235 #endif
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255 DWORD ss_millitime()
02256 {
02257 #ifdef OS_WINNT
02258
02259 return (int) GetTickCount();
02260
02261 #endif
02262 #ifdef OS_MSDOS
02263
02264 return clock() * 55;
02265
02266 #endif
02267 #ifdef OS_VMS
02268
02269 {
02270 char time[8];
02271 DWORD lo, hi;
02272
02273 sys$gettim(time);
02274
02275 lo = *((DWORD *) time);
02276 hi = *((DWORD *) (time + 4));
02277
02278
02279
02280 return lo / 10000 + hi * 429496.7296;
02281
02282 }
02283
02284 #endif
02285 #ifdef OS_UNIX
02286 {
02287 struct timeval tv;
02288
02289 gettimeofday(&tv, NULL);
02290
02291 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02292 }
02293
02294 #endif
02295 #ifdef OS_VXWORKS
02296 {
02297 int count;
02298 static int ticks_per_msec = 0;
02299
02300 if (ticks_per_msec == 0)
02301 ticks_per_msec = 1000 / sysClkRateGet();
02302
02303 return tickGet() * ticks_per_msec;
02304 }
02305 #endif
02306 }
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322 DWORD ss_time()
02323 {
02324 #if !defined(OS_VXWORKS)
02325 #if !defined(OS_VMS)
02326 tzset();
02327 #endif
02328 #endif
02329 return (DWORD) time(NULL);
02330 }
02331
02332
02333 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02334
02335
02336 DWORD ss_settime(DWORD seconds)
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352 {
02353 #if defined(OS_WINNT)
02354 SYSTEMTIME st;
02355 struct tm *ltm;
02356
02357 tzset();
02358 ltm = localtime((time_t *) & seconds);
02359
02360 st.wYear = ltm->tm_year + 1900;
02361 st.wMonth = ltm->tm_mon + 1;
02362 st.wDay = ltm->tm_mday;
02363 st.wHour = ltm->tm_hour;
02364 st.wMinute = ltm->tm_min;
02365 st.wSecond = ltm->tm_sec;
02366 st.wMilliseconds = 0;
02367
02368 SetLocalTime(&st);
02369
02370 #elif defined(OS_DARWIN)
02371
02372 assert(!"ss_settime() is not supported");
02373
02374 return SS_NO_DRIVER;
02375
02376 #elif defined(OS_UNIX)
02377
02378 stime((time_t *) & seconds);
02379
02380 #elif defined(OS_VXWORKS)
02381
02382 struct timespec ltm;
02383
02384 ltm.tv_sec = seconds;
02385 ltm.tv_nsec = 0;
02386 clock_settime(CLOCK_REALTIME, <m);
02387
02388 #endif
02389 return SS_SUCCESS;
02390 }
02391
02392
02393 char *ss_asctime()
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410 {
02411 static char str[32];
02412 time_t seconds;
02413
02414 seconds = (time_t) ss_time();
02415
02416 #if !defined(OS_VXWORKS)
02417 #if !defined(OS_VMS)
02418 tzset();
02419 #endif
02420 #endif
02421 strcpy(str, asctime(localtime(&seconds)));
02422
02423
02424 str[24] = 0;
02425
02426 return str;
02427 }
02428
02429
02430 INT ss_timezone()
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448 {
02449 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
02450 return 0;
02451 #else
02452 return timezone;
02453 #endif
02454 }
02455
02456
02457
02458
02459 #ifdef OS_UNIX
02460
02461 void ss_cont()
02462 {
02463 }
02464 #endif
02465
02466
02467 #endif
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481 INT ss_sleep(INT millisec)
02482 {
02483 fd_set readfds;
02484 struct timeval timeout;
02485 int status;
02486 static int sock = 0;
02487
02488 if (millisec == 0) {
02489 #ifdef OS_WINNT
02490 SuspendThread(GetCurrentThread());
02491 #endif
02492 #ifdef OS_VMS
02493 sys$hiber();
02494 #endif
02495 #ifdef OS_UNIX
02496 signal(SIGCONT, ss_cont);
02497 pause();
02498 #endif
02499 return SS_SUCCESS;
02500 }
02501 #ifdef OS_WINNT
02502 {
02503 WSADATA WSAData;
02504
02505
02506 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02507 return SS_SOCKET_ERROR;
02508 }
02509 #endif
02510
02511 timeout.tv_sec = millisec / 1000;
02512 timeout.tv_usec = (millisec % 1000) * 1000;
02513
02514 if (!sock)
02515 sock = socket(AF_INET, SOCK_DGRAM, 0);
02516
02517 FD_ZERO(&readfds);
02518 FD_SET(sock, &readfds);
02519 do {
02520 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02521
02522
02523 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02524 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02525
02526 } while (status == -1);
02527
02528 return SS_SUCCESS;
02529 }
02530
02531
02532 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02533
02534
02535 BOOL ss_kbhit()
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553 {
02554 #ifdef OS_MSDOS
02555
02556 return kbhit();
02557
02558 #endif
02559 #ifdef OS_WINNT
02560
02561 return kbhit();
02562
02563 #endif
02564 #ifdef OS_VMS
02565
02566 return FALSE;
02567
02568 #endif
02569 #ifdef OS_UNIX
02570
02571 int n;
02572
02573 if (_daemon_flag)
02574 return 0;
02575
02576 ioctl(0, FIONREAD, &n);
02577 return (n > 0);
02578
02579 #endif
02580 #ifdef OS_VXWORKS
02581
02582 int n;
02583 ioctl(0, FIONREAD, (long) &n);
02584 return (n > 0);
02585
02586 #endif
02587 }
02588
02589
02590
02591 #ifdef LOCAL_ROUTINES
02592
02593 INT ss_wake(INT pid, INT tid, INT thandle)
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615 {
02616 #ifdef OS_WINNT
02617 HANDLE process_handle;
02618 HANDLE dup_thread_handle;
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02630
02631 if (process_handle == 0)
02632 return SS_NO_PROCESS;
02633
02634 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02635 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02636
02637
02638 CloseHandle(process_handle);
02639
02640 if (dup_thread_handle == 0)
02641 return SS_NO_PROCESS;
02642
02643 ResumeThread(dup_thread_handle);
02644
02645
02646 CloseHandle(dup_thread_handle);
02647
02648 return SS_SUCCESS;
02649
02650 #endif
02651 #ifdef OS_VMS
02652
02653 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02654 return SS_NO_PROCESS;
02655
02656 return SS_SUCCESS;
02657
02658 #endif
02659 #ifdef OS_UNIX
02660
02661 if (kill(pid, SIGCONT) < 0)
02662 return SS_NO_PROCESS;
02663
02664 return SS_SUCCESS;
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674 #endif
02675 }
02676
02677
02678 #ifdef OS_WINNT
02679
02680 static void (*UserCallback) (int);
02681 static UINT _timer_id = 0;
02682
02683 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02684 DWORD dwReserved1, DWORD dwReserved2)
02685 {
02686 _timer_id = 0;
02687 if (UserCallback != NULL)
02688 UserCallback(0);
02689 }
02690
02691 #endif
02692
02693 INT ss_alarm(INT millitime, void (*func) (int))
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713 {
02714 #ifdef OS_WINNT
02715
02716 UserCallback = func;
02717 if (millitime > 0)
02718 _timer_id =
02719 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
02720 else {
02721 if (_timer_id)
02722 timeKillEvent(_timer_id);
02723 _timer_id = 0;
02724 }
02725
02726 return SS_SUCCESS;
02727
02728 #endif
02729 #ifdef OS_VMS
02730
02731 signal(SIGALRM, func);
02732 alarm(millitime / 1000);
02733 return SS_SUCCESS;
02734
02735 #endif
02736 #ifdef OS_UNIX
02737
02738 signal(SIGALRM, func);
02739 alarm(millitime / 1000);
02740 return SS_SUCCESS;
02741
02742 #endif
02743 }
02744
02745
02746 void (*MidasExceptionHandler) ();
02747
02748 #ifdef OS_WINNT
02749
02750 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02751 {
02752 if (MidasExceptionHandler != NULL)
02753 MidasExceptionHandler();
02754
02755 return EXCEPTION_CONTINUE_SEARCH;
02756 }
02757
02758 INT MidasExceptionSignal(INT sig)
02759 {
02760 if (MidasExceptionHandler != NULL)
02761 MidasExceptionHandler();
02762
02763 raise(sig);
02764
02765 return 0;
02766 }
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778 #endif
02779
02780 #ifdef OS_VMS
02781
02782 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02783 {
02784 if (MidasExceptionHandler != NULL)
02785 MidasExceptionHandler();
02786
02787 return (SS$_RESIGNAL);
02788 }
02789
02790 void MidasExceptionSignal(INT sig)
02791 {
02792 if (MidasExceptionHandler != NULL)
02793 MidasExceptionHandler();
02794
02795 kill(getpid(), sig);
02796 }
02797
02798 #endif
02799
02800
02801 INT ss_exception_handler(void (*func) ())
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820 {
02821 #ifdef OS_WINNT
02822
02823 MidasExceptionHandler = func;
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835 #endif
02836 #ifdef OS_VMS
02837
02838 MidasExceptionHandler = func;
02839 lib$establish(MidasExceptionFilter);
02840
02841 signal(SIGINT, MidasExceptionSignal);
02842 signal(SIGILL, MidasExceptionSignal);
02843 signal(SIGQUIT, MidasExceptionSignal);
02844 signal(SIGFPE, MidasExceptionSignal);
02845 signal(SIGSEGV, MidasExceptionSignal);
02846 signal(SIGTERM, MidasExceptionSignal);
02847
02848 #endif
02849
02850 return SS_SUCCESS;
02851 }
02852
02853 #endif
02854
02855
02856 void *ss_ctrlc_handler(void (*func) (int))
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876 {
02877 #ifdef OS_WINNT
02878
02879 if (func == NULL) {
02880 signal(SIGBREAK, SIG_DFL);
02881 return signal(SIGINT, SIG_DFL);
02882 } else {
02883 signal(SIGBREAK, func);
02884 return signal(SIGINT, func);
02885 }
02886 return NULL;
02887
02888 #endif
02889 #ifdef OS_VMS
02890
02891 return signal(SIGINT, func);
02892
02893 #endif
02894
02895 #ifdef OS_UNIX
02896
02897 if (func == NULL) {
02898 signal(SIGTERM, SIG_DFL);
02899 return (void *) signal(SIGINT, SIG_DFL);
02900 } else {
02901 signal(SIGTERM, func);
02902 return (void *) signal(SIGINT, func);
02903 }
02904
02905 #endif
02906 }
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926 typedef struct {
02927 BOOL in_use;
02928 INT thread_id;
02929 INT ipc_port;
02930 INT ipc_recv_socket;
02931 INT ipc_send_socket;
02932 INT(*ipc_dispatch) (char *, INT);
02933 INT listen_socket;
02934 INT(*listen_dispatch) (INT);
02935 RPC_SERVER_CONNECTION *server_connection;
02936 INT(*client_dispatch) (INT);
02937 RPC_SERVER_ACCEPTION *server_acception;
02938 INT(*server_dispatch) (INT, int, BOOL);
02939 struct sockaddr_in bind_addr;
02940 } SUSPEND_STRUCT;
02941
02942 SUSPEND_STRUCT *_suspend_struct = NULL;
02943 INT _suspend_entries;
02944
02945
02946 INT ss_suspend_init_ipc(INT index)
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965 {
02966 INT status, sock;
02967 int i;
02968 struct sockaddr_in bind_addr;
02969 char local_host_name[HOST_NAME_LENGTH];
02970 struct hostent *phe;
02971
02972 #ifdef OS_WINNT
02973 {
02974 WSADATA WSAData;
02975
02976
02977 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02978 return SS_SOCKET_ERROR;
02979 }
02980 #endif
02981
02982
02983 sock = socket(AF_INET, SOCK_DGRAM, 0);
02984 if (sock == -1)
02985 return SS_SOCKET_ERROR;
02986
02987
02988 memset(&bind_addr, 0, sizeof(bind_addr));
02989 bind_addr.sin_family = AF_INET;
02990 bind_addr.sin_addr.s_addr = 0;
02991 bind_addr.sin_port = 0;
02992
02993 gethostname(local_host_name, sizeof(local_host_name));
02994
02995 #ifdef OS_VXWORKS
02996 {
02997 INT host_addr;
02998
02999 host_addr = hostGetByName(local_host_name);
03000 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03001 }
03002 #else
03003 phe = gethostbyname(local_host_name);
03004 if (phe == NULL) {
03005 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
03006 return SS_SOCKET_ERROR;
03007 }
03008 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03009 #endif
03010
03011 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
03012 if (status < 0)
03013 return SS_SOCKET_ERROR;
03014
03015
03016 i = sizeof(bind_addr);
03017 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
03018
03019 _suspend_struct[index].ipc_recv_socket = sock;
03020 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
03021
03022
03023 sock = socket(AF_INET, SOCK_DGRAM, 0);
03024
03025 if (sock == -1)
03026 return SS_SOCKET_ERROR;
03027
03028
03029 memset(&bind_addr, 0, sizeof(bind_addr));
03030 bind_addr.sin_family = AF_INET;
03031 bind_addr.sin_addr.s_addr = 0;
03032
03033 #ifdef OS_VXWORKS
03034 {
03035 INT host_addr;
03036
03037 host_addr = hostGetByName(local_host_name);
03038 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03039 }
03040 #else
03041 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03042 #endif
03043
03044 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
03045 _suspend_struct[index].ipc_send_socket = sock;
03046
03047 return SS_SUCCESS;
03048 }
03049
03050
03051 INT ss_suspend_get_index(INT * pindex)
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071 {
03072 INT index;
03073
03074 if (_suspend_struct == NULL) {
03075
03076 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
03077 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
03078 if (_suspend_struct == NULL)
03079 return SS_NO_MEMORY;
03080
03081 _suspend_entries = 1;
03082 *pindex = 0;
03083 _suspend_struct[0].thread_id = ss_gettid();
03084 _suspend_struct[0].in_use = TRUE;
03085 } else {
03086
03087 for (index = 0; index < _suspend_entries; index++)
03088 if (_suspend_struct[index].thread_id == ss_gettid()) {
03089 if (pindex != NULL)
03090 *pindex = index;
03091
03092 return SS_SUCCESS;
03093 }
03094
03095
03096 for (index = 0; index < _suspend_entries; index++)
03097 if (!_suspend_struct[index].in_use)
03098 break;
03099
03100 if (index == _suspend_entries) {
03101
03102 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
03103 sizeof
03104 (SUSPEND_STRUCT) *
03105 (_suspend_entries + 1));
03106 memset(&_suspend_struct[_suspend_entries], 0, sizeof(SUSPEND_STRUCT));
03107
03108 _suspend_entries++;
03109 if (_suspend_struct == NULL) {
03110 _suspend_entries--;
03111 return SS_NO_MEMORY;
03112 }
03113 }
03114 *pindex = index;
03115 _suspend_struct[index].thread_id = ss_gettid();
03116 _suspend_struct[index].in_use = TRUE;
03117 }
03118
03119 return SS_SUCCESS;
03120 }
03121
03122
03123 INT ss_suspend_exit()
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141 {
03142 INT i, status;
03143
03144 status = ss_suspend_get_index(&i);
03145
03146 if (status != SS_SUCCESS)
03147 return status;
03148
03149 if (_suspend_struct[i].ipc_recv_socket) {
03150 closesocket(_suspend_struct[i].ipc_recv_socket);
03151 closesocket(_suspend_struct[i].ipc_send_socket);
03152 }
03153
03154 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
03155
03156
03157 for (i = _suspend_entries - 1; i >= 0; i--)
03158 if (_suspend_struct[i].in_use)
03159 break;
03160
03161 _suspend_entries = i + 1;
03162
03163 if (_suspend_entries == 0) {
03164 free(_suspend_struct);
03165 _suspend_struct = NULL;
03166 }
03167
03168 return SS_SUCCESS;
03169 }
03170
03171
03172 INT ss_suspend_set_dispatch(INT channel, void *connection, INT(*dispatch) ())
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201 {
03202 INT i, status;
03203
03204 status = ss_suspend_get_index(&i);
03205
03206 if (status != SS_SUCCESS)
03207 return status;
03208
03209 if (channel == CH_IPC) {
03210 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
03211
03212 if (!_suspend_struct[i].ipc_recv_socket)
03213 ss_suspend_init_ipc(i);
03214 }
03215
03216 if (channel == CH_LISTEN) {
03217 _suspend_struct[i].listen_socket = *((INT *) connection);
03218 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
03219 }
03220
03221 if (channel == CH_CLIENT) {
03222 _suspend_struct[i].server_connection = (RPC_SERVER_CONNECTION *) connection;
03223 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
03224 }
03225
03226 if (channel == CH_SERVER) {
03227 _suspend_struct[i].server_acception = (RPC_SERVER_ACCEPTION *) connection;
03228 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
03229 }
03230
03231 return SS_SUCCESS;
03232 }
03233
03234
03235 INT ss_suspend_get_port(INT * port)
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256 {
03257 INT index, status;
03258
03259 status = ss_suspend_get_index(&index);
03260
03261 if (status != SS_SUCCESS)
03262 return status;
03263
03264 if (!_suspend_struct[index].ipc_port)
03265 ss_suspend_init_ipc(index);
03266
03267 *port = _suspend_struct[index].ipc_port;
03268
03269 return SS_SUCCESS;
03270 }
03271
03272
03273 INT ss_suspend(INT millisec, INT msg)
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304 {
03305 fd_set readfds;
03306 struct timeval timeout;
03307 INT sock, server_socket;
03308 INT index, status, i, return_status;
03309 int size;
03310 struct sockaddr from_addr;
03311 char str[100], buffer[80], buffer_tmp[80];
03312
03313
03314 status = ss_suspend_get_index(&index);
03315
03316 if (status != SS_SUCCESS)
03317 return status;
03318
03319 return_status = SS_TIMEOUT;
03320
03321 do {
03322 FD_ZERO(&readfds);
03323
03324
03325 if (_suspend_struct[index].listen_socket)
03326 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03327
03328
03329 if (_suspend_struct[index].server_acception)
03330 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03331
03332 sock = _suspend_struct[index].server_acception[i].recv_sock;
03333
03334
03335 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03336 continue;
03337
03338
03339 if (recv_tcp_check(sock) == 0)
03340 FD_SET(sock, &readfds);
03341
03342
03343 else if (msg == 0)
03344 millisec = 0;
03345
03346
03347 sock = _suspend_struct[index].server_acception[i].event_sock;
03348
03349 if (!sock)
03350 continue;
03351
03352
03353 if (recv_event_check(sock) == 0)
03354 FD_SET(sock, &readfds);
03355
03356
03357 else if (msg == 0)
03358 millisec = 0;
03359 }
03360
03361
03362 if (_suspend_struct[index].server_connection) {
03363 sock = _suspend_struct[index].server_connection->recv_sock;
03364 if (sock)
03365 FD_SET(sock, &readfds);
03366 }
03367
03368
03369 if (_suspend_struct[index].ipc_recv_socket)
03370 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03371
03372 timeout.tv_sec = millisec / 1000;
03373 timeout.tv_usec = (millisec % 1000) * 1000;
03374
03375 do {
03376 if (millisec < 0)
03377 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03378 else
03379 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03380
03381
03382 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03383 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03384
03385 } while (status == -1);
03386
03387
03388 if (_suspend_struct[index].listen_socket &&
03389 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03390 sock = _suspend_struct[index].listen_socket;
03391
03392 if (_suspend_struct[index].listen_dispatch) {
03393 status = _suspend_struct[index].listen_dispatch(sock);
03394 if (status == RPC_SHUTDOWN)
03395 return status;
03396 }
03397 }
03398
03399
03400 if (_suspend_struct[index].server_acception)
03401 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03402
03403 sock = _suspend_struct[index].server_acception[i].recv_sock;
03404
03405
03406 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03407 continue;
03408
03409 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03410 if (_suspend_struct[index].server_dispatch) {
03411 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03412 _suspend_struct[index].server_acception[i].
03413 last_activity = ss_millitime();
03414
03415 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03416 return status;
03417
03418 return_status = SS_SERVER_RECV;
03419 }
03420 }
03421
03422
03423 sock = _suspend_struct[index].server_acception[i].event_sock;
03424 if (!sock)
03425 continue;
03426
03427 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03428 if (_suspend_struct[index].server_dispatch) {
03429 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03430 _suspend_struct[index].server_acception[i].
03431 last_activity = ss_millitime();
03432
03433 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03434 return status;
03435
03436 return_status = SS_SERVER_RECV;
03437 }
03438 }
03439 }
03440
03441
03442 if (_suspend_struct[index].server_connection) {
03443 sock = _suspend_struct[index].server_connection->recv_sock;
03444
03445 if (sock && FD_ISSET(sock, &readfds)) {
03446 if (_suspend_struct[index].client_dispatch)
03447 status = _suspend_struct[index].client_dispatch(sock);
03448 else {
03449 status = SS_SUCCESS;
03450 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03451
03452 if (size <= 0)
03453 status = SS_ABORT;
03454 }
03455
03456 if (status == SS_ABORT) {
03457 sprintf(str, "Server connection broken to %s",
03458 _suspend_struct[index].server_connection->host_name);
03459 cm_msg(MINFO, "ss_suspend", str);
03460
03461
03462 closesocket(_suspend_struct[index].server_connection->send_sock);
03463 closesocket(_suspend_struct[index].server_connection->recv_sock);
03464 closesocket(_suspend_struct[index].server_connection->event_sock);
03465
03466 memset(_suspend_struct[index].server_connection,
03467 0, sizeof(RPC_CLIENT_CONNECTION));
03468
03469
03470 return SS_ABORT;
03471 }
03472
03473 return_status = SS_CLIENT_RECV;
03474 }
03475 }
03476
03477
03478 if (_suspend_struct[index].ipc_recv_socket &&
03479 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03480
03481 size = sizeof(struct sockaddr);
03482 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03483 buffer, sizeof(buffer), 0, &from_addr, (int *) &size);
03484
03485
03486 server_socket = 0;
03487 if (_suspend_struct[index].server_acception &&
03488 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03489 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03490 sock = _suspend_struct[index].server_acception[i].send_sock;
03491 if (sock && _suspend_struct[index].server_acception[i].tid == ss_gettid())
03492 server_socket = sock;
03493 }
03494
03495
03496 do {
03497 FD_ZERO(&readfds);
03498 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03499
03500 timeout.tv_sec = 0;
03501 timeout.tv_usec = 0;
03502
03503 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03504
03505 if (status != -1
03506 && FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03507 size = sizeof(struct sockaddr);
03508 size =
03509 recvfrom(_suspend_struct[index].ipc_recv_socket,
03510 buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &size);
03511
03512
03513 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03514 if (_suspend_struct[index].ipc_dispatch)
03515 _suspend_struct[index].ipc_dispatch(buffer_tmp, server_socket);
03516 }
03517
03518 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03519
03520
03521 if (msg == MSG_BM && buffer[0] == 'B')
03522 return SS_SUCCESS;
03523 if (msg == MSG_ODB && buffer[0] == 'O')
03524 return SS_SUCCESS;
03525
03526
03527 if (_suspend_struct[index].ipc_dispatch)
03528 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03529
03530 return_status = SS_SUCCESS;
03531 }
03532
03533 } while (millisec < 0);
03534
03535 return return_status;
03536 }
03537
03538
03539 INT ss_resume(INT port, char *message)
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562 {
03563 INT status, index;
03564
03565 if (ss_in_async_routine_flag) {
03566
03567 index = 0;
03568 } else {
03569 status = ss_suspend_get_index(&index);
03570
03571 if (status != SS_SUCCESS)
03572 return status;
03573 }
03574
03575 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03576
03577 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03578 strlen(message) + 1, 0,
03579 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03580 sizeof(struct sockaddr_in));
03581
03582 if (status != (INT) strlen(message) + 1)
03583 return SS_SOCKET_ERROR;
03584
03585 return SS_SUCCESS;
03586 }
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616 {
03617 DWORD count;
03618 INT status;
03619
03620
03621
03622 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03623 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03624 if (status != -1)
03625 count += status;
03626 else {
03627 cm_msg(MERROR, "send_tcp",
03628 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03629 sock, NET_TCP_SIZE, status, errno, strerror(errno));
03630 return status;
03631 }
03632 }
03633
03634 while (count < buffer_size) {
03635 status = send(sock, buffer + count, buffer_size - count, flags);
03636 if (status != -1)
03637 count += status;
03638 else {
03639 cm_msg(MERROR, "send_tcp",
03640 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03641 sock, (int) (buffer_size - count), status, errno, strerror(errno));
03642 return status;
03643 }
03644 }
03645
03646 return count;
03647 }
03648
03649
03650 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675 {
03676 INT i, status;
03677 DWORD n;
03678 fd_set readfds;
03679 struct timeval timeout;
03680
03681 n = 0;
03682 memset(buffer, 0, buffer_size);
03683
03684 do {
03685 if (millisec > 0) {
03686 FD_ZERO(&readfds);
03687 FD_SET(sock, &readfds);
03688
03689 timeout.tv_sec = millisec / 1000;
03690 timeout.tv_usec = (millisec % 1000) * 1000;
03691
03692 do {
03693 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03694
03695
03696 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03697 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03698
03699 } while (status == -1);
03700
03701 if (!FD_ISSET(sock, &readfds))
03702 break;
03703 }
03704
03705 i = recv(sock, buffer + n, 1, 0);
03706
03707 if (i <= 0)
03708 break;
03709
03710 n++;
03711
03712 if (n >= buffer_size)
03713 break;
03714
03715 } while (buffer[n - 1] && buffer[n - 1] != 10);
03716
03717 return n - 1;
03718 }
03719
03720
03721 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751 {
03752 INT param_size, n_received, n;
03753 NET_COMMAND *nc;
03754
03755 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03756 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03757 return -1;
03758 }
03759
03760
03761 n_received = 0;
03762 do {
03763 #ifdef OS_UNIX
03764 do {
03765 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03766
03767
03768 } while (n == -1 && errno == EINTR);
03769 #else
03770 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03771 #endif
03772
03773 if (n <= 0) {
03774 cm_msg(MERROR, "recv_tcp",
03775 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03776 n, n_received, errno, strerror(errno));
03777 return n;
03778 }
03779
03780 n_received += n;
03781
03782 } while (n_received < sizeof(NET_COMMAND_HEADER));
03783
03784
03785
03786 nc = (NET_COMMAND *) net_buffer;
03787 param_size = nc->header.param_size;
03788 n_received = 0;
03789
03790 if (param_size == 0)
03791 return sizeof(NET_COMMAND_HEADER);
03792
03793 do {
03794 #ifdef OS_UNIX
03795 do {
03796 n = recv(sock,
03797 net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03798 param_size - n_received, flags);
03799
03800
03801 } while (n == -1 && errno == EINTR);
03802 #else
03803 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03804 param_size - n_received, flags);
03805 #endif
03806
03807 if (n <= 0) {
03808 cm_msg(MERROR, "recv_tcp",
03809 "param: recv returned %d, n_received = %d, errno: %d (%s)",
03810 n, n_received, errno, strerror(errno));
03811 return n;
03812 }
03813
03814 n_received += n;
03815 } while (n_received < param_size);
03816
03817 return sizeof(NET_COMMAND_HEADER) + param_size;
03818 }
03819
03820
03821 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844 {
03845 INT status;
03846 UDP_HEADER *udp_header;
03847 static char udp_buffer[NET_UDP_SIZE];
03848 static INT serial_number = 0, n_received = 0;
03849 DWORD i, data_size;
03850
03851 udp_header = (UDP_HEADER *) udp_buffer;
03852 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03853
03854
03855
03856
03857
03858 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03859
03860
03861
03862 if (n_received) {
03863 udp_header->serial_number = UDP_FIRST | n_received;
03864 udp_header->sequence_number = ++serial_number;
03865
03866 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03867 n_received = 0;
03868 }
03869
03870 udp_header->serial_number = UDP_FIRST | buffer_size;
03871 udp_header->sequence_number = ++serial_number;
03872
03873 memcpy(udp_header + 1, buffer, buffer_size);
03874 status = send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03875 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03876 status -= sizeof(UDP_HEADER);
03877
03878 return status;
03879 }
03880
03881
03882
03883
03884
03885 if (buffer_size <= data_size) {
03886
03887 if (buffer_size + n_received < data_size) {
03888 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer, buffer_size);
03889
03890 n_received += buffer_size;
03891 return buffer_size;
03892 }
03893
03894
03895 udp_header->serial_number = UDP_FIRST | n_received;
03896 udp_header->sequence_number = ++serial_number;
03897
03898 status = send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03899
03900 n_received = 0;
03901
03902 memcpy(udp_header + 1, buffer, buffer_size);
03903 n_received = buffer_size;
03904
03905 return buffer_size;
03906 }
03907
03908
03909
03910
03911
03912
03913
03914 if (n_received) {
03915 udp_header->serial_number = UDP_FIRST | n_received;
03916 udp_header->sequence_number = ++serial_number;
03917
03918 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03919 n_received = 0;
03920 }
03921
03922 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03923 if (i == 0) {
03924 udp_header->serial_number = UDP_FIRST | buffer_size;
03925 udp_header->sequence_number = ++serial_number;
03926 } else {
03927 udp_header->serial_number = serial_number;
03928 udp_header->sequence_number = i;
03929 }
03930
03931 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03932 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03933 }
03934
03935
03936 udp_header->serial_number = serial_number;
03937 udp_header->sequence_number = i;
03938 memcpy(udp_header + 1, buffer + i * data_size, buffer_size - i * data_size);
03939 status =
03940 send(sock, udp_buffer, sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03941 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03942 return buffer_size;
03943
03944 return status;
03945 }
03946
03947
03948 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970 {
03971 INT i, status;
03972 UDP_HEADER *udp_header;
03973 char udp_buffer[NET_UDP_SIZE];
03974 DWORD serial_number, sequence_number, total_buffer_size;
03975 DWORD data_size, n_received;
03976 fd_set readfds;
03977 struct timeval timeout;
03978
03979 udp_header = (UDP_HEADER *) udp_buffer;
03980 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03981
03982
03983 #ifdef OS_UNIX
03984 do {
03985 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03986
03987
03988 } while (i == -1 && errno == EINTR);
03989 #else
03990 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03991 #endif
03992
03993 start:
03994
03995
03996 while (!(udp_header->serial_number & UDP_FIRST)) {
03997
03998 FD_ZERO(&readfds);
03999 FD_SET(sock, &readfds);
04000
04001 timeout.tv_sec = 0;
04002 timeout.tv_usec = 100000;
04003
04004 do {
04005 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04006 } while (status == -1);
04007
04008
04009
04010
04011
04012 if (!FD_ISSET(sock, &readfds))
04013 return 0;
04014
04015 #ifdef OS_UNIX
04016 do {
04017 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04018
04019
04020 } while (i == -1 && errno == EINTR);
04021 #else
04022 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04023 #endif
04024 }
04025
04026
04027 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
04028 serial_number = udp_header->sequence_number;
04029 sequence_number = 0;
04030
04031 if (total_buffer_size <= data_size) {
04032 if (buffer_size < total_buffer_size) {
04033 memcpy(buffer, udp_header + 1, buffer_size);
04034 return buffer_size;
04035 } else {
04036 memcpy(buffer, udp_header + 1, total_buffer_size);
04037 return total_buffer_size;
04038 }
04039 }
04040
04041
04042 n_received = data_size;
04043
04044 if (buffer_size < data_size) {
04045 memcpy(buffer, udp_header + 1, buffer_size);
04046 return buffer_size;
04047 }
04048
04049 memcpy(buffer, udp_header + 1, data_size);
04050
04051
04052 do {
04053
04054 FD_ZERO(&readfds);
04055 FD_SET(sock, &readfds);
04056
04057 timeout.tv_sec = 0;
04058 timeout.tv_usec = 100000;
04059
04060 do {
04061 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04062 } while (status == -1);
04063
04064
04065
04066
04067
04068 if (!FD_ISSET(sock, &readfds))
04069 return 0;
04070
04071 #ifdef OS_UNIX
04072 do {
04073 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04074
04075
04076 } while (i == -1 && errno == EINTR);
04077 #else
04078 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04079 #endif
04080
04081 sequence_number++;
04082
04083
04084 if (udp_header->serial_number != serial_number ||
04085 udp_header->sequence_number != sequence_number)
04086
04087 goto start;
04088
04089
04090 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
04091
04092 n_received += (i - sizeof(UDP_HEADER));
04093
04094 } while (n_received < total_buffer_size);
04095
04096 return n_received;
04097 }
04098
04099
04100
04101 #ifdef OS_MSDOS
04102 #ifdef sopen
04103
04104
04105
04106
04107
04108
04109 #undef sopen
04110
04111 int sopen(const char *path, int access, int shflag, int mode)
04112 {
04113 return open(path, (access) | (shflag), mode);
04114 }
04115
04116 #endif
04117 #endif
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127 INT ss_tape_open(char *path, INT oflag, INT * channel)
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149 {
04150 #ifdef OS_UNIX
04151 struct mtop arg;
04152
04153 cm_enable_watchdog(FALSE);
04154
04155 *channel = open(path, oflag, 0644);
04156
04157 cm_enable_watchdog(TRUE);
04158
04159 if (*channel < 0)
04160 cm_msg(MERROR, "ss_tape_open", strerror(errno));
04161
04162 if (*channel < 0) {
04163 if (errno == EIO)
04164 return SS_NO_TAPE;
04165 if (errno == EBUSY)
04166 return SS_DEV_BUSY;
04167 return errno;
04168 }
04169 #ifdef MTSETBLK
04170
04171 arg.mt_op = MTSETBLK;
04172 arg.mt_count = 0;
04173
04174 ioctl(*channel, MTIOCTOP, &arg);
04175 #endif
04176
04177 #endif
04178
04179 #ifdef OS_WINNT
04180 INT status;
04181 TAPE_GET_MEDIA_PARAMETERS m;
04182
04183 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04184 0, OPEN_EXISTING, 0, NULL);
04185
04186 if (*channel == (INT) INVALID_HANDLE_VALUE) {
04187 status = GetLastError();
04188 if (status == ERROR_SHARING_VIOLATION) {
04189 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
04190 return SS_DEV_BUSY;
04191 }
04192 if (status == ERROR_FILE_NOT_FOUND) {
04193 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
04194 return SS_NO_TAPE;
04195 }
04196
04197 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
04198 return status;
04199 }
04200
04201 status = GetTapeStatus((HANDLE) (*channel));
04202 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04203 cm_msg(MERROR, "ss_tape_open", "no media in drive");
04204 return SS_NO_TAPE;
04205 }
04206
04207
04208 memset(&m, 0, sizeof(m));
04209 m.BlockSize = TAPE_BUFFER_SIZE;
04210 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
04211
04212 #endif
04213
04214 return SS_SUCCESS;
04215 }
04216
04217
04218 INT ss_tape_close(INT channel)
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236 {
04237 INT status;
04238
04239 #ifdef OS_UNIX
04240
04241 status = close(channel);
04242
04243 if (status < 0) {
04244 cm_msg(MERROR, "ss_tape_close", strerror(errno));
04245 return errno;
04246 }
04247 #endif
04248
04249 #ifdef OS_WINNT
04250
04251 if (!CloseHandle((HANDLE) channel)) {
04252 status = GetLastError();
04253 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
04254 return status;
04255 }
04256 #endif
04257
04258 return SS_SUCCESS;
04259 }
04260
04261
04262 INT ss_tape_status(char *path)
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279 {
04280 #ifdef OS_UNIX
04281 char str[256];
04282
04283 sprintf(str, "mt -f %s status", path);
04284 system(str);
04285 #endif
04286
04287 #ifdef OS_WINNT
04288 INT status, channel;
04289 DWORD size;
04290 TAPE_GET_MEDIA_PARAMETERS m;
04291 TAPE_GET_DRIVE_PARAMETERS d;
04292 double x;
04293
04294 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04295 0, OPEN_EXISTING, 0, NULL);
04296
04297 if (channel == (INT) INVALID_HANDLE_VALUE) {
04298 status = GetLastError();
04299 if (status == ERROR_SHARING_VIOLATION) {
04300 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04301 return SS_SUCCESS;
04302 }
04303 if (status == ERROR_FILE_NOT_FOUND) {
04304 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
04305 return SS_SUCCESS;
04306 }
04307
04308 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04309 return status;
04310 }
04311
04312
04313 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04314 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04315
04316 status = GetTapeStatus((HANDLE) channel);
04317 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04318 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04319 CloseHandle((HANDLE) channel);
04320 return SS_SUCCESS;
04321 }
04322
04323 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04324 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
04325
04326 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04327 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04328 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04329
04330 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04331 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
04332 / 1024.0 / 1000.0;
04333 printf("Tape capacity remaining is %d MB\n", (int) x);
04334 } else
04335 printf("Tape capacity is not reported by tape\n");
04336
04337 CloseHandle((HANDLE) channel);
04338
04339 #endif
04340
04341 return SS_SUCCESS;
04342 }
04343
04344
04345 INT ss_tape_write(INT channel, void *pdata, INT count)
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366 {
04367 #ifdef OS_UNIX
04368 INT status;
04369
04370 do {
04371 status = write(channel, pdata, count);
04372
04373
04374
04375
04376 } while (status == -1 && errno == EINTR);
04377
04378 if (status != count) {
04379 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04380
04381 if (errno == EIO)
04382 return SS_IO_ERROR;
04383 else
04384 return SS_TAPE_ERROR;
04385 }
04386 #endif
04387
04388 #ifdef OS_WINNT
04389 INT status;
04390 DWORD written;
04391
04392 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04393 if (written != (DWORD) count) {
04394 status = GetLastError();
04395 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04396
04397 return SS_IO_ERROR;
04398 }
04399 #endif
04400
04401 return SS_SUCCESS;
04402 }
04403
04404
04405 INT ss_tape_read(INT channel, void *pdata, INT * count)
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425 {
04426 #ifdef OS_UNIX
04427 INT n, status;
04428
04429 do {
04430 n = read(channel, pdata, *count);
04431 } while (n == -1 && errno == EINTR);
04432
04433 if (n == -1) {
04434 if (errno == ENOSPC || errno == EIO)
04435 status = SS_END_OF_TAPE;
04436 else {
04437 if (n == 0 && errno == 0)
04438 status = SS_END_OF_FILE;
04439 else {
04440 cm_msg(MERROR, "ss_tape_read",
04441 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04442 status = errno;
04443 }
04444 }
04445 } else
04446 status = SS_SUCCESS;
04447 *count = n;
04448
04449 return status;
04450
04451 #elif defined(OS_WINNT)
04452
04453 INT status;
04454 DWORD read;
04455
04456 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04457 status = GetLastError();
04458 if (status == ERROR_NO_DATA_DETECTED)
04459 status = SS_END_OF_TAPE;
04460 else if (status == ERROR_FILEMARK_DETECTED)
04461 status = SS_END_OF_FILE;
04462 else if (status == ERROR_MORE_DATA)
04463 status = SS_SUCCESS;
04464 else
04465 cm_msg(MERROR, "ss_tape_read",
04466 "unexpected tape error: n=%d, errno=%d\n", read, status);
04467 } else
04468 status = SS_SUCCESS;
04469
04470 *count = read;
04471 return status;
04472
04473 #else
04474
04475 return SS_SUCCESS;
04476
04477 #endif
04478 }
04479
04480
04481 INT ss_tape_write_eof(INT channel)
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499 {
04500 INT status;
04501
04502 #ifdef OS_UNIX
04503 struct mtop arg;
04504
04505 arg.mt_op = MTWEOF;
04506 arg.mt_count = 1;
04507
04508 cm_enable_watchdog(FALSE);
04509
04510 status = ioctl(channel, MTIOCTOP, &arg);
04511
04512 cm_enable_watchdog(TRUE);
04513
04514 if (status < 0) {
04515 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04516 return errno;
04517 }
04518 #endif
04519
04520 #ifdef OS_WINNT
04521
04522 TAPE_GET_DRIVE_PARAMETERS d;
04523 DWORD size;
04524
04525 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04526 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04527
04528 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04529 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04530 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04531 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04532 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04533 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04534 else
04535 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
04536
04537 if (status != NO_ERROR) {
04538 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04539 return status;
04540 }
04541 #endif
04542
04543 return SS_SUCCESS;
04544 }
04545
04546
04547 INT ss_tape_fskip(INT channel, INT count)
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566 {
04567 INT status;
04568
04569 #ifdef OS_UNIX
04570 struct mtop arg;
04571
04572 if (count > 0)
04573 arg.mt_op = MTFSF;
04574 else
04575 arg.mt_op = MTBSF;
04576 arg.mt_count = abs(count);
04577
04578 cm_enable_watchdog(FALSE);
04579
04580 status = ioctl(channel, MTIOCTOP, &arg);
04581
04582 cm_enable_watchdog(TRUE);
04583
04584 if (status < 0) {
04585 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04586 return errno;
04587 }
04588 #endif
04589
04590 #ifdef OS_WINNT
04591
04592 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04593 (DWORD) count, 0, FALSE);
04594
04595 if (status == ERROR_END_OF_MEDIA)
04596 return SS_END_OF_TAPE;
04597
04598 if (status != NO_ERROR) {
04599 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04600 return status;
04601 }
04602 #endif
04603
04604 return SS_SUCCESS;
04605 }
04606
04607
04608 INT ss_tape_rskip(INT channel, INT count)
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627 {
04628 INT status;
04629
04630 #ifdef OS_UNIX
04631 struct mtop arg;
04632
04633 if (count > 0)
04634 arg.mt_op = MTFSR;
04635 else
04636 arg.mt_op = MTBSR;
04637 arg.mt_count = abs(count);
04638
04639 cm_enable_watchdog(FALSE);
04640
04641 status = ioctl(channel, MTIOCTOP, &arg);
04642
04643 cm_enable_watchdog(TRUE);
04644
04645 if (status < 0) {
04646 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04647 return errno;
04648 }
04649 #endif
04650
04651 #ifdef OS_WINNT
04652
04653 status =
04654 SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04655 (DWORD) count, 0, FALSE);
04656 if (status != NO_ERROR) {
04657 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04658 return status;
04659 }
04660 #endif
04661
04662 return CM_SUCCESS;
04663 }
04664
04665
04666 INT ss_tape_rewind(INT channel)
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684 {
04685 INT status;
04686
04687 #ifdef OS_UNIX
04688 struct mtop arg;
04689
04690 arg.mt_op = MTREW;
04691 arg.mt_count = 0;
04692
04693 cm_enable_watchdog(FALSE);
04694
04695 status = ioctl(channel, MTIOCTOP, &arg);
04696
04697 cm_enable_watchdog(TRUE);
04698
04699 if (status < 0) {
04700 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04701 return errno;
04702 }
04703 #endif
04704
04705 #ifdef OS_WINNT
04706
04707 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04708 if (status != NO_ERROR) {
04709 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04710 return status;
04711 }
04712 #endif
04713
04714 return CM_SUCCESS;
04715 }
04716
04717
04718 INT ss_tape_spool(INT channel)
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736 {
04737 INT status;
04738
04739 #ifdef OS_UNIX
04740 struct mtop arg;
04741
04742 #ifdef MTEOM
04743 arg.mt_op = MTEOM;
04744 #else
04745 arg.mt_op = MTSEOD;
04746 #endif
04747 arg.mt_count = 0;
04748
04749 cm_enable_watchdog(FALSE);
04750
04751 status = ioctl(channel, MTIOCTOP, &arg);
04752
04753 cm_enable_watchdog(TRUE);
04754
04755 if (status < 0) {
04756 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04757 return errno;
04758 }
04759 #endif
04760
04761 #ifdef OS_WINNT
04762
04763 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
04764 if (status != NO_ERROR) {
04765 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04766 return status;
04767 }
04768 #endif
04769
04770 return CM_SUCCESS;
04771 }
04772
04773
04774 INT ss_tape_mount(INT channel)
04775
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792 {
04793 INT status;
04794
04795 #ifdef OS_UNIX
04796 struct mtop arg;
04797
04798 #ifdef MTLOAD
04799 arg.mt_op = MTLOAD;
04800 #else
04801 arg.mt_op = MTNOP;
04802 #endif
04803 arg.mt_count = 0;
04804
04805 cm_enable_watchdog(FALSE);
04806
04807 status = ioctl(channel, MTIOCTOP, &arg);
04808
04809 cm_enable_watchdog(TRUE);
04810
04811 if (status < 0) {
04812 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04813 return errno;
04814 }
04815 #endif
04816
04817 #ifdef OS_WINNT
04818
04819 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04820 if (status != NO_ERROR) {
04821 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04822 return status;
04823 }
04824 #endif
04825
04826 return CM_SUCCESS;
04827 }
04828
04829
04830 INT ss_tape_unmount(INT channel)
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848 {
04849 INT status;
04850
04851 #ifdef OS_UNIX
04852 struct mtop arg;
04853
04854 #ifdef MTOFFL
04855 arg.mt_op = MTOFFL;
04856 #else
04857 arg.mt_op = MTUNLOAD;
04858 #endif
04859 arg.mt_count = 0;
04860
04861 cm_enable_watchdog(FALSE);
04862
04863 status = ioctl(channel, MTIOCTOP, &arg);
04864
04865 cm_enable_watchdog(TRUE);
04866
04867 if (status < 0) {
04868 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04869 return errno;
04870 }
04871 #endif
04872
04873 #ifdef OS_WINNT
04874
04875 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04876 if (status != NO_ERROR) {
04877 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04878 return status;
04879 }
04880 #endif
04881
04882 return CM_SUCCESS;
04883 }
04884
04885
04886 INT ss_tape_get_blockn(INT channel)
04887
04888
04889
04890
04891
04892
04893
04894
04895 {
04896 #if defined(OS_DARWIN)
04897
04898 return 0;
04899
04900 #elif defined(OS_UNIX)
04901
04902 INT status;
04903 struct mtpos arg;
04904
04905 cm_enable_watchdog(FALSE);
04906 status = ioctl(channel, MTIOCPOS, &arg);
04907 cm_enable_watchdog(TRUE);
04908 if (status < 0) {
04909 if (errno == EIO)
04910 return 0;
04911 else {
04912 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04913 return -errno;
04914 }
04915 }
04916 return (arg.mt_blkno);
04917
04918 #elif defined(OS_WINNT)
04919
04920 INT status;
04921 TAPE_GET_MEDIA_PARAMETERS media;
04922 unsigned long size;
04923
04924 status =
04925 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
04926 return (media.PartitionCount);
04927
04928 #endif
04929 }
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940 double ss_disk_free(char *path)
04941
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954
04955
04956 {
04957 #ifdef OS_UNIX
04958 #if defined(OS_OSF1)
04959 struct statfs st;
04960 statfs(path, &st, sizeof(st));
04961 return (double) st.f_bavail * st.f_bsize;
04962 #elif defined(OS_LINUX)
04963 struct statfs st;
04964 statfs(path, &st);
04965 return (double) st.f_bavail * st.f_bsize;
04966 #elif defined(OS_SOLARIS)
04967 struct statvfs st;
04968 statvfs(path, &st);
04969 return (double) st.f_bavail * st.f_bsize;
04970 #elif defined(OS_IRIX)
04971 struct statfs st;
04972 statfs(path, &st, sizeof(struct statfs), 0);
04973 return (double) st.f_bfree * st.f_bsize;
04974 #else
04975 struct fs_data st;
04976 statfs(path, &st);
04977 return (double) st.fd_otsize * st.fd_bfree;
04978 #endif
04979
04980 #elif defined(OS_WINNT)
04981 DWORD SectorsPerCluster;
04982 DWORD BytesPerSector;
04983 DWORD NumberOfFreeClusters;
04984 DWORD TotalNumberOfClusters;
04985 char str[80];
04986
04987 strcpy(str, path);
04988 if (strchr(str, ':') != NULL) {
04989 *(strchr(str, ':') + 1) = 0;
04990 strcat(str, DIR_SEPARATOR_STR);
04991 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04992 &NumberOfFreeClusters, &TotalNumberOfClusters);
04993 } else
04994 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04995 &NumberOfFreeClusters, &TotalNumberOfClusters);
04996
04997 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
04998 #else
04999
05000 return 1e9;
05001
05002 #endif
05003 }
05004
05005 #if defined(OS_ULTRIX) || defined(OS_WINNT)
05006 int fnmatch(const char *pat, const char *str, const int flag)
05007 {
05008 while (*str != '\0') {
05009 if (*pat == '*') {
05010 pat++;
05011 if ((str = strchr(str, *pat)) == NULL)
05012 return -1;
05013 }
05014 if (*pat == *str) {
05015 pat++;
05016 str++;
05017 } else
05018 return -1;
05019 }
05020 if (*pat == '\0')
05021 return 0;
05022 else
05023 return -1;
05024 }
05025 #endif
05026
05027 #ifdef OS_WINNT
05028 HANDLE pffile;
05029 LPWIN32_FIND_DATA lpfdata;
05030 #endif
05031 INT ss_file_find(char *path, char *pattern, char **plist)
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047
05048
05049 {
05050 int i;
05051 #ifdef OS_UNIX
05052 DIR *dir_pointer;
05053 struct dirent *dp;
05054
05055 if ((dir_pointer = opendir(path)) == NULL)
05056 return 0;
05057 *plist = (char *) malloc(MAX_STRING_LENGTH);
05058 i = 0;
05059 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
05060 if (fnmatch(pattern, dp->d_name, 0) == 0) {
05061 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05062 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name, strlen(dp->d_name));
05063 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
05064 i++;
05065 seekdir(dir_pointer, telldir(dir_pointer));
05066 }
05067 }
05068 closedir(dir_pointer);
05069 #endif
05070 #ifdef OS_WINNT
05071 char str[255];
05072 int first;
05073
05074 strcpy(str, path);
05075 strcat(str, "\\");
05076 strcat(str, pattern);
05077 first = 1;
05078 i = 0;
05079 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
05080 *plist = (char *) malloc(MAX_STRING_LENGTH);
05081 pffile = FindFirstFile(str, lpfdata);
05082 if (pffile == INVALID_HANDLE_VALUE)
05083 return 0;
05084 first = 0;
05085 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05086 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05087 strlen(lpfdata->cFileName));
05088 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05089 i++;
05090 while (FindNextFile(pffile, lpfdata)) {
05091 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05092 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05093 strlen(lpfdata->cFileName));
05094 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05095 i++;
05096 }
05097 free(lpfdata);
05098 #endif
05099 return i;
05100 }
05101
05102 INT ss_file_remove(char *path)
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118 {
05119 return remove(path);
05120 }
05121
05122 double ss_file_size(char *path)
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138 {
05139 struct stat stat_buf;
05140
05141
05142 stat(path, &stat_buf);
05143 return (double) stat_buf.st_size;
05144 }
05145
05146 double ss_disk_size(char *path)
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162 {
05163 #ifdef OS_UNIX
05164 #if defined(OS_OSF1)
05165 struct statfs st;
05166 statfs(path, &st, sizeof(st));
05167 return (double) st.f_blocks * st.f_fsize;
05168 #elif defined(OS_LINUX)
05169 struct statfs st;
05170 statfs(path, &st);
05171 return (double) st.f_blocks * st.f_bsize;
05172 #elif defined(OS_SOLARIS)
05173 struct statvfs st;
05174 statvfs(path, &st);
05175 if (st.f_frsize > 0)
05176 return (double) st.f_blocks * st.f_frsize;
05177 else
05178 return (double) st.f_blocks * st.f_bsize;
05179 #elif defined(OS_ULTRIX)
05180 struct fs_data st;
05181 statfs(path, &st);
05182 return (double) st.fd_btot * 1024;
05183 #elif defined(OS_IRIX)
05184 struct statfs st;
05185 statfs(path, &st, sizeof(struct statfs), 0);
05186 return (double) st.f_blocks * st.f_bsize;
05187 #else
05188 #error ss_disk_size not defined for this OS
05189 #endif
05190 #endif
05191
05192 #ifdef OS_WINNT
05193 DWORD SectorsPerCluster;
05194 DWORD BytesPerSector;
05195 DWORD NumberOfFreeClusters;
05196 DWORD TotalNumberOfClusters;
05197 char str[80];
05198
05199 strcpy(str, path);
05200 if (strchr(str, ':') != NULL) {
05201 *(strchr(str, ':') + 1) = 0;
05202 strcat(str, DIR_SEPARATOR_STR);
05203 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
05204 &NumberOfFreeClusters, &TotalNumberOfClusters);
05205 } else
05206 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
05207 &NumberOfFreeClusters, &TotalNumberOfClusters);
05208
05209 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
05210 #endif
05211
05212 return 1e9;
05213 }
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223 void ss_clear_screen()
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240 {
05241 #ifdef OS_WINNT
05242
05243 HANDLE hConsole;
05244 COORD coordScreen = { 0, 0 };
05245 BOOL bSuccess;
05246 DWORD cCharsWritten;
05247 CONSOLE_SCREEN_BUFFER_INFO csbi;
05248 DWORD dwConSize;
05249
05250 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05251
05252
05253 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
05254 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
05255
05256
05257 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
05258 dwConSize, coordScreen, &cCharsWritten);
05259
05260
05261 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
05262 return;
05263
05264 #endif
05265 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05266 printf("\033[2J");
05267 #endif
05268 #ifdef OS_MSDOS
05269 clrscr();
05270 #endif
05271 }
05272
05273
05274 void ss_set_screen_size(int x, int y)
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291 {
05292 #ifdef OS_WINNT
05293
05294 HANDLE hConsole;
05295 COORD coordSize;
05296
05297 coordSize.X = (short) x;
05298 coordSize.Y = (short) y;
05299 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05300 SetConsoleScreenBufferSize(hConsole, coordSize);
05301
05302 #endif
05303 }
05304
05305
05306 void ss_printf(INT x, INT y, const char *format, ...)
05307
05308
05309
05310
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327 {
05328 char str[256];
05329 va_list argptr;
05330
05331 va_start(argptr, format);
05332 vsprintf(str, (char *) format, argptr);
05333 va_end(argptr);
05334
05335 #ifdef OS_WINNT
05336 {
05337 HANDLE hConsole;
05338 COORD dwWriteCoord;
05339 DWORD cCharsWritten;
05340
05341 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05342
05343 dwWriteCoord.X = (short) x;
05344 dwWriteCoord.Y = (short) y;
05345
05346 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05347 dwWriteCoord, &cCharsWritten);
05348 }
05349
05350 #endif
05351
05352 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05353 printf("\033[%1d;%1d;H", y + 1, x + 1);
05354 printf(str);
05355 fflush(stdout);
05356 #endif
05357
05358 #ifdef OS_MSDOS
05359 gotoxy(x + 1, y + 1);
05360 cputs(str);
05361 #endif
05362 }
05363
05364
05365 char *ss_getpass(char *prompt)
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382 {
05383 static char password[32];
05384
05385 printf(prompt);
05386 memset(password, 0, sizeof(password));
05387
05388 #ifdef OS_UNIX
05389 return (char *) getpass("");
05390 #elif defined(OS_WINNT)
05391 {
05392 HANDLE hConsole;
05393 DWORD nCharsRead;
05394
05395 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05396 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05397 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05398 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05399 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05400 printf("\n");
05401
05402 if (password[strlen(password) - 1] == '\r')
05403 password[strlen(password) - 1] = 0;
05404
05405 return password;
05406 }
05407 #elif defined(OS_MSDOS)
05408 {
05409 char c, *ptr;
05410
05411 ptr = password;
05412 while ((c = getchar()) != EOF && c != '\n')
05413 *ptr++ = c;
05414 *ptr = 0;
05415
05416 printf("\n");
05417 return password;
05418 }
05419 #else
05420 {
05421 ss_gets(password, 32);
05422 return password;
05423 }
05424 #endif
05425 }
05426
05427
05428 INT ss_getchar(BOOL reset)
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448 {
05449 #ifdef OS_UNIX
05450
05451 static BOOL init = FALSE;
05452 static struct termios save_termios;
05453 struct termios buf;
05454 int i, fd;
05455 char c[3];
05456
05457 if (_daemon_flag)
05458 return 0;
05459
05460 fd = fileno(stdin);
05461
05462 if (reset) {
05463 if (init)
05464 tcsetattr(fd, TCSAFLUSH, &save_termios);
05465 init = FALSE;
05466 return 0;
05467 }
05468
05469 if (!init) {
05470 tcgetattr(fd, &save_termios);
05471 memcpy(&buf, &save_termios, sizeof(buf));
05472
05473 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05474
05475 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05476
05477 buf.c_cflag &= ~(CSIZE | PARENB);
05478 buf.c_cflag |= CS8;
05479
05480 buf.c_cc[VMIN] = 0;
05481 buf.c_cc[VTIME] = 0;
05482
05483 tcsetattr(fd, TCSAFLUSH, &buf);
05484 init = TRUE;
05485 }
05486
05487 memset(c, 0, 3);
05488 i = read(fd, c, 1);
05489
05490 if (i == 0)
05491 return 0;
05492
05493
05494 if (c[0] == 27) {
05495 i = read(fd, c, 2);
05496 if (i == 0)
05497 return 27;
05498
05499
05500 if (c[1] < 65)
05501 read(fd, c, 1);
05502
05503
05504 switch (c[1]) {
05505 case 49:
05506 return CH_HOME;
05507 case 50:
05508 return CH_INSERT;
05509 case 51:
05510 return CH_DELETE;
05511 case 52:
05512 return CH_END;
05513 case 53:
05514 return CH_PUP;
05515 case 54:
05516 return CH_PDOWN;
05517 case 65:
05518 return CH_UP;
05519 case 66:
05520 return CH_DOWN;
05521 case 67:
05522 return CH_RIGHT;
05523 case 68:
05524 return CH_LEFT;
05525 }
05526 }
05527
05528
05529 if (c[0] == 127)
05530 return CH_BS;
05531
05532 return c[0];
05533
05534 #elif defined(OS_WINNT)
05535
05536 static BOOL init = FALSE;
05537 static INT repeat_count = 0;
05538 static INT repeat_char;
05539 HANDLE hConsole;
05540 DWORD nCharsRead;
05541 INPUT_RECORD ir;
05542 OSVERSIONINFO vi;
05543
05544
05545 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05546 GetVersionEx(&vi);
05547
05548 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05549
05550 int c;
05551
05552 if (!kbhit())
05553 return 0;
05554
05555 c = getch();
05556 if (c == 224) {
05557 c = getch();
05558 switch (c) {
05559 case 71:
05560 return CH_HOME;
05561 case 72:
05562 return CH_UP;
05563 case 73:
05564 return CH_PUP;
05565 case 75:
05566 return CH_LEFT;
05567 case 77:
05568 return CH_RIGHT;
05569 case 79:
05570 return CH_END;
05571 case 80:
05572 return CH_DOWN;
05573 case 81:
05574 return CH_PDOWN;
05575 case 82:
05576 return CH_INSERT;
05577 case 83:
05578 return CH_DELETE;
05579 }
05580 }
05581 return c;
05582 }
05583
05584 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05585
05586 if (reset) {
05587 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05588 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05589 init = FALSE;
05590 return 0;
05591 }
05592
05593 if (!init) {
05594 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05595 init = TRUE;
05596 }
05597
05598 if (repeat_count) {
05599 repeat_count--;
05600 return repeat_char;
05601 }
05602
05603 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05604
05605 if (nCharsRead == 0)
05606 return 0;
05607
05608 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05609
05610 if (ir.EventType != KEY_EVENT)
05611 return ss_getchar(0);
05612
05613 if (!ir.Event.KeyEvent.bKeyDown)
05614 return ss_getchar(0);
05615
05616 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05617 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05618 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05619 return repeat_char;
05620 }
05621
05622 if (ir.Event.KeyEvent.uChar.AsciiChar)
05623 return ir.Event.KeyEvent.uChar.AsciiChar;
05624
05625 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05626 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05627 case 33:
05628 return CH_PUP;
05629 case 34:
05630 return CH_PDOWN;
05631 case 35:
05632 return CH_END;
05633 case 36:
05634 return CH_HOME;
05635 case 37:
05636 return CH_LEFT;
05637 case 38:
05638 return CH_UP;
05639 case 39:
05640 return CH_RIGHT;
05641 case 40:
05642 return CH_DOWN;
05643 case 45:
05644 return CH_INSERT;
05645 case 46:
05646 return CH_DELETE;
05647 }
05648
05649 return ir.Event.KeyEvent.wVirtualKeyCode;
05650 }
05651
05652 return ss_getchar(0);
05653
05654 #elif defined(OS_MSDOS)
05655
05656 int c;
05657
05658 if (!kbhit())
05659 return 0;
05660
05661 c = getch();
05662 if (!c) {
05663 c = getch();
05664 switch (c) {
05665 case 71:
05666 return CH_HOME;
05667 case 72:
05668 return CH_UP;
05669 case 73:
05670 return CH_PUP;
05671 case 75:
05672 return CH_LEFT;
05673 case 77:
05674 return CH_RIGHT;
05675 case 79:
05676 return CH_END;
05677 case 80:
05678 return CH_DOWN;
05679 case 81:
05680 return CH_PDOWN;
05681 case 82:
05682 return CH_INSERT;
05683 case 83:
05684 return CH_DELETE;
05685 }
05686 }
05687 return c;
05688
05689 #else
05690 return -1;
05691 #endif
05692 }
05693
05694
05695 char *ss_gets(char *string, int size)
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714 {
05715 char *p;
05716
05717 do {
05718 p = fgets(string, size, stdin);
05719 } while (p == NULL);
05720
05721
05722 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05723 p[strlen(p) - 1] = 0;
05724
05725 return p;
05726 }
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736 INT ss_directio_give_port(INT start, INT end)
05737 {
05738 #ifdef OS_WINNT
05739
05740
05741
05742 OSVERSIONINFO vi;
05743 HANDLE hdio = 0;
05744 DWORD buffer[] = { 6, 0, 0, 0 };
05745 DWORD size;
05746
05747 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05748 GetVersionEx(&vi);
05749
05750
05751 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05752 hdio =
05753 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05754 NULL, OPEN_EXISTING, 0, NULL);
05755 if (hdio == INVALID_HANDLE_VALUE) {
05756 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05757 return -1;
05758 }
05759
05760
05761 buffer[1] = start;
05762 buffer[2] = end;
05763 if (!DeviceIoControl
05764 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05765 return -1;
05766 }
05767
05768 return SS_SUCCESS;
05769 #else
05770 return SS_SUCCESS;
05771 #endif
05772 }
05773
05774
05775 INT ss_directio_lock_port(INT start, INT end)
05776 {
05777 #ifdef OS_WINNT
05778
05779
05780
05781 OSVERSIONINFO vi;
05782 HANDLE hdio;
05783 DWORD buffer[] = { 7, 0, 0, 0 };
05784 DWORD size;
05785
05786 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05787 GetVersionEx(&vi);
05788
05789
05790 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05791 hdio =
05792 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05793 NULL, OPEN_EXISTING, 0, NULL);
05794 if (hdio == INVALID_HANDLE_VALUE) {
05795 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05796 return -1;
05797 }
05798
05799
05800 buffer[1] = start;
05801 buffer[2] = end;
05802 if (!DeviceIoControl
05803 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05804 return -1;
05805 }
05806
05807 return SS_SUCCESS;
05808 #else
05809 return SS_SUCCESS;
05810 #endif
05811 }
05812
05813
05814
05815
05816
05817
05818
05819
05820
05821 INT ss_syslog(const char *message)
05822
05823
05824
05825
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838 {
05839 #ifdef OS_UNIX
05840 static BOOL init = FALSE;
05841
05842 if (!init) {
05843 #ifdef OS_ULTRIX
05844 openlog("MIDAS", LOG_PID);
05845 #else
05846 openlog("MIDAS", LOG_PID, LOG_USER);
05847 #endif
05848 init = TRUE;
05849 }
05850
05851 syslog(LOG_DEBUG, message);
05852 return SS_SUCCESS;
05853 #elif defined(OS_WINNT)
05854
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884 return SS_SUCCESS;
05885
05886 #else
05887
05888 return SS_SUCCESS;
05889
05890 #endif
05891 }
05892
05893
05894
05895
05896
05897
05898
05899
05900 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05901
05902 char *ss_crypt(char *buf, char *salt)
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922 {
05923 int i, seed;
05924 static char enc_pw[13];
05925
05926 memset(enc_pw, 0, sizeof(enc_pw));
05927 enc_pw[0] = salt[0];
05928 enc_pw[1] = salt[1];
05929
05930 for (i = 0; i < 8 && buf[i]; i++)
05931 enc_pw[i + 2] = buf[i];
05932 for (; i < 8; i++)
05933 enc_pw[i + 2] = 0;
05934
05935 seed = 123;
05936 for (i = 2; i < 13; i++) {
05937 seed = 5 * seed + 27 + enc_pw[i];
05938 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05939 }
05940
05941 return enc_pw;
05942 }
05943
05944
05945 #endif
05946
05947
05948
05949